The introduction part is transferred from https://www.cnblogs.com/lisuyun/p/5245609.html
Parts of the program are original.
Minidump way to save the program crash site
When using C++ to develop applications under the Windows platform, the last thing you want to see is that the program crashes. To solve the bugs that cause problems, the most difficult thing is to debug the release version. Because the release version lacks a lot of debugging information, not to mention that it is generally released for use by users, it is difficult to retain and reproduce the scene of the crash. There are currently some ways to solve it: crash address + MAP file; MAP file; SetUnhandledExceptionFilter + Minidump. This article focuses on the SetUnhandledExceptionFilter + Minidump method.
1. Minidump file generation
1. Minidump concept
minidump (small memory dump) can be understood as a dump file, which records the minimum useful information that can help debug crash. In fact, if you select “Small memory dump (64 KB)” in System Properties -> Advanced -> Startup and Recovery -> Settings -> Write Debug Information, when the system stops unexpectedly, it will be in C:\ A file with a .dmp suffix is generated under the Windows\Minidump\ path. This file is a minidump file, but this is a minidump in kernel mode.
What we want to generate is a user mode minidump, which contains the module information, thread information, stack call information, etc. of the program running. And in order to conform to the characteristics of its mini, the dump file is compressed.
2. Generate a minidump file
Dump files are generated by debugging tools such as drwtsn32, NTSD, CDB, etc. Although the shortcomings of drwtsn32 can be completely solved by NTSD and CDB, not all operating systems have installed debugging tools such as NTSD and CDB. According to the MiniDumpWriteDump interface, the Dump file can be automatically generated by the program. MiniDumpWriteDump is an API in MS DbgHelp.dll, which is used to export the dump of the currently running program.
3. Automatically generate Minidump file
When the program encounters an unhandled exception (mainly caused by a non-pointer) that causes the program to crash and die, if the SetUnhandledExceptionFilter() function is called before the exception occurs, the exception will be handed over to the function for processing. Described in MSDN as:
Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.
Therefore, add the SetUnhandledExceptionFilter() function at the beginning of the program, and use an appropriate method to generate a Dump file in the function to achieve the desired function.
#include #pragma comment(lib,"DbgHelp.lib") //Call SetUnhandledExceptionFilter in the main function SetUnhandledExceptionFilter(DumpCallback); LONG WINAPI DumpCallback(_EXCEPTION_POINTERS* excp) { boost::mutex::scoped_lock lock(g_dump_mutex); CreateDump(excp); return EXCEPTION_EXECUTE_HANDLER; } VOID CreateDump(struct _EXCEPTION_POINTERS *pExceptionPointers) { //collect information CStringW strBuild; strBuild.Format(L"Build: %s %s", __DATE__, __TIME__); CStringW strError; WCHAR* szModuleName = L"my_module_name"; strError.Format(L"%s %d , %d ,%d.", szModuleName, pExceptionPointers->ExceptionRecord->ExceptionCode, pExceptionPointers->ExceptionRecord->ExceptionFlags, pExceptionPointers->ExceptionRecord->ExceptionAddress); //Generate mini crash dump BOOL bMiniDumpSuccessful; WCHAR* szPath = L"./"; WCHAR szFileName[MAX_PATH]; WCHAR* szAppName = L"DumpFile"; WCHAR* szVersion = L"v1.0"; DWORD dwBufferSize = MAX_PATH; HANDLE hDumpFile; SYSTEMTIME stLocalTime; MINIDUMP_EXCEPTION_INFORMATION ExpParam; GetLocalTime(&stLocalTime); //GetTempPathW(dwBufferSize, szPath); StringCchPrintfW(szFileName, MAX_PATH, L"%s%s", szPath, szAppName); CreateDirectoryW(szFileName, NULL); //std::wcout << szFileName; StringCchPrintfW(szFileName, MAX_PATH, L"%s%s//%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", szPath, szAppName, szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, GetCurrentProcessId(), GetCurrentThreadId()); hDumpFile = CreateFileW(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); MINIDUMP_USER_STREAM UserStream[2]; MINIDUMP_USER_STREAM_INFORMATION UserInfo; UserInfo. UserStreamCount = 1; UserInfo. UserStreamArray = UserStream; UserStream[0].Type = CommentStreamW; UserStream[0].BufferSize = strBuild.GetLength()*sizeof(WCHAR); UserStream[0].Buffer = strBuild.GetBuffer(); UserStream[1].Type = CommentStreamW; UserStream[1].BufferSize = strError.GetLength()*sizeof(WCHAR); UserStream[1].Buffer = strError.GetBuffer(); ExpParam.ThreadId = GetCurrentThreadId(); ExpParam. ExceptiOnPointers = pExceptionPointers; ExpParam.ClientPointers = TRUE; MINIDUMP_TYPE MiniDumpWithDataSegs = (MINIDUMP_TYPE)(MiniDumpNormal |MiniDumpWithHandleData |MiniDumpWithUnloadedModules |MiniDumpWithIndirectlyReferencedMemory |MiniDumpScanMemory |MiniDumpWithProcessThreadData | MiniDumpWithThreadInfo); bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL); return; }
2. Debug Minidump file
- Double-click the minidump file (*.dmp). VisualStudio starts by default.
- In the menu Tools/Options, Debugging/Symbols, add the PDB file path. Note: If the minidump file is in the same directory as the pdb file, you don’t need to set this.
- If the debugged program needs the PDB information of the Microsoft basic library, you can add a path: http://msdl.microsoft.com/download/symbols
- Cache Symbol From symbol… Select the path to store these Symbols locally at the bottom of the interface. Note: If the pdb of Microsoft’s basic library has been stored locally, you can directly follow this step to set the local path, and you don’t need to perform the previous step.
- Set the code path: the dmp project just opened, enter the properties of the solution. Enter the code path of the source program here. Note: It must be the path where sln is located, not the path of vcproj!
6. Press F5 to debug.