debug时候我们可以很快速、精确的定位问题所在。
但是对于release版本,我们往往无能为力。
尤其面对一群难缠的客户,情况就会更加糟糕。
而且对于release版本来说,crash的时候日志系统往往起不到任何作用。而且,我们也不可能捕获所有的异常,更何况,客户端崩溃的原因都是我们捕获不了的异常。
这就需要dump文件了。
dump文件是C++程序发生异常时,保存当时程序运行状态的文件,是调试异常程序重要的方法,所以程序崩溃时,除了日志文件,dump文件便成了我们查找错误的最后一根救命的稻草。
Not all bugs can be found prior to release, which means not all bugs that throw exceptions can be found before release. Fortunately, Microsoft has included in the Platform SDK a function to help developers collect information on exceptions that are discovered by users. The MiniDumpWriteDump function writes the necessary crash dump information to a file without saving the whole process space. This crash dump information file is called a minidump. This technical article provides info about how to write and use a minidump.
SetUnhandledExceptionFilter
调用SetUnhandledExceptionFilter注册一个自定义的异常处理回调函数,也就是在回调函数中进行写minidump文件。
MiniDumpWriteDump
这个函数就是用来写dump了:
<code class="hljs perl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">#include <dbghelp.h></span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">#include <shellapi.h></span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">#include <shlobj.h></span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> GenerateDump(EXCEPTION_POINTERS* pExceptionPointers) { BOOL bMiniDumpSuccessful; WCHAR szPath[MAX_PATH]; WCHAR szFileName[MAX_PATH]; WCHAR* szAppName = L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"AppName"</span>; WCHAR* szVersion = L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"v1.0"</span>; DWORD dwBufferSize = MAX_PATH; HANDLE hDumpFile; SYSTEMTIME stLocalTime; MINIDUMP_EXCEPTION_INFORMATION ExpParam; GetLocalTime( &stLocalTime ); GetTempPath( dwBufferSize, szPath ); StringCchPrintf( szFileName, MAX_PATH, L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%s</span><span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%s</span>"</span>, szPath, szAppName ); CreateDirectory( szFileName, NULL ); StringCchPrintf( szFileName, MAX_PATH, L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%s</span><span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%s</span>\\<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%s</span>-<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%04d</span><span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%02d</span><span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%02d</span>-<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%02d</span><span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%02d</span><span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%02d</span>-<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%ld</span>-<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">%ld</span>.dmp"</span>, szPath, szAppName, szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, GetCurrentProcessId(), GetCurrentThreadId()); hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, CREATE_ALWAYS, <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>); ExpParam.ThreadId = GetCurrentThreadId(); ExpParam.ExceptionPointers = pExceptionPointers; ExpParam.ClientPointers = TRUE; bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL); <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> EXCEPTION_EXECUTE_HANDLER; } void SomeFunction() { __try { <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">*pBadPtr</span> = NULL; <span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">*pBadPtr</span> = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; } __except(GenerateDump(GetExceptionInformation())) { } }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">23</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">24</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">25</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">26</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">27</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">28</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">29</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">30</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">31</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">32</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">33</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">34</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">35</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">36</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">37</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">38</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">39</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">40</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">41</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">42</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">43</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">44</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">45</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">46</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">47</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">48</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">49</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">50</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">51</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">52</li></ul>
最后,献上完整的代码:
新建一个nimidumo.h:
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#pragma once </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#include <windows.h> </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#include <DbgHelp.h> </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#include <stdlib.h> </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#pragma comment(lib, "dbghelp.lib") </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#ifndef _M_IX86 </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#error "The following code only works for x86!" </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#endif </span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">inline</span> <span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span> IsDataSectionNeeded(<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">const</span> WCHAR* pModuleName) { <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (pModuleName == <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) { <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">FALSE</span>; } WCHAR szFileName[_MAX_FNAME] = L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">""</span>; _wsplitpath(pModuleName, <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>, <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>, szFileName, <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>); <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (_wcsicmp(szFileName, L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"ntdll"</span>) == <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">TRUE</span>; <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">FALSE</span>; } <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">inline</span> <span class="hljs-built_in" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span> CALLBACK MiniDumpCallback(PVOID pParam, <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">const</span> PMINIDUMP_CALLBACK_INPUT pInput, PMINIDUMP_CALLBACK_OUTPUT pOutput) { <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (pInput == <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span> || pOutput == <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">FALSE</span>; <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">switch</span> (pInput->CallbackType) { <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">case</span> ModuleCallback: <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (pOutput->ModuleWriteFlags & ModuleWriteDataSeg) <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (!IsDataSectionNeeded(pInput->Module<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.FullPath</span>)) pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg); <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">case</span> IncludeModuleCallback: <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">case</span> IncludeThreadCallback: <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">case</span> ThreadCallback: <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">case</span> ThreadExCallback: <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">TRUE</span>; <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">default</span>:; } <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">FALSE</span>; } <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">inline</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName) { HANDLE hFile = CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>); <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ((hFile != <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>) && (hFile != INVALID_HANDLE_VALUE)) { MINIDUMP_EXCEPTION_INFORMATION mdei; mdei<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.ThreadId</span> = GetCurrentThreadId(); mdei<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.ExceptionPointers</span> = pep; mdei<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.ClientPointers</span> = <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>; MINIDUMP_CALLBACK_INFORMATION mci; mci<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.CallbackRoutine</span> = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback; mci<span class="hljs-variable" style="margin: 0px; padding: 0px; color: rgb(102, 0, 102); box-sizing: border-box;">.CallbackParam</span> = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal, (pep != <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) ? &mdei : <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>, &mci); CloseHandle(hFile); } } LONG __stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo) { CreateMiniDump(pExceptionInfo, L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"core.dmp"</span>); MessageBox(<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"Error"</span>, L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"error"</span>, MB_OK); <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">/*printf("Error address %x/n", pExceptionInfo->ExceptionRecord->ExceptionAddress); printf("CPU register:/n"); printf("eax %x ebx %x ecx %x edx %x/n", pExceptionInfo->ContextRecord->Eax, pExceptionInfo->ContextRecord->Ebx, pExceptionInfo->ContextRecord->Ecx, pExceptionInfo->ContextRecord->Edx);*/</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> EXCEPTION_EXECUTE_HANDLER; } <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">// 此函数一旦成功调用,之后对 SetUnhandledExceptionFilter 的调用将无效 </span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> DisableSetUnhandledExceptionFilter() { <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span>* addr = (<span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span>*)GetProcAddress(LoadLibrary(L<span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"kernel32.dll"</span>), <span class="hljs-string" style="margin: 0px; padding: 0px; color: rgb(0, 136, 0); box-sizing: border-box;">"SetUnhandledExceptionFilter"</span>); <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (addr) { <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">char</span> code[<span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">16</span>]; <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> size = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; code[size++] = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0x33</span>; code[size++] = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0xC0</span>; code[size++] = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0xC2</span>; code[size++] = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0x04</span>; code[size++] = <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0x00</span>; DWORD dwOldFlag, dwTempFlag; VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag); WriteProcessMemory(GetCurrentProcess(), addr, code, size, <span class="hljs-literal" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">NULL</span>); VirtualProtect(addr, size, dwOldFlag, &dwTempFlag); } } <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">void</span> InitMinDump() { <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">//注册异常处理函数 </span> SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">//使SetUnhandledExceptionFilter </span> DisableSetUnhandledExceptionFilter(); } <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#pragma once</span> </code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">9</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">10</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">11</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">12</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">13</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">14</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">15</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">16</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">17</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">18</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">19</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">20</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">21</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">22</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">23</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">24</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">25</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">26</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">27</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">28</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">29</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">30</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">31</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">32</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">33</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">34</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">35</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">36</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">37</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">38</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">39</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">40</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">41</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">42</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">43</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">44</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">45</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">46</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">47</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">48</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">49</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">50</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">51</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">52</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">53</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">54</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">55</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">56</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">57</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">58</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">59</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">60</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">61</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">62</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">63</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">64</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">65</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">66</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">67</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">68</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">69</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">70</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">71</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">72</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">73</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">74</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">75</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">76</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">77</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">78</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">79</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">80</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">81</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">82</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">83</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">84</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">85</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">86</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">87</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">88</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">89</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">90</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">91</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">92</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">93</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">94</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">95</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">96</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">97</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">98</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">99</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">100</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">101</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">102</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">103</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">104</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">105</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">106</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">107</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">108</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">109</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">110</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">111</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">112</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">113</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">114</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">115</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">116</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">117</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">118</li></ul>
在我们的main.cc中使用:
<code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#include <iostream> </span> <span class="hljs-preprocessor" style="margin: 0px; padding: 0px; color: rgb(68, 68, 68); box-sizing: border-box;">#include "minidump.h" </span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span><span class="hljs-constant" style="margin: 0px; padding: 0px; box-sizing: border-box;"> WINAPI </span>WinMain(HINSTANCE hInstance, <span class="hljs-constant" style="margin: 0px; padding: 0px; box-sizing: border-box;"> HINSTANCE </span>hPrevInstance, <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">char</span> * lpCmdLine, <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> nCmdShow) { SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); _asm <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">3</span> <span class="hljs-comment" style="margin: 0px; padding: 0px; color: rgb(136, 0, 0); box-sizing: border-box;">//只是为了让程序崩溃</span> <span class="hljs-keyword" style="margin: 0px; padding: 0px; color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="margin: 0px; padding: 0px; color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; }</code><ul class="pre-numbering" style="margin: 0px; padding: 6px 0px 40px; box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">1</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">2</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">3</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">4</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">5</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">6</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">7</li><li style="margin: 0px; padding: 0px 5px; box-sizing: border-box;">8</li></ul>
这样,在程序崩溃的时候,我们就会得到一个core.dump文件。
接下来也是重点,如何根据dump文件定位代码:
在VS中 文件->打开->文件
然后就是进行调试:
点击 使用仅限本机进行调试
这里需要注意的是:
dump文件 pdb文件 源码 要保持版本一直,否则就无法准确定位了。