Trace CallStack when App Crashes (程序崩溃时导出调用栈) ---- BugSlayerUtil.dll 的使用

以前写的一个例子, 现在才放上来..

 

程序出错时, 调用BugSlayerUtil.dll 中的函数将调用栈(callstack) 写入文件. 用来调试程序, 事半功倍.

 

首先要做的是让程序带有调试信息. vc6 IDE 为例. 打开项目属性, 切换到所有配置(All Configurations), 然后C/C++属性页下的 General , Debug info 改成 Program Database.


然后切换到 Link , 选择 Debug ,选中 Debug Info, 并选中 Microsoft format.

 

将附带的 include 目录复制到你的硬盘中, 比如d:/include, 在如图的 Directories 中指定这个目录.


 

最简单的做法就是包含UnhandledExceptionFilter.h, 然后把其中的CUnhandledExceptionFilter 类作为 app 类的父类. 就像附带的 TestBugslayer 项目一样. CUnhandledExceptionFilter 会在构造的时候调用SetUnhandledExceptionFilter(). 如果你有自己的 UnhandledExceptionFilter 函数, 则不要从CUnhandledExceptionFilter 派生. 可以在自己的UnhandledExceptionFilter 函数中调用CUnhandledExceptionFilter::GetCrashInfoString() 静态函数, 该函数将返回包括调用栈在内的丰富调试信息的一个字符串. 你需要做的只是把这个字符串写入文件即可.

当然, 你的程序能通过编译连接还需要BugslayerUtil.lib 文件. 你可以简单的将这个文件复制到你的源文件目录中. 另外, 要运行你的程序需要BugslayerUtil.dll 文件. 确保它在你的项目生成 exe 的目录中.

 

注意: 由于 release 版本中用到的系统 dll 不带调试信息, release 版本的程序导出的调用栈信息会较 debug 版程序少一些. 但关键的出错行还是会有的. 另外, 发布程序时需要带上编译时生成 pdb 文件

 

附录:

Appendix:

 

Where does BugslayerUtil.dll come from?

BugslayerUtil.dll 来自 John Robbins Bugslayer专栏. John 将每次专栏中写的工具都放到了BugslayerUtil.dll.

http://www.microsoft.com/msj/0898/bugslayer0898.aspx

 

调用栈的信息如下形式:

 

DEBUG 版程序:

 

RnmsAdaptorD.exe caused a EXCEPTION_ACCESS_VIOLATION in module MSVCRTD.dll at 001B:10218207, memset()+71 byte(s), intel/memset.asm, line 115

EAX=00000000  EBX=000504E2  ECX=00000000  EDX=00000001  ESI=5F4335C0

EDI=00000000  EBP=0013EF04  ESP=0013EEC4  EIP=10218207  FLG=00010293

CS=001B   DS=0023  SS=0023  ES=0023   FS=003B  GS=0000

001B:10218207 (0x00000000 0x00000000 0x00000001 0x5F4335C0) MSVCRTD.dll, memset()+71 byte(s), intel/memset.asm, line 115

001B:00410383 (0x0013F624 0x0013EF3C 0x77D48734 0x00060434) RnmsAdaptorD.exe, CAboutDlg::OnInitDialog()+76 byte(s), D:/mss3000/v220/RnmsAdaptor/RnmsAdaptorDlg.cpp, line 546+11 byte(s)

001B:5F4335FB (0x00060434 0x00000110 0x000504E2 0x00000000) MFC42D.DLL, AfxDlgProc()+59 byte(s), dlgcore.cpp, line 35+14 byte(s)

001B:77D48734 (0x5F4335C0 0x00060434 0x00000110 0x000504E2) USER32.dll, GetDC()+109 byte(s)

001B:77D545E4 (0x00000000 0x5F4335C0 0x00060434 0x00000110) USER32.dll, DefDlgProcW()+1026 byte(s)

001B:77D53FD9 (0x00000000 0x00000110 0x000504E2 0x00000000) USER32.dll, PrivateExtractIconExW()+254 byte(s)

001B:77D6E571 (0x00060434 0x00000110 0x000504E2 0x00000000) USER32.dll, DefDlgProcA()+34 byte(s)

001B:77D48734 (0x77D6E54F 0x00060434 0x00000110 0x000504E2) USER32.dll, GetDC()+109 byte(s)

001B:77D48816 (0x00000000 0x77D6E54F 0x00060434 0x00000110) USER32.dll, GetDC()+335 byte(s)

001B:77D4C63F (0x77D6E54F 0x00060434 0x00000110 0x000504E2) USER32.dll, IsWindowUnicode()+161 byte(s)

001B:77D4E905 (0x77D6E54F 0x00060434 0x00000110 0x000504E2) USER32.dll, CallWindowProcA()+27 byte(s)

001B:5F42DF36 (0x00000110 0x000504E2 0x00000000 0x0013F624) MFC42D.DLL, CWnd::DefWindowProcA()+50 byte(s), wincore.cpp, line 1000+32 byte(s)

001B:5F42C8CB (0x0013F624 0x5F495541 0x5F4CFE48 0x00000000) MFC42D.DLL, CWnd::Default()+57 byte(s), wincore.cpp, line 249

001B:5F434816 (0x000504E2 0x00000000 0x0013F2CC 0x00155060) MFC42D.DLL, CDialog::HandleInitDialog()+173 byte(s), dlgcore.cpp, line 621+8 byte(s)

001B:5F42F2AC (0x00000110 0x000504E2 0x00000000 0x0013F268) MFC42D.DLL, CWnd::OnWndMsg()+1690 byte(s), wincore.cpp, line 1815+17 byte(s)

001B:5F42EBE8 (0x00000110 0x000504E2 0x00000000 0x0013F3A4) MFC42D.DLL, CWnd::WindowProc()+46 byte(s), wincore.cpp, line 1585+30 byte(s)

001B:5F42C789 (0x0013F624 0x00060434 0x00000110 0x000504E2) MFC42D.DLL, AfxCallWndProc()+237 byte(s), wincore.cpp, line 215+26 byte(s)

001B:5F42CC25 (0x00060434 0x00000110 0x000504E2 0x00000000) MFC42D.DLL, AfxWndProc()+129 byte(s), wincore.cpp, line 368

001B:5F49049D (0x00060434 0x00000110 0x000504E2 0x00000000) MFC42D.DLL, AfxWndProcBase()+74 byte(s), afxstate.cpp, line 220+21 byte(s)

001B:77D48734 (0x5F490453 0x00060434 0x00000110 0x000504E2) USER32.dll, GetDC()+109 byte(s)

001B:77D48816 (0x00000000 0x5F490453 0x00060434 0x00000110) USER32.dll, GetDC()+335 byte(s)

001B:77D4B89B (0x00691700 0x0068B778 0x000504E2 0x00000000) USER32.dll, GetParent()+364 byte(s)

001B:77D54E28 (0x00000000 0x00691700 0x00000194 0x00060434) USER32.dll, GetWindowTextLengthW()+1351 byte(s)

001B:77D5514C (0x00400000 0x00428278 0x000A0422 0x5F4335C0) USER32.dll, CreateDialogIndirectParamAorW()+51 byte(s)

001B:77D69B1B (0x00400000 0x00428278 0x000A0422 0x5F4335C0) USER32.dll, CreateDialogIndirectParamA()+27 byte(s)

001B:5F433F17 (0x00428278 0x0013FBA4 0x00400000 0x0013F684) MFC42D.DLL, CWnd::CreateDlgIndirect()+662 byte(s), dlgcore.cpp, line 327+36 byte(s)

001B:5F434552 (0x0013F930 0x0013FBA4 0x0041D684 0x00000001) MFC42D.DLL, CDialog::DoModal()+324 byte(s), dlgcore.cpp, line 528+32 byte(s)

001B:0040FF5A (0x0013F930 0x00155060 0x00000000 0x0000000A) RnmsAdaptorD.exe, CRnmsAdaptorDlg::OnHelpAbout()+71 byte(s), D:/mss3000/v220/RnmsAdaptor/RnmsAdaptorDlg.cpp, line 428

001B:5F4373FC (0x0013FBA4 0x00008004 0x00000000 0x00401311) MFC42D.DLL, _AfxDispatchCmdMsg()+162 byte(s), cmdtarg.cpp, line 88

001B:5F437B2B (0x00008004 0x00000000 0x00000000 0x00000000) MFC42D.DLL, CCmdTarget::OnCmdMsg()+628 byte(s), cmdtarg.cpp, line 302+39 byte(s)

001B:5F43374B (0x00008004 0x00000000 0x00000000 0x00000000) MFC42D.DLL, CDialog::OnCmdMsg()+36 byte(s), dlgcore.cpp, line 97+24 byte(s)

001B:5F42FA63 (0x00008004 0x00000000 0x0013F930 0x00155060) MFC42D.DLL, CWnd::OnCommand()+312 byte(s), wincore.cpp, line 2088

001B:5F42EC65 (0x00000111 0x00008004 0x00000000 0x0013F8CC) MFC42D.DLL, CWnd::OnWndMsg()+83 byte(s), wincore.cpp, line 1597+28 byte(s)

001B:5F42EBE8 (0x00000111 0x00008004 0x00000000 0x0013FA08) MFC42D.DLL, CWnd::WindowProc()+46 byte(s), wincore.cpp, line 1585+30 byte(s)

001B:5F42C789 (0x0013FBA4 0x000A0422 0x00000111 0x00008004) MFC42D.DLL, AfxCallWndProc()+237 byte(s), wincore.cpp, line 215+26 byte(s)

001B:5F42CC25 (0x000A0422 0x00000111 0x00008004 0x00000000) MFC42D.DLL, AfxWndProc()+129 byte(s), wincore.cpp, line 368

001B:5F49049D (0x000A0422 0x00000111 0x00008004 0x00000000) MFC42D.DLL, AfxWndProcBase()+74 byte(s), afxstate.cpp, line 220+21 byte(s)

001B:77D48734 (0x5F490453 0x000A0422 0x00000111 0x00008004) USER32.dll, GetDC()+109 byte(s)

001B:77D48816 (0x00000000 0x5F490453 0x000A0422 0x00000111) USER32.dll, GetDC()+335 byte(s)

001B:77D489CD (0x00424A68 0x00000001 0x0013FAC0 0x5F4396C8) USER32.dll, GetWindowLongW()+295 byte(s)

001B:77D496C7 (0x00424A68 0x0013FEDC 0x0013FB64 0x7FFDE000) USER32.dll, DispatchMessageA()+15 byte(s)

001B:5F4396C8 (0x0013FEDC 0x0013FB64 0x7FFDE000 0x00424A30) MFC42D.DLL, CWinThread::PumpMessage()+256 byte(s), thrdcore.cpp, line 846

001B:5F43219F (0x00000004 0x0013FEDC 0x0013FB64 0x7FFDE000) MFC42D.DLL, CWnd::RunModalLoop()+514 byte(s), wincore.cpp, line 3478+19 byte(s)

001B:5F43459F (0x7C903804 0x0013E3EC 0x0013FB90 0x0013FB90) MFC42D.DLL, CDialog::DoModal()+401 byte(s), dlgcore.cpp, line 536+12 byte(s)

001B:00403FC4 (0x7C903804 0x0013E3EC 0x7FFDE000 0x00424A30) RnmsAdaptorD.exe, CRnmsAdaptorApp::InitInstance()+1038 byte(s), D:/mss3000/v220/RnmsAdaptor/RnmsAdaptor.cpp, line 205+11 byte(s)

001B:5F433523 (0x00400000 0x00000000 0x001523A1 0x00000001) MFC42D.DLL, AfxWinMain()+131 byte(s), winmain.cpp, line 39+11 byte(s)

001B:00418AF8 (0x00400000 0x00000000 0x001523A1 0x00000001) RnmsAdaptorD.exe, WinMain()+24 byte(s), appmodul.cpp, line 30

001B:00418513 (0x7C903804 0x0013E3EC 0x7FFDE000 0x8054A6ED) RnmsAdaptorD.exe, WinMainCRTStartup()+435 byte(s), crtexe.c, line 330+54 byte(s)

001B:7C816FD7 (0x00418360 0x00000000 0x78746341 0x00000020) kernel32.dll, RegisterWaitForInputIdle()+73 byte(s)

RELEASE 版程序:

 

RnmsAdaptor.exe caused a EXCEPTION_ACCESS_VIOLATION in module RnmsAdaptor.exe at 001B:00407C74, CAboutDlg::OnInitDialog()+36 byte(s), D:/mss3000/v220/RnmsAdaptor/RnmsAdaptorDlg.cpp, line 546+2 byte(s)

EAX=00000000  EBX=0013F7CC  ECX=00000000  EDX=7FFEFFFF  ESI=73DD6745

EDI=00000000  EBP=0013F20C  ESP=0013F1BC  EIP=00407C74  FLG=00010246

CS=001B   DS=0023  SS=0023  ES=0023   FS=003B  GS=0000

001B:00407C74 (0x77D48734 0x0011045C 0x00000110 0x002E04FC) RnmsAdaptor.exe, CAboutDlg::OnInitDialog()+36 byte(s), D:/mss3000/v220/RnmsAdaptor/RnmsAdaptorDlg.cpp, line 546+2 byte(s)

001B:73DD6773 (0x73DD6745 0x0011045C 0x00000110 0x002E04FC) MFC42.DLL, Ordinal1130()+46 byte(s)

001B:77D545E4 (0x00000000 0x73DD6745 0x0011045C 0x00000110) USER32.dll, DefDlgProcW()+1026 byte(s)

001B:77D53FD9 (0x00000000 0x00000110 0x002E04FC 0x00000000) USER32.dll, PrivateExtractIconExW()+254 byte(s)

001B:77D6E571 (0x0011045C 0x00000110 0x002E04FC 0x00000000) USER32.dll, DefDlgProcA()+34 byte(s)

001B:77D48734 (0x77D6E54F 0x0011045C 0x00000110 0x002E04FC) USER32.dll, GetDC()+109 byte(s)

001B:77D48816 (0x00000000 0x77D6E54F 0x0011045C 0x00000110) USER32.dll, GetDC()+335 byte(s)

001B:77D4C63F (0x77D6E54F 0x0011045C 0x00000110 0x002E04FC) USER32.dll, IsWindowUnicode()+161 byte(s)

001B:77D4E905 (0x77D6E54F 0x0011045C 0x00000110 0x002E04FC) USER32.dll, CallWindowProcA()+27 byte(s)

001B:73DD216B (0x00000110 0x002E04FC 0x00000000 0x0013F7CC) MFC42.DLL, Ordinal2385()+68 byte(s)

001B:73DD21EC (0x00000110 0x002E04FC 0x73E7B0E8 0x0013F49C) MFC42.DLL, Ordinal2379()+39 byte(s)

001B:73DD1B9B (0x00000110 0x002E04FC 0x00000000 0x0013F5B4) MFC42.DLL, Ordinal6374()+36 byte(s)

001B:73DD1B05 (0x0013F7CC 0x84C800C4 0x00000110 0x002E04FC) MFC42.DLL, Ordinal1109()+145 byte(s)

001B:73DD1A58 (0x0011045C 0x00000110 0x002E04FC 0x00000000) MFC42.DLL, Ordinal1578()+54 byte(s)

001B:73E6847D (0x0011045C 0x00000110 0x002E04FC 0x00000000) MFC42.DLL, Ordinal1579()+57 byte(s)

001B:77D48734 (0x73E68444 0x0011045C 0x00000110 0x002E04FC) USER32.dll, GetDC()+109 byte(s)

001B:77D48816 (0x00000000 0x73E68444 0x0011045C 0x00000110) USER32.dll, GetDC()+335 byte(s)

001B:77D4B89B (0x0062CC10 0x00629BF0 0x002E04FC 0x00000000) USER32.dll, GetParent()+364 byte(s)

001B:77D54E28 (0x00000000 0x0062CC10 0x00000194 0x0011045C) USER32.dll, GetWindowTextLengthW()+1351 byte(s)

001B:77D5514C (0x00400000 0x004140E8 0x0029054A 0x73DD6745) USER32.dll, CreateDialogIndirectParamAorW()+51 byte(s)

001B:77D69B1B (0x00400000 0x004140E8 0x0029054A 0x73DD6745) USER32.dll, CreateDialogIndirectParamA()+27 byte(s)

001B:73DDF11E (0x004140E8 0x0013FBDC 0x00400000 0x0013FBDC) MFC42.DLL, Ordinal2147()+373 byte(s)

001B:73DE6A08 (0x0040D9C0 0x00000001 0x00000000 0x00000000) MFC42.DLL, Ordinal2514()+194 byte(s)

001B:004078B2 (0x0040D7C0 0x00000111 0x0013F874 0x73DD23BF) RnmsAdaptor.exe, CRnmsAdaptorDlg::OnHelpAbout()+50 byte(s), D:/mss3000/v220/RnmsAdaptor/RnmsAdaptorDlg.cpp, line 428

001B:73DD24C0 (0x0013FBDC 0x00008004 0x00000000 0x00407880) MFC42.DLL, Ordinal567()+171 byte(s)

001B:73DD23BF (0x00008004 0x00000000 0x00000000 0x00000000) MFC42.DLL, Ordinal4424()+266 byte(s)

001B:73E3DEAD (0x00008004 0x00000000 0x00000000 0x00000000) MFC42.DLL, Ordinal4431()+29 byte(s)

001B:73DD3244 (0x00000000 0x00000000 0x0013FBDC 0x0013FBDC) MFC42.DLL, Ordinal4441()+83 byte(s)

001B:73DD1BF1 (0x00000111 0x00008004 0x00000000 0x0013F984) MFC42.DLL, Ordinal5163()+47 byte(s)

001B:73DD1B9B (0x00000111 0x00008004 0x00000000 0x0013FA9C) MFC42.DLL, Ordinal6374()+36 byte(s)

001B:73DD1B05 (0x0013FBDC 0x00000000 0x00000111 0x00008004) MFC42.DLL, Ordinal1109()+145 byte(s)

001B:73DD1A58 (0x0029054A 0x00000111 0x00008004 0x00000000) MFC42.DLL, Ordinal1578()+54 byte(s)

001B:73E6847D (0x0029054A 0x00000111 0x00008004 0x00000000) MFC42.DLL, Ordinal1579()+57 byte(s)

001B:77D48734 (0x73E68444 0x0029054A 0x00000111 0x00008004) USER32.dll, GetDC()+109 byte(s)

001B:77D48816 (0x00000000 0x73E68444 0x0029054A 0x00000111) USER32.dll, GetDC()+335 byte(s)

001B:77D489CD (0x00412844 0x00000001 0x00412844 0x73DD125A) USER32.dll, GetWindowLongW()+295 byte(s)

001B:77D496C7 (0x00412844 0x00000000 0x0013FBDC 0x73DE6B99) USER32.dll, DispatchMessageA()+15 byte(s)

001B:73DD125A (0x00008004 0x00000000 0x009068FE 0x0000014D) MFC42.DLL, Ordinal5307()+60 byte(s)

 

googlepages 最近不能用. 找个 ftp 先放上代码和带插图的 doc 版本

ftp://222.90.231.60/doc/unhandle.rar

你可能感兴趣的:(Trace CallStack when App Crashes (程序崩溃时导出调用栈) ---- BugSlayerUtil.dll 的使用)