> 热点 >

天天动态:重复delete 对象指针后的 异常调用栈怪异 解析

时间:2023-04-19 13:28:04       来源:博客园


【资料图】

Release版VC6 MFC程序 程序正常退出时得到一个如下异常调用栈:

0:000> kb # ChildEBP RetAddr      Args to Child              WARNING: Frame IP not in any known module. Following frames may be wrong.00 0019eb94 76124f2f     00c3afc8 0019ebdc 0019ebb8 0x8c73d0101 0019ebdc 0079451a     00c3afc8 73d82ec0 00000001 USER32!IsZoomed+0xaf02 0019ebe4 73d82ec0     00000001 73d35d1c 00c3afc8 JXC_MED!CMainFrame::`scalar deleting destructor"+0x803 0019ebec 73d35d1c     00c3afc8 00000000 73d35c0f MFC42!CControlFrameWnd::PostNcDestroy+0xb04 0019ec2c 73d31e1d     00c3afc8 00c3afc8 00cae670 MFC42!CWnd::OnNcDestroy+0x10d05 0019eca4 73d31b07     00000082 00000000 73dca448 MFC42!CWnd::OnWndMsg+0x2f406 0019ecc4 73d31a78     00000082 00000000 00000000 MFC42!CWnd::WindowProc+0x2207 0019ed24 73d319d0     00c3afc8 00000000 00000082 MFC42!AfxCallWndProc+0x9108 0019ed44 73dbe00c     00031002 00000082 00000000 MFC42!AfxWndProc+0x3409 0019ed70 76135cab     00031002 00000082 00000000 MFC42!AfxWndProcBase+0x390a 0019ed9c 761267bc     73dbdfd3 00031002 00000082 USER32!_InternalCallWinProc+0x2b0b 0019ee80 7612635a     73dbdfd3 00000000 00000082 USER32!UserCallWinProcCheckWow+0x3ac0c 0019eee4 76133f87     01225f90 00000000 00000082 USER32!DispatchClientMessage+0xea0d 0019ef28 77e62add     0019ef44 00000020 0019efac USER32!__fnNCDESTROY+0x370e 0019ef60 73d364c5     00031002 009a034c 009a1f14 ntdll!KiUserCallbackDispatcher+0x4d0f 0019ef74 00794760     009a8968 00000000 00c3afc8 MFC42!CWnd::DestroyWindow+0x3110 0019efb8 73d38fb4     00c3afc8 00c3afc8 00794965 JXC_MED!CMainFrame::DestroyWindow+0x13c [MainFrm.cpp @ 852] 11 0019efd0 02b056f3     00000000 00794a45 00c3afc8 MFC42!CFrameWnd::OnClose+0xf512 0019efec 007949a3     00000000 73dca64c 00000001 ToolLib!CTFrameWnd::OnClose+0x1313 0019f044 73d31e1d     00c3afc8 00c3afc8 00cae670 JXC_MED!CMainFrame::OnClose+0x3e [MainFrm.cpp @ 1133] 

顶层两个函数调用帧都是错的,地址怪异 ,没有函数名子通过反汇编校验,根据帧返回地址是 0079451a 判断出具体函数源码位置,不及格的程序员-八神

JXC_MED!CMainFrame::`scalar deleting destructor":00794512 56             push    esi00794513 8bf1           mov     esi, this (ecx)00794515 e814000000     call    JXC_MED!CMainFrame::~CMainFrame (79452e) //顶层栈实际上是在调用此析构函数中的代码0079451a f644240801     test    byte ptr [esp+8], 10079451f 7407           je      JXC_MED!CMainFrame::`scalar deleting destructor"+0x16 (794528)00794521 56             push    esi00794522 e8338c0000     call    JXC_MED!operator delete (79d15a)00794527 59             pop     this (ecx)00794528 8bc6           mov     eax, esi0079452a 5e             pop     esi0079452b c20400         ret     4JXC_MED!CMainFrame::~CMainFrame:0079452e b806828200     mov     eax, 828206h00794533 e8489b0000     call    JXC_MED!__EH_prolog (79e080)00794538 51             push    this (ecx)00794539 51             push    this (ecx)0079453a 56             push    esi0079453b 8bf1           mov     esi, this (ecx)0079453d 57             push    edi0079453e 8975f0         mov     dword ptr [ebp-10h], esi00794541 c70668a98800   mov     dword ptr [esi], 88A968h00794547 8b8e58040000   mov     this (ecx), dword ptr [esi+458h]0079454d c745fc06000000 mov     dword ptr [ebp-4], 600794554 85c9           test    this (ecx), this (ecx)00794556 7407           je      JXC_MED!CMainFrame::~CMainFrame+0x31 (79455f)00794558 8b01           mov     eax, dword ptr [this(??) (ecx)] //通过指令飞越技术查出是这里出错,代码对应 delete loadWareWork;0079455a 6a01           push    10079455c ff5004         call    dword ptr [eax+4]0079455f a150889a00     mov     eax, dword ptr ds:[009A8850h]00794564 83780400       cmp     dword ptr [eax+4], 000794568 741f           je      JXC_MED!CMainFrame::~CMainFrame+0x5b (794589)00794623 c3             ret 
CMainFrame::~CMainFrame(){    if(loadWareWork) delete loadWareWork; //这个被重复删了 导至出错    if (gpDb->IsOpen())    {        WriteOpLog(gpDb, gstrOprCode, GSP_OPLOG_MODULEID, "2", "退出系统");     }}

图1:指令飞越技术重现@eip内存地址 0x8c73d01

解决办法,将这段代码删掉,此处多余的代码,理由是此类型是CWnd子类。不及格的程序员-八神创建时使用WS_CHILD类型创建,它会随着父窗体自动DESTORY, 并且子类重载函数 PostNcDestroy 并 delete this了,不需要这里再次delete。

关键词: