【问题标题】:Program was killed after function returning函数返回后程序被杀死
【发布时间】:2017-08-05 21:18:18
【问题描述】:

当函数“dbmSetIndex”返回时,我的程序被杀死了。 您可以在下面看到被杀死的位置。 (=> 部分) 你能解释一下发生了什么吗? (x86 英特尔)

   0x0000000000420723 <+83>:    mov    rdi,r14
   0x0000000000420726 <+86>:    call   0x405260 <dbmSetIndex@plt>
   0x000000000042072b <+91>:    test   eax,eax
   0x000000000042072d <+93>:    mov    ebp,eax
=> 0x000000000042072f <+95>:    mov    DWORD PTR [r12],eax
   0x0000000000420733 <+99>:    jne    0x4207d0 <FnDBBase::SelectSecurity(s_oms_security*, char*)+256>
   0x0000000000420739 <+105>:   lea    rsi,[rip+0x4197d]        # 0x4620bd

这是 dbmSetIndex 代码。 我找不到这段代码的哪一部分导致了这个问题。

int dbmSetIndex ( dbmHandle* aHandle, const char* aTable, const char* aIndexName )
{
    dbmInternalHandle* pHandle = NULL;

    _TRY
    {   
        pHandle = (dbmInternalHandle*)aHandle->mHandle;

        // Water Mark가 다르면 걍 리턴해라.
        if ( unlikely ( aHandle->mMark != DBM_HANDLE_MARK ) ) 
        {   
            DBM_ERR ( "invalide magic number (%ld)", aHandle->mMark );
            _THROW( ERR_DBM_INVALID_HANDLE );
        }   

        if( pHandle->mRemote != NULL )
        {   
            if( pHandle->mRemote->mSockFd > 0 ) 
            {
                _CALL( dbmRemoteSetIndex( aHandle, aTable, aIndexName ) );
                _RETURN;
            }
        }   

        /****************************************
         * DataObject 맵핑.
        ****************************************/
        memset_s( &pHandle->mData, 0x00, sizeof( pHandle->mData ) );
        memcpy_s ( pHandle->mData.mTableName, aTable, strlen_s ( aTable ) + 1 );
        pHandle->mData.mTransType = DBM_SET_INDEX;
        pHandle->mData.mUserData  = (char*)aIndexName;

        /****************************************
         * mAct 호출.
        ****************************************/
        _CALL( pHandle->mTrans->mAct ( pHandle ) );
    }   
    _CATCH
    {   
        _CATCH_ERR;
    }   
    _FINALLY
    _END
}

【问题讨论】:

  • 请用编程语言标记。

标签: c++ function assembly x86 stack


【解决方案1】:

您提供了一点反汇编,表明对您提供的函数的调用已经返回。崩溃并没有在函数内部发生,而是在之后发生:

调用你的函数:

0x0000000000420726 <+86>:    call   0x405260 <dbmSetIndex@plt>

你已经返回了:

0x000000000042072b <+91>:    test   eax,eax

关键行是对存储在寄存器 r12 中的地址的内存访问(写入):

0x000000000042072f <+95>:    mov    DWORD PTR [r12],eax

让您的调试器显示寄存器并查看 r12 的内容。它很可能是 0x0000000000000000 或一个小值,因此是空指针(或空引用),但它也可能包含无效地址(未初始化的指针!)。

不过,从您提供的信息中可以看出一点。您将不得不查看函数调用的代码位置——它必须在函数FnDBBase::SelectSecurity(s_oms_security*, char*) 内,因为您跳转(jne)到此函数内的偏移量([...] + 256) .应该有一个if 涉及(test + jne 指令),可能还有一些指针分配。可能是这样的:

SomeClass* s = [...];
s->someMember = dbmSetIndex([...]); // (*)
if(*s->someMember)

(*): 失败位置,赋值时发生错误之后函数已经完成。不要指望 100% 找到这样的赋值,它也可能是对内联 setter 函数的调用。

在这里我们也看到了为什么 r12 不一定是 0:它将包含 someMemberSomeClass 内的预先计算的偏移量,即。 e. &(s->someMember) 这很可能是,如果 s 是 0,例如。 G。 16, 28, ... 准确地说,那么包含的值等于offsetof(SomeClass, somemember)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    相关资源
    最近更新 更多