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. Age of Moyu HDU - 6386 (杭电多校7A)

    给出n和点,m条边,每条边有各自的标号,进入第一个标号需要消耗1的费用,此后转换标号需要1费用,在同一个标号上走不需要费用.问你从1到n最少需要多少费用. 最短路变形,把第一个点看成不存在的标号,然后 ...

  2. LOJ#6280. 数列分块入门 4

    另外开一个数组维护每一个块内的总和. 给区间加值是,残余的块一个一个点更新,整个的块一次性更新 查询的时候也是,残余的块一个一个点加,整个的块一次性加 #include<map> #inc ...

  3. 牛客练习赛43 Tachibana Kanade Loves Review C(最小生成树Kruskal)

    链接:https://ac.nowcoder.com/acm/contest/548/C来源:牛客网 题目描述 立华奏是一个刚刚开始学习 OI 的萌新. 最近,实力强大的 QingyuQingyu 当 ...

  4. Miniconda 虚拟环境安装及应用

    首先要下载Miniconda安装包 下载地址  链接:https://pan.baidu.com/s/1rj-9exKBSHnCCxqq7JQSxA      提取码:ab53 下一步 打开下载好的M ...

  5. Web 服务器被配置为不列出此目录的内容。

    vs2015运行类库程序,遇到问题如下图, 最可能的原因: 没有为请求的 URL 配置默认文档,并且没有在服务器上启用目录浏览. 解决方法: 确认网站或应用程序配置文件中的 configuration ...

  6. python enumarate方法的使用

    '''enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中.'''

  7. tcping 与 telnet命令粗略使用

        使用tcping命令,在网上下载tcping文件,放入c盘的system32目录下,即可使用 使用tcping命令用来ping某个端口,能通的话,说明从外部到端口是没有问题的 使用telnet ...

  8. python: 基本知识(二)

    1.set() set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集.差集.并集等. x = set('hello’) y = set('world') x ---- ...

  9. 有了这8款Mac安全杀毒和流氓防护软件,让你的mac清理优化,更加安全

    其实Mac系统相对Windows来说更加安全,主要原因是针对Mac系统的病毒和流氓软件并不多,而且Mac系统的安全机制也更加完善,不过为了更加安全的使用Mac,使用以下8款Mac 杀毒安全.安全防护和 ...

  10. HTML常用提交按钮

    1. 标签=元素 disabled(不可操作)  readonly(只读)  placeholder(提示文本) autofocus(自动获焦)  autocomplete=”on(默认.规定启用自动 ...