windows生成dump文件
生活随笔
收集整理的這篇文章主要介紹了
windows生成dump文件
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
windows下程序有時突然崩潰了,偶發性的崩潰很難找。于是就需要保存崩潰時的dump信息了。
下面是關于如何生成dmp文件的代碼。
頭文件
#pragma once #include <windows.h> #include <DbgHelp.h> #include <stdlib.h> #include <string> #pragma comment(lib, "dbghelp.lib")namespace FrameworkMiniDump {std::wstring GetTimeNowString();std::string WStringToString(const std::wstring& str);std::wstring StringToWString(const std::string& str);std::string getexepath();inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName);inline BOOL CALLBACK MiniDumpCallback(PVOID pParam,const PMINIDUMP_CALLBACK_INPUT pInput,PMINIDUMP_CALLBACK_OUTPUT pOutput);inline void CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName);LONG __stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo);void DisableSetUnhandledExceptionFilter();// 此函數一旦成功調用,之后對 SetUnhandledExceptionFilter 的調用將無效void InitMinDump(); }?
源文件:
#include "MiniDump.h" #include <iostream> #include <ctime> #include <string>namespace FrameworkMiniDump {std::wstring GetTimeNowString(){time_t rawtime;struct tm * timeinfo;wchar_t buffer[80];time(&rawtime);timeinfo = localtime(&rawtime);//wcsftime(buffer, sizeof(buffer), L"%d-%m-%Y %H:%M:%S", timeinfo);wcsftime(buffer, sizeof(buffer), L"%d-%m-%Y-%H-%M-%S", timeinfo);std::wstring str(buffer);return str;}std::wstring StringToWString(const std::string& str){ #if defined(WIN32)size_t sz = str.length();int nd = MultiByteToWideChar(CP_ACP, 0, &str[0], sz, NULL, 0);std::wstring ret(nd, 0);int w = MultiByteToWideChar(CP_ACP, 0, &str[0], sz, &ret[0], nd);if (str.length() != sz) {throw std::exception("StringToWString Err");}return ret; #elseconst char* p = str.c_str();size_t len = str.length();size_t sz = len * sizeof(wchar_t);wchar_t* tp = new wchar_t[sz];size_t w = mbstowcs(tp, p, sz);if (w != len) {delete[] tp;throw std::exception("StringToWString Err");}std::wstring ret(tp);delete[] tp;return ret; #endif}std::string WStringToString(const std::wstring& str){size_t sz = str.length(); #if defined(WIN32)int nd = WideCharToMultiByte(CP_ACP, 0, &str[0], sz, NULL, 0, NULL, NULL);std::string ret(nd, 0);int w = WideCharToMultiByte(CP_ACP, 0, &str[0], sz, &ret[0], nd, NULL, NULL);/*if (ret.length() != sz) {throw std::exception("WStringToString Err");}*/return ret; #elseconst wchar_t* p = str.c_str();char* tp = new char[sz];size_t w = wcstombs(tp, p, sz);if (w != sz) {delete[] tp;throw std::exception("WStringToString Err");}std::string ret(tp);delete[] tp;return ret; #endif}std::string getexepath(){wchar_t result[MAX_PATH];std::wstring wstr = std::wstring(result, GetModuleFileName(NULL, result, MAX_PATH));return WStringToString(wstr);}inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName){if (pModuleName == 0){return FALSE;}WCHAR szFileName[_MAX_FNAME] = L"";_wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);if (_wcsicmp(szFileName, std::wstring(L"ntdll").c_str()) == 0)return TRUE;return FALSE;}inline BOOL CALLBACK MiniDumpCallback(PVOID pParam,const PMINIDUMP_CALLBACK_INPUT pInput,PMINIDUMP_CALLBACK_OUTPUT pOutput){if (pInput == 0 || pOutput == 0)return FALSE;switch (pInput->CallbackType){case ModuleCallback:if (pOutput->ModuleWriteFlags & ModuleWriteDataSeg)if (!IsDataSectionNeeded(pInput->Module.FullPath))pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);case IncludeModuleCallback:case IncludeThreadCallback:case ThreadCallback:case ThreadExCallback:return TRUE;default:;}return FALSE;}inline void CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName){HANDLE hFile = CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE)){MINIDUMP_EXCEPTION_INFORMATION mdei;mdei.ThreadId = GetCurrentThreadId();mdei.ExceptionPointers = pep;mdei.ClientPointers = NULL;MINIDUMP_CALLBACK_INFORMATION mci;mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;mci.CallbackParam = 0;::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal, (pep != 0) ? &mdei : 0, NULL, &mci);CloseHandle(hFile);}}LONG __stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo){std::string exename = "Dmp";std::wstring wexename = StringToWString(exename);;std::wstring filename = wexename + L"-" + GetTimeNowString() + L".dmp";CreateMiniDump(pExceptionInfo, filename.c_str());return EXCEPTION_EXECUTE_HANDLER;}// 此函數一旦成功調用,之后對 SetUnhandledExceptionFilter 的調用將無效void DisableSetUnhandledExceptionFilter(){void* addr = (void*)GetProcAddress(LoadLibrary(L"kernel32.dll"),"SetUnhandledExceptionFilter");if (addr){unsigned char code[16];int size = 0;code[size++] = 0x33;code[size++] = 0xC0;code[size++] = 0xC2;code[size++] = 0x04;code[size++] = 0x00;DWORD dwOldFlag, dwTempFlag;VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);}}void InitMinDump(){//注冊異常處理函數 SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);//使SetUnhandledExceptionFilter DisableSetUnhandledExceptionFilter();} }?
使用:
int main() {......FrameworkMiniDump::InitMinDump(); ...... }調用一下InitMinDump就可以了,這里面會注冊一個回調,崩潰時會保存的dmp文件。
注意:需要在debug模式。保存下來的dmp文件,需要結合pdb文件和源代碼才能定位到哪里崩潰了。具體的我也不懂。
?
轉載于:https://www.cnblogs.com/xcywt/p/10291219.html
總結
以上是生活随笔為你收集整理的windows生成dump文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【引用】Json 定义与操作
- 下一篇: 全套支付宝系统架构(内部架构图)【收藏】