请看示例(图1):
很明显,在代码行108行有一个对空指针p的赋值操作,在IDE环境下运行,结果如下(图2):
提示p是nullptr。一位曾经工作于中科院的学者告诉我,程序运行过程中出现错误提示,90%都是错误指针(空指针、野指针)引起的,鉴于多年工作经验的总结,对于这一点我深信无疑。IDE环境下运行,我们很容易发现和解决类似这种错误,但是如果我们脱离IDE运行,一般都会提示0xC0000005错误提示对话框,这个时候要解决这种问题就有些茫然了,手足无措,不知如何下手了。要解决类似这种问题,我们需要借助应用程序异常调试信息记录文件CrashDump文件,那么我们如何来生成这样的文件呢?请看修改后的代码:
void ExpTest5() { char *p = NULL; p[0] = 0; }
void ExpTest4() { ExpTest5(); }
void ExpTest3() { ExpTest4(); }
void ExpTest2() { ExpTest3(); }
void ExpTest1() { ExpTest2(); }
#include <dbgHelp.h>
#pragma comment(lib, "dbghelp.lib")
void WINAPI WriteCrashDumpFile(_EXCEPTION_POINTERS * pExInfo, _MINIDUMP_TYPE WriteFlag)
{
//analyze -v 自动分析
//.ecxr 转到源码
if (pExInfo == NULL)
RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
char lpszModuleFilePath[MAX_PATH];
GetModuleFileName(NULL, lpszModuleFilePath, MAX_PATH);
(_tcsrchr(lpszModuleFilePath, '.'))[0] = 0;
strcat_s(lpszModuleFilePath, ".dump");
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ThreadId = ::GetCurrentThreadId();
dumpInfo.ExceptionPointers = pExInfo;
dumpInfo.ClientPointers = TRUE;
HANDLE hCrashFile = ::CreateFile(lpszModuleFilePath, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hCrashFile != INVALID_HANDLE_VALUE)
{
BOOL bWrite = ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hCrashFile, WriteFlag, &dumpInfo, NULL, NULL);
if (bWrite)
::FlushFileBuffers(hCrashFile);
}
CloseHandle(hCrashFile);
hCrashFile = NULL;
}
LONG WINAPI HandledExpFilter(_EXCEPTION_POINTERS *lpExceptionInfo)
{
WriteCrashDumpFile(lpExceptionInfo, MiniDumpWithFullMemory);
return EXCEPTION_EXECUTE_HANDLER;
}
void TestExceptionWalking()
{
__try
{
ExpTest1();
}
__except (HandledExpFilter(GetExceptionInformation()))
{
}
}
int _tmain()
{
TestExceptionWalking();
system("pause");
return 0;
}
这样在我们的exe相同工作目录下就会生成一个后缀名为dump的文件,我们用IDE打开这个dump文件(图3):
选择“使用 仅限本机 进行调试”,这个时候会跳转到错误代码行位置(图4):
图4显示的错误描述和图2显示的错误描述一致,这样我们就可以通过dump文件很方便解决这种类似错误问题。
注意:要实现在IDE定位到错误代码位置,除了要借助这个dump问题,其中还有一个很重要的文件pdb文件(程序数据库文件)。Debug环境下,编译会自动产生pdb文件,但是Release模式下,就需要我们手动来打开这个选项了,如图5:
这样一个通过IDE环境下应用程序异常处理方案就介绍完了。说到异常处理机制,肯定要讲解下轻量级调试软件WinDbg,下一遍将简单介绍WinDbg如何来处理类似问题。
来源:CSDN
作者:老狼主
链接:https://blog.csdn.net/u012156872/article/details/103679744