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[]; 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文件的更多相关文章
- Windows下dump文件生成与分析
一. 生成Dump文件方式 1.1任务管理器 在程序崩溃后,先不关闭程序,在任务管理器中找到该程序对应的进程.右键—>创建转储文件. 此时会在默认的目录下创建出一个dump文件. 可以看出 ...
- 使用dbghelp生成dump文件以及事后调试分析
前言 在产品的实际应用环境中,如果我们的程序在客户那里出现了问题,例如程序异常了,而这个时候的现象又不能还原或者很难还原重现,那么只有使用dump文件来保存程序的当前运行信息,例如调用堆栈等,同时使用 ...
- 调试SQLSERVER (一)生成dump文件的方法
调试SQLSERVER (一)生成dump文件的方法 调试SQLSERVER (二)使用Windbg调试SQLSERVER的环境设置调试SQLSERVER (三)使用Windbg调试SQLSERVER ...
- 程序自动生成Dump文件
前言:通过drwtsn32.NTSD.CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD.CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD.CDB等调试工具.了解了 ...
- 程序自动生成Dump文件()
前言:通过drwtsn32.NTSD.CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD.CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD.CDB等调试工具.了解了 ...
- 如何设置C++崩溃时生成Dump文件
Dump 文件是进程的内存镜像 , 可以把程序的执行状态通过调试器保存到dump文件中 ; Dump 文件是用来给驱动程序编写人员调试驱动程序用的 , 这种文件必须用专用工具软件打开 , 比如使用 W ...
- JVM在遇到OOM(OutOfMemoryError)时生成Dump文件
方法一: 命令:jmap -dump:format=b,file=heap.bin file:保存路径及文件名pid:进程编号(windows通过任务管理器查看,linux通过ps aux查看) du ...
- 如何生成Dump文件
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何生成Dump文件.
- windows下dump文件调试
dump调试:在系统中异常或者崩溃的时候,来生成dump文件,然后用调试器来调试.这样就可以在生产环境中的dmp文件,拷贝到自己的开发机器上,调试就可以找到错误的位置,配合程序调试符号pdb文件,直接 ...
随机推荐
- 【dfs】p1025 数的划分
P1025 数的划分 题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5; 1,5,1; 5,1,1; 问有 ...
- python中无法被转化为set的list[list组成的list]
arr = [[a],[b]] set(arr) output: Traceback (most recent call last): File "<stdin>", ...
- LOJ#6282. 数列分块入门 6
一个动态的插入过程,还需要带有查询操作. 我可以把区间先分块,然后每个块块用vector来维护它的插入和查询操作,但是如果我现在这个块里的vector太大了,我可能的操作会变的太大,所以这时候我需要把 ...
- [SDOI2010]大陆争霸
幻想历8012年5月12日深夜,斯普林·布拉泽降下神谕:“Trust me, earn eternal life.”克里斯军团士气大增.作为克里斯军团的主帅,你决定利用这一机会发动奇袭,一举击败杰森国 ...
- BZOJ 1996: [Hnoi2010]chorus 合唱队(区间dp)
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=1996 题解: 这题刚拿到手的时候一脸懵逼qwq,经过思考与分析(看题解),发现是一道区间d ...
- iview 模态框点击确定按钮不消失
<div slot="footer"> <Button type="text" size="large" @click=& ...
- Linux基本命令总结(三)
接上篇: 11,more命令,功能类似 cat ,cat命令是整个文件的内容从上到下显示在屏幕上. more会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示 ...
- (转)C++ 值传递、指针传递、引用传递详解
一直以来对函数的值传递引用传递理解很模糊,这篇文章可以说是给自己扫盲了. 值传递:实参不会发生改变,是因为形参传递的是不是实参的源地址(形参和实参地址不一样).不影响实参 指针传递:本质也是值传递,只 ...
- listview 样式 LVS_REPORT 与 LVS_EDITLABELS 编辑单元格时,当前行第一列内容不显示
今天想做一个可编辑单元格的 listview,样式是 LVS_REPORT 与 LVS_EDITLABELS 网上搜索了一些相关资料,照葫芦画瓢写了一个,可测试的时候发现,当从第2列开始编辑的时候,第 ...
- 2019_01_16 sem_init
sem_init() #include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); S ...