开发者社区> y2hr4cjzssnlm> 正文

dump系列(2)C++程序异常或内存错误,导致闪退的解决办法:分析dump文件

简介: dump系列(2)C++程序异常或内存错误,导致闪退的解决办法:分析dump文件
+关注继续查看

如何在发布后程序中捕获程序的崩溃和异常往往是比较麻烦的事情,一般采用日志记录的方法来记录程序运行的每个流程,但是通常为了程序运行的性能,日志记录的方法只是记录程序运行的每个主要的处理流程,不能进行具体详细的记录,比如for 循环中的崩溃记录。C++语言中调用window API函数CreateFile()和MiniDumpWriteDump(),可以方便的记录程序崩溃时的Dump信息,并保持dump文件,根据dump文件对应的源码工程和.pdb文件,我们就可以快速的定位到程序崩溃的源码位置,极大的提高了调试代码的效率。然而,Dump记录程序崩溃的方法不是万能的,有时候一些数组越界、容器访问异常等致命的问题,也不一定能准确的记录下来。总之,Dump文件记录程序崩溃的方法是开放人员常用的方法,并且能捕获大多数的程序崩溃问题。


1、程序中加入存储Dump的代码


通过SetUnhandledExceptionFilter设置捕获dump的入口,然后通过MiniDumpWriteDump生成dump文件。


头文件dump.h

#pragma once
#define SOFTWARE_VERSION      _T("V1.0.202001")
int GenerateMiniDump(PEXCEPTION_POINTERS pExceptionPointers);
LONG ApplicationCrashHandler(LPEXCEPTION_POINTERS lpExceptionInfo);


源文件dump.cpp

#include "stdafx.h"
#include "dump.h"
#include <Windows.h>
#include <DbgHelp.h>
 
//需要用到文件dbghelp.dll,可以从以下路径拷贝
//C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions\Cpp\dbghelp.dll
//C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions\Cpp\x64\dbghelp.dll
 
// 创建Dump文件
int GenerateMiniDump(PEXCEPTION_POINTERS pExceptionPointers)
{
    // 定义函数指针
    typedef BOOL(WINAPI * MiniDumpWriteDumpT)(
        HANDLE,
        DWORD,
        HANDLE,
        MINIDUMP_TYPE,
        PMINIDUMP_EXCEPTION_INFORMATION,
        PMINIDUMP_USER_STREAM_INFORMATION,
        PMINIDUMP_CALLBACK_INFORMATION
        );
 
    // 从"DbgHelp.dll"库中获取"MiniDumpWriteDump"函数
    MiniDumpWriteDumpT pfnMiniDumpWriteDump = NULL;
    HMODULE hDbgHelp = LoadLibrary(L"dbghelp.dll");
    if (NULL == hDbgHelp)
    {
        return EXCEPTION_CONTINUE_EXECUTION;
    }
 
    pfnMiniDumpWriteDump = (MiniDumpWriteDumpT)GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
    if (NULL == pfnMiniDumpWriteDump)
    {
        FreeLibrary(hDbgHelp);
        return EXCEPTION_CONTINUE_EXECUTION;
    }
 
    // 创建dmp文件
    TCHAR szFileName[MAX_PATH] = { 0 };
    TCHAR* szVersion = SOFTWARE_VERSION;
    SYSTEMTIME stLocalTime;
    GetLocalTime(&stLocalTime);
    wsprintf(szFileName, L"%04d%02d%02d_%02d%02d%02d_%s.dmp",
        stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
        stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, szVersion);
 
    HANDLE hDumpFile = CreateFile(szFileName, GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_WRITE | FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
    if (INVALID_HANDLE_VALUE == hDumpFile)
    {
        FreeLibrary(hDbgHelp);
        return EXCEPTION_CONTINUE_EXECUTION;
    }
 
    // 写入dmp文件
    MINIDUMP_EXCEPTION_INFORMATION expParam;
    expParam.ThreadId = GetCurrentThreadId();
    expParam.ExceptionPointers = pExceptionPointers;
    expParam.ClientPointers = FALSE;
    pfnMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
        hDumpFile, MiniDumpWithDataSegs, (pExceptionPointers ? &expParam : NULL), NULL, NULL);
 
    // 释放文件
    CloseHandle(hDumpFile);
    FreeLibrary(hDbgHelp);
    return EXCEPTION_EXECUTE_HANDLER;
}
 
// 处理Unhandled Exception的回调函数
LONG ApplicationCrashHandler(LPEXCEPTION_POINTERS lpExceptionInfo)
{
    // 这里做一些异常的过滤或提示
    if (IsDebuggerPresent())
    {
        return EXCEPTION_CONTINUE_SEARCH;
    }
 
    return GenerateMiniDump(lpExceptionInfo);
}

举例MFC项目程序,在app入口添加SetUnhandledExceptionFilter


#include "stdafx.h"
#include "dump.h"
BOOL CSmartDispenserApp::InitInstance()
{
    //加入崩溃自动记录dump文件功能
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
    ...
}


2、如何分析dump文件?


详情参见我的另一篇博文《Windows下dump文件生成与分析


 


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
解决.Net 4.0 A potentially dangerous Request.Form value was detected from the client 异常
解决ASP.NET 4.0   "A potentially dangerous Request.Form value was detected from the client". 错误在.net中,Request时出现有HTML或Javascript等字符串时,系统会认为是危险性值。
873 0
“/”应用程序中的服务器错误。
从客户端(ftb1="fadsf...")中检测到有潜在危险的 Request.Form 值。 说明: 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止。该值可能指示危及应用程序安全的尝试,如跨站点的脚本攻击。
1018 0
IE中ocx控件的无模式对话框不接收方向键等键盘消息的问题的解决办法
在ocx控件中如果含有无模式对话框,那么当ocx在ie中显示时,往往接收不到 诸如tab,方向键和退格键。所有这些消息都被IE容器给截取了,对于这个问题,ms给出了解决方法: 首先:   int CMyActiveXCtrl::OnCreate(LPCREATESTRUCT lpCreateStru...
943 0
未能解析目标框架“.NETFramework,Version=v4.0”的 mscorlib 错误的解决办法
VS2010有时候莫名出现下面问题: 未能解析目标框架“.NETFramework,Version=v4.0”的 mscorlib 错误 相关的工程出现这个问题,可能是使用同步盘同步的引起的。
2511 0
只需4个步骤,分析解决在生产环境下JVM内存泄露问题
只需4个步骤,分析解决在生产环境下JVM内存泄露问题
4874 0
WINDOWS下,找包含特殊字串的文件的解决办法
WINDOWS下,找包含特殊字串的文件的解决办法
28 0
[软考考点解析]软件设计师--内存按字节编址
1. 概念 内存按字节编址的意思,就是每个地址指向的储存单元可以保存1个字节的数据,也就是8bit(8个二进制位)。 此处注意几个常用单位: 1B(Byte 字节)=8bit 1KB (Kilobyte 千字节)=1024B 1MB (Mega byte 兆字节)=1024KB 1GB (Giga byte 吉字节)=1024MB 然后1024的话是2^10。
27 0
【错误记录】Flutter 设备连接显示 Loading... ( 断网 | 删除 flutter/bin/cache/lockfile 文件 )
【错误记录】Flutter 设备连接显示 Loading... ( 断网 | 删除 flutter/bin/cache/lockfile 文件 )
24 0
682
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载