异常时输出异常来源

来源:互联网 发布:网络老虎机骗局分析 编辑:程序博客网 时间:2024/05/23 14:25

条件:需要pdb调试符号文件

可以使用seh将程序入口包围起来,一旦出现异常,就在异常处理器中,查询其pdb符号文件

输出异常的代码行以及堆栈,这对日常调试跟踪问题,很有益处

int __cdecl PrintExceptionHandler(PEXCEPTION_POINTERS pExp, LPCSTR Message){memset(bufferIMAGEHLP_SYMBOL,0,10240);DWORD nameBytes = sizeof(bufferIMAGEHLP_SYMBOL) - sizeof(SYMBOL_INFO)+sizeof(TCHAR);PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(bufferIMAGEHLP_SYMBOL);symbol->SizeOfStruct = sizeof(SYMBOL_INFO);symbol->MaxNameLen   = nameBytes/(sizeof(TCHAR));//The length of the name, in characters,not bytesSTACKFRAME64 sratckFrame = {0};sratckFrame.AddrPC.Offset = pExp->ContextRecord->Eip;sratckFrame.AddrStack.Offset = pExp->ContextRecord->Esp;sratckFrame.AddrFrame.Offset = pExp->ContextRecord->Ebp;sratckFrame.AddrPC.Mode = AddrModeFlat;sratckFrame.AddrStack.Mode = AddrModeFlat;sratckFrame.AddrFrame.Mode = AddrModeFlat;DBGVIEW("%s Occurred a Exception:",Message);if(!::SymInitialize(::GetCurrentProcess(), NULL, TRUE)){DBGVIEW("CAN NOT FIND PDB FILE,CAN NOT OUTPUT CALLSTACK WITH LINE AND FUNC NAME");return FALSE;}int stackLevel = 0;BOOL bResult = FALSE;DWORD levelFound = 0;const char* levelstr = " LEVEL:";const char* linestr  = " LINE:";const char* filestr  = " FILE:";const char* funcstr  = " FUNC:";for(;;){bResult = ::StackWalk64(IMAGE_FILE_MACHINE_I386,::GetCurrentProcess(),::GetCurrentThread(),&sratckFrame,NULL, NULL,SymFunctionTableAccess64,SymGetModuleBase64,NULL);if(!bResult || sratckFrame.AddrFrame.Offset == 0) {break;}DWORD64 displacement;BOOL bResult2 = FALSE;memset(symbol->Name,0,nameBytes);//SymFromAddr can not reset NamebResult = ::SymFromAddr(GetCurrentProcess(), sratckFrame.AddrPC.Offset, &displacement, symbol);if(bResult) {DWORD displacement2 = 0;IMAGEHLP_LINE64* imageHelpLine = (IMAGEHLP_LINE64*)bufferIMAGE_LINE;memset(bufferIMAGE_LINE,0,sizeof(IMAGEHLP_LINE64)+MAX_PATH*2);imageHelpLine->SizeOfStruct = sizeof(IMAGEHLP_LINE64);imageHelpLine->FileName = (CHAR*)(imageHelpLine+1);bResult2 = ::SymGetLineFromAddr64(::GetCurrentProcess(),sratckFrame.AddrPC.Offset, &displacement2,imageHelpLine);if(bResult2){if(levelFound==0){DBGVIEW("       STACK:     LINE: FILE\\FUNCTION()");}DBGVIEW("          %02d:%05d    : %s\\%s()",stackLevel,imageHelpLine->LineNumber,imageHelpLine->FileName,symbol->Name);levelFound++;}}stackLevel++;}if(levelFound<=0){DBGVIEW("CAN NOT FIND PDB FILE,CAN NOT OUTPUT CALLSTACK WITH LINE AND FUNC NAME");}::SymCleanup(::GetCurrentProcess());return TRUE;}
还提供方便使用的宏

#define DBGTRY __try{#define DBGEXCEPT }__except(PrintExceptionHandler(GetExceptionInformation(),__FILE__)){\DBGVIEW("File:%s at Line:%s has a exception",__FILE__,__LINE__);}
只需要用DBGTRY和DBGEXCEPT将可能出错的代码包围起来,即可

注意,使用该宏的函数,不能有栈上的类的变量

0 0
原创粉丝点击