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 0x8c73d01 01 0019ebdc 0079451a 00c3afc8 73d82ec0 00000001 USER32!IsZoomed+0xaf 02 0019ebe4 73d82ec0 00000001 73d35d1c 00c3afc8 JXC_MED!CMainFrame::`scalar deleting destructor'+0x8 03 0019ebec 73d35d1c 00c3afc8 00000000 73d35c0f MFC42!CControlFrameWnd::PostNcDestroy+0xb 04 0019ec2c 73d31e1d 00c3afc8 00c3afc8 00cae670 MFC42!CWnd::OnNcDestroy+0x10d 05 0019eca4 73d31b07 00000082 00000000 73dca448 MFC42!CWnd::OnWndMsg+0x2f4 06 0019ecc4 73d31a78 00000082 00000000 00000000 MFC42!CWnd::WindowProc+0x22 07 0019ed24 73d319d0 00c3afc8 00000000 00000082 MFC42!AfxCallWndProc+0x91 08 0019ed44 73dbe00c 00031002 00000082 00000000 MFC42!AfxWndProc+0x34 09 0019ed70 76135cab 00031002 00000082 00000000 MFC42!AfxWndProcBase+0x39 0a 0019ed9c 761267bc 73dbdfd3 00031002 00000082 USER32!_InternalCallWinProc+0x2b 0b 0019ee80 7612635a 73dbdfd3 00000000 00000082 USER32!UserCallWinProcCheckWow+0x3ac 0c 0019eee4 76133f87 01225f90 00000000 00000082 USER32!DispatchClientMessage+0xea 0d 0019ef28 77e62add 0019ef44 00000020 0019efac USER32!__fnNCDESTROY+0x37 0e 0019ef60 73d364c5 00031002 009a034c 009a1f14 ntdll!KiUserCallbackDispatcher+0x4d 0f 0019ef74 00794760 009a8968 00000000 00c3afc8 MFC42!CWnd::DestroyWindow+0x31 10 0019efb8 73d38fb4 00c3afc8 00c3afc8 00794965 JXC_MED!CMainFrame::DestroyWindow+0x13c [MainFrm.cpp @ 852] 11 0019efd0 02b056f3 00000000 00794a45 00c3afc8 MFC42!CFrameWnd::OnClose+0xf5 12 0019efec 007949a3 00000000 73dca64c 00000001 ToolLib!CTFrameWnd::OnClose+0x13 13 0019f044 73d31e1d 00c3afc8 00c3afc8 00cae670 JXC_MED!CMainFrame::OnClose+0x3e [MainFrm.cpp @ 1133]
頂層兩個函數呼叫幀都是錯的,地址怪異 ,沒有函數名子通過反組合校驗,根據幀返回地址是 0079451a 判斷出具體函數原始碼位置, 不及格的程式設計師-八神
JXC_MED!CMainFrame::`scalar deleting destructor': 00794512 56 push esi 00794513 8bf1 mov esi, this (ecx) 00794515 e814000000 call JXC_MED!CMainFrame::~CMainFrame (79452e) //頂層棧實際上是在呼叫此解構函式中的程式碼 0079451a f644240801 test byte ptr [esp+8], 1 0079451f 7407 je JXC_MED!CMainFrame::`scalar deleting destructor'+0x16 (794528) 00794521 56 push esi 00794522 e8338c0000 call JXC_MED!operator delete (79d15a) 00794527 59 pop this (ecx) 00794528 8bc6 mov eax, esi 0079452a 5e pop esi 0079452b c20400 ret 4 JXC_MED!CMainFrame::~CMainFrame: 0079452e b806828200 mov eax, 828206h 00794533 e8489b0000 call JXC_MED!__EH_prolog (79e080) 00794538 51 push this (ecx) 00794539 51 push this (ecx) 0079453a 56 push esi 0079453b 8bf1 mov esi, this (ecx) 0079453d 57 push edi 0079453e 8975f0 mov dword ptr [ebp-10h], esi 00794541 c70668a98800 mov dword ptr [esi], 88A968h 00794547 8b8e58040000 mov this (ecx), dword ptr [esi+458h] 0079454d c745fc06000000 mov dword ptr [ebp-4], 6 00794554 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 1 0079455c ff5004 call dword ptr [eax+4] 0079455f a150889a00 mov eax, dword ptr ds:[009A8850h] 00794564 83780400 cmp dword ptr [eax+4], 0 00794568 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。
======================個性簽名=====================
之前認為Apple 的iOS 設計的要比 Android 穩定,我錯了嗎?
下載的許多使用者端程式/遊戲程式,經常會Crash,是程式寫的不好(記憶體漏失?剛啟動也會嗎?)還是iOS本身的不穩定!!!
如果在Android手機中可以簡單聯接到ddms,就可以檢視系統log,很容易看到程式為什麼出錯,在iPhone中如何得知呢?試試Organizer吧,分析一下Device logs,也許有用.