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[]; 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, , &str[], sz, NULL, );
std::wstring ret(nd, );
int w = MultiByteToWideChar(CP_ACP, , &str[], sz, &ret[], nd);
if (str.length() != sz) { throw std::exception("StringToWString Err");
}
return ret;
#else
const 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, , &str[], sz, NULL, , NULL, NULL);
std::string ret(nd, );
int w = WideCharToMultiByte(CP_ACP, , &str[], sz, &ret[], nd, NULL, NULL);
/*if (ret.length() != sz) {
throw std::exception("WStringToString Err");
}*/
return ret;
#else
const 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 == )
{
return FALSE;
} WCHAR szFileName[_MAX_FNAME] = L"";
_wsplitpath(pModuleName, NULL, NULL, szFileName, NULL); if (_wcsicmp(szFileName, std::wstring(L"ntdll").c_str()) == )
return TRUE; return FALSE;
} inline BOOL CALLBACK MiniDumpCallback(PVOID pParam,
const PMINIDUMP_CALLBACK_INPUT pInput,
PMINIDUMP_CALLBACK_OUTPUT pOutput)
{
if (pInput == || pOutput == )
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 = ; ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal, (pep != ) ? &mdei : , 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[];
int size = ; 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文件和源代码才能定位到哪里崩溃了。具体的我也不懂。

windows生成dump文件的更多相关文章

  1. Windows下dump文件生成与分析

    一.    生成Dump文件方式 1.1任务管理器 在程序崩溃后,先不关闭程序,在任务管理器中找到该程序对应的进程.右键—>创建转储文件. 此时会在默认的目录下创建出一个dump文件. 可以看出 ...

  2. 使用dbghelp生成dump文件以及事后调试分析

    前言 在产品的实际应用环境中,如果我们的程序在客户那里出现了问题,例如程序异常了,而这个时候的现象又不能还原或者很难还原重现,那么只有使用dump文件来保存程序的当前运行信息,例如调用堆栈等,同时使用 ...

  3. 调试SQLSERVER (一)生成dump文件的方法

    调试SQLSERVER (一)生成dump文件的方法 调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置调试SQLSERVER (三)使用Windbg调试SQLSERVER ...

  4. 程序自动生成Dump文件

    前言:通过drwtsn32.NTSD.CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD.CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD.CDB等调试工具.了解了 ...

  5. 程序自动生成Dump文件()

    前言:通过drwtsn32.NTSD.CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD.CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD.CDB等调试工具.了解了 ...

  6. 如何设置C++崩溃时生成Dump文件

    Dump 文件是进程的内存镜像 , 可以把程序的执行状态通过调试器保存到dump文件中 ; Dump 文件是用来给驱动程序编写人员调试驱动程序用的 , 这种文件必须用专用工具软件打开 , 比如使用 W ...

  7. JVM在遇到OOM(OutOfMemoryError)时生成Dump文件

    方法一: 命令:jmap -dump:format=b,file=heap.bin file:保存路径及文件名pid:进程编号(windows通过任务管理器查看,linux通过ps aux查看) du ...

  8. 如何生成Dump文件

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何生成Dump文件.

  9. windows下dump文件调试

    dump调试:在系统中异常或者崩溃的时候,来生成dump文件,然后用调试器来调试.这样就可以在生产环境中的dmp文件,拷贝到自己的开发机器上,调试就可以找到错误的位置,配合程序调试符号pdb文件,直接 ...

随机推荐

  1. luogu5008 逛庭院 (tarjan缩点)

    首先如果这是一个DAG,我按照拓扑序倒着去选,一定能选到所有入度不为0的点 然后考虑有环的情况 我们拎出来一个强连通分量 先假设它缩点以后是没有入度的 那我最后它里面一定至少剩一个不能选 因为就剩一个 ...

  2. Ubuntu18.04 下 VirtualBox or VMWare 虚拟化问题

    This host supports Intel VT-x, but Intel VT-x is disabled.Intel VT-x might be disabled if it has bee ...

  3. js jquery 数组的合并 对象的合并

    转载自:http://www.cnblogs.com/xingxiangyi/p/6416468.html 1 数组合并 1.1 concat 方法 1 2 3 4 var a=[1,2,3],b=[ ...

  4. Django(二十)model中的 class Meta

    https://www.cnblogs.com/tongchengbin/p/7670927.html class Main(models.Model): img = models.CharField ...

  5. PHP的SQL语句优化

    (转)仅供自己学习,特此转发 普遍遇到的慢SQL有以下三种: 1.未走索引 2.where条件里包含子查询,多表联查 3.查询大量数据 解决 一.索引:SQL中的高速公路 但凡优化SQL,首先要看的就 ...

  6. 第二十九节,目标检测算法之R-CNN算法详解

    Girshick, Ross, et al. “Rich feature hierarchies for accurate object detection and semantic segmenta ...

  7. selenium官方网站文档,testng官方网站文档

    selenium 阅读至grid部分,当前没有远程需求,搁置:https://www.seleniumhq.org/docs/07_selenium_grid.jsp testng http://te ...

  8. Linux系统诊断必备技能之一:lsof 用法详解!

    lsof(list open files)是一个查看当前系统文件的工具.在linux环境下,任何事物都以文件的形式存在,用户通过文件不仅可以访问常规数据,还可以访问网络连接和硬件:如传输控制协议 (T ...

  9. day-03(js)

    回顾: css: 层叠样式表 作用: 渲染页面 提供工作效率,将html和样式分离 和html的整合 方式1:内联样式表 通过标签的style属性 <xxx style="...&qu ...

  10. jquery 实现按回车键登录功能的写法

    <script> //登录的逻辑函数 自己写 function submitFuc(){ var loginName= $("#loginName").val(); v ...