之前碰到论坛里有几个好友,说程序不时的崩溃,什么xxoo不能read的!
如果光要是这个内存地址,估计你会疯掉~~
所以分享一下基本的调试技巧,需要准备的工具有WinDbg + VC6.0,
下面是自己整理的一份自动生成DUMP文件的源代码,只需要添加到工程即可,源代码如下:
MiniDump.h
MiniDump.cpp
<具体请参考附件SRC中,太大就不贴了>
1、在CXXDlg::OnInitDialog()中添加这样一段:
- BOOL CTestDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
-
- // ......
- SetUnhandledExceptionFilter(CrashReportEx);
- HMODULE hKernel32;
- // Try to get MiniDumpWriteDump() address.
- hDbgHelp = LoadLibrary("DBGHELP.DLL");
- MiniDumpWriteDump_ = (MINIDUMP_WRITE_DUMP)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
- // d("hDbgHelp=%X, MiniDumpWriteDump_=%X", hDbgHelp, MiniDumpWriteDump_);
-
- // Try to get Tool Help library functions.
- hKernel32 = GetModuleHandle("KERNEL32");
- CreateToolhelp32Snapshot_ = (CREATE_TOOL_HELP32_SNAPSHOT)GetProcAddress(hKernel32, "CreateToolhelp32Snapshot");
- Module32First_ = (MODULE32_FIRST)GetProcAddress(hKernel32, "Module32First");
- Module32Next_ = (MODULE32_NEST)GetProcAddress(hKernel32, "Module32Next");
- }
复制代码
下面是工程中的测试代码:
- class CTestDlg : public CDialog
- {
- // Construction
- public:
- CTestDlg(CWnd* pParent = NULL); // standard constructor
- void Fun1(char *pszBuffer);
- void Fun2(char *pszBuffer);
- void Fun3(char *pszBuffer);
- };
复制代码
- void CTestDlg::Fun1(char *pszBuffer)
- {
- Fun2(pszBuffer);
- }
- void CTestDlg::Fun2(char *pszBuffer)
- {
- Fun3(pszBuffer);
- }
- void CTestDlg::Fun3(char *pszBuffer)
- {
- pszBuffer[1] = 0x00;
- }
复制代码
我们在双击确定按钮时的响应代码如下:
- void CTestDlg::OnOK()
- {
- // TODO: Add extra validation here
- Fun1(NULL);
- }
复制代码
2、设置VC编译选项,勾选生成MAP和Debug Info、Progma Datebase:
3、将编译生成的Release目录中的pdb、map文件保存起来,以后调试会用到:
4、运行程序,单击确定按钮出现异常后自动重启,并创建一个Log文件夹,里面生成dump文件:
5、我们打开WinDbg,设置一下相关路径
A、设置pdb路径(File \ Symbol File Path)
B、设置源代码路径( File \ Source File Path )
C、设置Exe路径( File \ Image File Path )
6、用WiinDbg打开dump文件(File \ Open Crash Dump)
7、输入命令!analyze -v,等待几秒后会打印出错误信息,函数调用栈如下图:
OK ,这样我们就能在发布版本的程序中,准确的定位到哪个函数出了问题,所以发布程序时,一定要记得生成pdb、map文件,不然客户运行出错的话,你不死也残!
测试工程下载地址: