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. APIO2018解题报告

    今年的APIO好邪啊. T1铁人两项 题目大意 给一个无向图,问有多少三元组(三个元素两两不同)使得它们构成一条简单路径 . 题解 无向图这种东西不好直接处理,考虑点双缩点建圆方树. 然后就出现了一个 ...

  2. BZOJ2801/洛谷P3544 [POI2012]BEZ-Minimalist Security(题目性质发掘+图的遍历+解不等式组)

    题面戳这 化下题面给的式子: \(z_u+z_v=p_u+p_v-b_{u,v}\) 发现\(p_u+p_v-b_{u,v}\)是确定的,所以只要确定了一个点\(i\)的权值\(x_i\),和它在同一 ...

  3. CF1101F Trucks and Cities

    题意:给定线段上n个特殊点,m次询问. 每次询问:在第l个点到第r个点这一段区间中选出k个点,将其分成k + 1段.使得最长的段尽量短. 输出这m个询问中答案最大的. n<=400,m<= ...

  4. 利用sqlalchemy读取数据库 和pandas的Dataframe对象 互相生成

    #导入pandas import pandas as pd import numpy as np #导入SqlAlchemy from sqlalchemy import create_engine ...

  5. java面试——问题回溯

    背景:用来记录面试过程中遇到的问题,在这里进行记录,下次不要犯同样的错误. 迪普科技 Linux服务器下的top命令 #动态更新的虚拟文件实际上是许多其他内存相关工具(如:free / ps / to ...

  6. Cannot read property 'properties' of undefined

    今天运行一个很有意思的项目,报上面的错 根据报错,可以发现,报错出现在项目文件夹下的node_modules\webpack-cli\bin\config-yargs.js文件第89行. 当前webp ...

  7. Python基础-元组、列表、字典

    元组tuple 元组被称为只读列表,即数据可以被查询,但不能被修改,所以,字符串的切片操作同样适用于元组.例:(1,2,3)("a","b","c&q ...

  8. vcftools报错:Writing PLINK PED and MAP files ... Error: Could not open temporary file.解决方案

    一般来说有两种解决方案. 第一种:添加“--plink-tped”参数: 用vcftools的“--plink”参数生成plink格式文件时,小样本量测试可以正常生成plink格式,用大样本量时产生W ...

  9. Proxy代理模式

    https://www.cnblogs.com/vincentzh/p/5988145.html https://www.cnblogs.com/wrbxdj/p/5267370.html(不错)

  10. Luogu P3868 [TJOI2009]猜数字

    题目链接 \(Click\) \(Here\) 中国剩余定理的板子.小心取模. #include <bits/stdc++.h> using namespace std; const in ...