如何让C++程序生成dump文件?生成dump文件的方式有哪些?如何使用Windbg分析dump文件?

目录

1、API函数SetUnhandledExceptionFilter介绍

2、调用SetUnhandledExceptionFilter设置异常处理函数

3、调用MiniDumpWriteDump函数导出包含异常上下文的dump文件

4、生成dump文件的多种生成

4.1、调用SetUnhandledExceptionFilter设置异常处理回调函数,然后调用MiniDumpWriteDump生成dump文件

4.2、安装异常捕获模块,由该模块感知异常并自动生成dump文件(最常用的方式)

4.3、从任务管理器中导出dump文件

4.4、在动态调试的Windbg中使用.dump命令导出dump文件

4.5、Windows系统感知到程序发生了异常,自动生成dump文件

5、使用Windbg分析dump文件

5.1、Windbg版本与安装

5.2、Windbg常用命令

5.3、使用Windbg分析dump文件

6、最后


C++软件异常排查从入门到精通系列教程(核心精品专栏,订阅量已达8000多个,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++实战专栏(重点专栏,专栏文章已更新500多篇,订阅量已达6000多个,欢迎订阅,持续更新中...)https://blog.csdn.net/chenlycly/article/details/140824370C++ 软件开发从入门到实战(重点专栏,专栏文章已更新300多篇,欢迎订阅,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.htmlVC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_2276111.html C++程序在运行过程中会时常发生内存越界、内存访问违例、Stack overflow线程栈溢出、空指针与野指针等异常崩溃,仅仅是依靠Debug和Release下的调试是远远不够的,因为有些崩溃不是必现的,或者是Debug或Release下很难复现。所以我们需要让C++程序自动感知并捕获到异常,自动生成包含异常上下文的dump文件,以供事后使用Windbg等工具进行分析排查。本文我们就来详细介绍一下如何让C++程序生成dump文件、生成dump文件的多种方式以及如何使用Windbg分析dump文件。

1、API函数SetUnhandledExceptionFilter介绍

Windows系统提供设置异常处理函数的API函数SetUnhandledExceptionFilter,调用该接口向系统注册当前程序的异常处理函数,当程序发生异常时系统会调用设置的异常处理函数,这样程序就能感知到了,可以调用MiniDumpWriteDump生成包含异常上下文的dump文件,事后使用Windbg分析这个dump文件去分析排查。

API函数SetUnhandledExceptionFilter的声明如下:

cpp 复制代码
LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(
  [in] LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
);

该函数的参数就是设置的异常处理函数。当软件发生异常时,会回调设置的异常处理函数,异常处理函数的原型如下:

cpp 复制代码
LONG WINAPI SEHUnhandledExceptionFilter(PEXCEPTION_POINTERS pExInfo)

该函数的参数存放的是异常信息的结构体EXCEPTION_POINTERS指针,如下:

cpp 复制代码
//
// Typedef for pointer returned by exception_info()
//
typedef struct _EXCEPTION_POINTERS {
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT ContextRecord;
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

其中,EXCEPTION_RECORD结构体定义如下:

cpp 复制代码
//
// Exception record definition.
//
typedef struct _EXCEPTION_RECORD {
    DWORD    ExceptionCode;
    DWORD ExceptionFlags;
    struct _EXCEPTION_RECORD *ExceptionRecord;
    PVOID ExceptionAddress;
    DWORD NumberParameters;
    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    } EXCEPTION_RECORD;

typedef EXCEPTION_RECORD *PEXCEPTION_RECORD;

上述结构体中的ExceptionCode字段对应异常类型的异常码,常见的异常码有:

cpp 复制代码
#define STATUS_ACCESS_VIOLATION          ((DWORD   )0xC0000005L)    // 内存访问违例
#define STATUS_IN_PAGE_ERROR             ((DWORD   )0xC0000006L)    
#define STATUS_INVALID_HANDLE            ((DWORD   )0xC0000008L)    
#define STATUS_INVALID_PARAMETER         ((DWORD   )0xC000000DL)    // 无效参数
#define STATUS_NO_MEMORY                 ((DWORD   )0xC0000017L)    
#define STATUS_ILLEGAL_INSTRUCTION       ((DWORD   )0xC000001DL)    
#define STATUS_NONCONTINUABLE_EXCEPTION  ((DWORD   )0xC0000025L)    
#define STATUS_INVALID_DISPOSITION       ((DWORD   )0xC0000026L)    
#define STATUS_ARRAY_BOUNDS_EXCEEDED     ((DWORD   )0xC000008CL)    // 数组越界
#define STATUS_FLOAT_DENORMAL_OPERAND    ((DWORD   )0xC000008DL)    
#define STATUS_FLOAT_DIVIDE_BY_ZERO      ((DWORD   )0xC000008EL)    
#define STATUS_FLOAT_INEXACT_RESULT      ((DWORD   )0xC000008FL)    
#define STATUS_FLOAT_INVALID_OPERATION   ((DWORD   )0xC0000090L)    
#define STATUS_FLOAT_OVERFLOW            ((DWORD   )0xC0000091L)    
#define STATUS_FLOAT_STACK_CHECK         ((DWORD   )0xC0000092L)    
#define STATUS_FLOAT_UNDERFLOW           ((DWORD   )0xC0000093L)    
#define STATUS_INTEGER_DIVIDE_BY_ZERO    ((DWORD   )0xC0000094L)    // 除0崩溃
#define STATUS_INTEGER_OVERFLOW          ((DWORD   )0xC0000095L)    
#define STATUS_PRIVILEGED_INSTRUCTION    ((DWORD   )0xC0000096L)    
#define STATUS_STACK_OVERFLOW            ((DWORD   )0xC00000FDL)    // 线程栈溢出
#define STATUS_DLL_NOT_FOUND             ((DWORD   )0xC0000135L)    
#define STATUS_ORDINAL_NOT_FOUND         ((DWORD   )0xC0000138L)    
#define STATUS_ENTRYPOINT_NOT_FOUND      ((DWORD   )0xC0000139L)    
#define STATUS_CONTROL_C_EXIT            ((DWORD   )0xC000013AL)    
#define STATUS_DLL_INIT_FAILED           ((DWORD   )0xC0000142L)    
#define STATUS_FLOAT_MULTIPLE_FAULTS     ((DWORD   )0xC00002B4L)    
#define STATUS_FLOAT_MULTIPLE_TRAPS      ((DWORD   )0xC00002B5L)    
#define STATUS_REG_NAT_CONSUMPTION       ((DWORD   )0xC00002C9L)    
#define STATUS_STACK_BUFFER_OVERRUN      ((DWORD   )0xC0000409L)    // 栈内存buffer越界
#define STATUS_INVALID_CRUNTIME_PARAMETER ((DWORD   )0xC0000417L) 

此外,存放线程上下文信息的结构体CONTEXT的定义如下:

cpp 复制代码
//
// Context Frame
//
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) is is used to constuct a call frame for APC delivery,
//  and 3) it is used in the user level thread creation routines.
//
//  The layout of the record conforms to a standard call frame.
//

typedef struct _CONTEXT {

    //
    // The flags values within this flag control the contents of
    // a CONTEXT record.
    //
    // If the context record is used as an input parameter, then
    // for each portion of the context record controlled by a flag
    // whose value is set, it is assumed that that portion of the
    // context record contains valid context. If the context record
    // is being used to modify a threads context, then only that
    // portion of the threads context will be modified.
    //
    // If the context record is used as an IN OUT parameter to capture
    // the context of a thread, then only those portions of the thread's
    // context corresponding to set flags will be returned.
    //
    // The context record is never used as an OUT only parameter.
    //

    DWORD ContextFlags;

    //
    // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
    // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
    // included in CONTEXT_FULL.
    //

    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
    //

    FLOATING_SAVE_AREA FloatSave;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_SEGMENTS.
    //

    DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_INTEGER.
    //

    DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_CONTROL.
    //

    DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;

    //
    // This section is specified/returned if the ContextFlags word
    // contains the flag CONTEXT_EXTENDED_REGISTERS.
    // The format and contexts are processor specific
    //

    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

该结构体中主要存放各个寄存器的信息。

2、调用SetUnhandledExceptionFilter设置异常处理函数

设置异常处理函数的示例代码如下:

cpp 复制代码
// 异常处理函数(回调函数)
LONG WINAPI SEHUnhandledExceptionFilter( PEXCEPTION_POINTERS pExInfo )
{
    // 处理异常的代码
	// ......
	
    return EXCEPTION_EXECUTE_HANDLER;
}

// 调用SetUnhandledExceptionFilter设置异常处理函数
LPTOP_LEVEL_EXCEPTION_FILTER oldExceptionFilter = SetUnhandledExceptionFilter( SEHUnhandledExceptionFilter );

调用系统API函数SetUnhandledExceptionFilter像系统注册当前程序的异常处理函数,当程序发生异常时系统会调用设置的异常处理函数。

3、调用MiniDumpWriteDump函数导出包含异常上下文的dump文件

dump文件最终都是调用API函数MiniDumpWriteDump去生成的,生成dump文件的示例代码如下:

cpp 复制代码
void CreateDump(struct _EXCEPTION_POINTERS *pExceptionPointers) 
{
    CString strDumpFile = _T("E:\\2025-1210.dump");
	
	HANDLE hDumpFile;
	hDumpFile = CreateFile(strDumpFile, GENERIC_READ|GENERIC_WRITE, 
		FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);

	MINIDUMP_EXCEPTION_INFORMATION ExpParam;
	ExpParam.ThreadId = GetCurrentThreadId();
	ExpParam.ExceptionPointers = pExceptionPointers;
	ExpParam.ClientPointers = TRUE;

    // 此处调整参数,确定要导出的dump文件中包含的信息多少
	MINIDUMP_TYPE MiniDumpWithDataSegs = (MINIDUMP_TYPE)(MiniDumpNormal 
		| MiniDumpWithHandleData 
		| MiniDumpWithUnloadedModules 
		| MiniDumpWithIndirectlyReferencedMemory 
		| MiniDumpScanMemory 
		| MiniDumpWithProcessThreadData 
		| MiniDumpWithThreadInfo);

	BOOL bMiniDumpSuccessful = FALSE;
	bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), 
		hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);

	return;
}

上述接口中我们调用MiniDumpWriteDump接口导出dump文件,上述代码导出的是mini dump文件,文件大小大概在几MB左右。如果要导出包含所有信息的全dump文件,则会比较大,大概在几百MB到上GB的大小。**可以通过调整调用MiniDumpWriteDump接口的第四个参数来确定导出的dump文件中包含哪些异常信息。**如包含的信息越多,dump文件会越大。

mini dump文件和全dump文件的区别在于,全dump文件包含了所有的信息,而mini dump只包含了部分信息。在全dump文件中,使用Windbg可以查看所有变量内存中的值,而mini dump中只能查看到部分变量的值,某些变量的值可能是排查问题的关键线索。

一般我们在自动生成dump文件时,文件不宜太大,如果太大的话,会占用PC大量的磁盘空间。dump文件包含一些概要信息就可以排查问题了,没必要导出包含所有信息的全dump文件的。在某些特殊的情况下,为了方便排查问题,可能需要包含所有信息的全dump文件,具体情况具体分析吧。

4、生成dump文件的多种生成

分析dump文件是排查C++程序异常的最常用方法。那dump文件是如何产生的呢?主要有以下几个途径生成dump文件。

4.1、调用SetUnhandledExceptionFilter设置异常处理回调函数,然后调用MiniDumpWriteDump生成dump文件

这种方式,我们上面已经详细讲了,这里就不再重复说了。这种方式有一定的缺陷,很多异常是捕获不到的。

4.2、安装异常捕获模块,由该模块感知异常并自动生成dump文件(最常用的方式)

一般Windows程序中都会安装异常捕获模块(比如google开源的CrashRpt / breakpad / crashpad),一旦软件发生异常崩溃,该异常捕获模块就能感知到,就会将发生异常时的异常上下文信息导出到dump文件中。比如QQ、钉钉、企业微信等常用的主流软件中都安装了异常捕获模块,当软件发生异常时可能会弹出如下的提示框:

提示软件发生了崩溃,询问是否将崩溃信息(崩溃时的日志文件以及包含异常上下文的dump文件等)上报给后台,后台搜集到这些信息,就可以自行分析排查了。

关于异常捕获库的详细介绍,可以查看我的文章:

基于开源CrashRpt与微软开源Detours技术深度改造的异常捕获库分享https://blog.csdn.net/chenlycly/article/details/138075577

4.3、从任务管理器中导出dump文件

程序发生异常时(比如窗口不可点击、程序发生卡死(可能是发生死循环、死锁导致的)),如果进程还在,可以到Windows系统的任务管理器中右键点击目标进程,在弹出的右键菜单中点击"创建转储文件"菜单项导出dump文件。比如程序弹出崩溃报错提示框时,或者程序发生死循环或死锁时,程序进程还在的,可以尝试从任务管理器中导出dump文件去分析的。


在这里,给大家重点推荐一下我的几个热门畅销专栏,欢迎订阅:(博客主页还有其他专栏,可以去查看)

专栏1:【C++软件异常与异常排查从入门到精通系列教程】该精品技术专栏的订阅量已达到10000多个,专栏中包含大量项目实战分析案例,有很强的实战参考价值,广受好评!专栏文章持续更新中,已经更新到200篇以上!欢迎订阅!)

C++软件调试与异常排查从入门到精通系列文章汇总https://blog.csdn.net/chenlycly/article/details/125529931

本专栏根据多年C++软件异常排查的项目实践,系统地总结了引发C++软件异常的常见原因以及排查C++软件异常的常用思路与方法详细讲述了C++软件的调试方法与手段详细介绍分析C++软件问题的常用分析工具, 以图文并茂的方式给出具体的项目问题实战分析实例(详细讲述分析排查过程,很有实战参考价值),带领大家逐步掌握C++软件调试与异常排查的相关技术,适合基础进阶和想做技术提升的相关C++开发人员!

考察一个开发人员的水平,一是看其编码及设计能力,二是要看其软件调试能力 !所以软件调试能力(排查软件异常的能力)很重要,必须重视起来!能解决一般人解决不了的问题,既能提升个人能力及价值,也能体现对团队及公司的贡献!

**专栏中的文章都是通过项目实战总结出来的,包含大量项目问题实战分析案例,有很强的实战参考价值!**专栏文章还在持续更新中,预计文章篇数能更新到200篇以上!

专栏2:【C/C++实战进阶】 (该专栏涵盖了C++多方面的内容,是当前重点打造的专栏,订阅量已达8000多个,专栏文章已经更新到500多篇,持续更新中...)

C/C++实战进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html

以多年的开发实战为基础,总结并讲解一些的C/C++基础与项目实战进阶内容,以图文并茂的方式对相关知识点进行详细地展开与阐述!专栏涉及了C/C++领域多个方面的内容,包括C++基础及编程要点 (模版泛型编程、STL容器及算法函数的使用等)、数据结构与算法C++11及以上新特性 (开源代码中可能会用到很多新特性(比如WebRTC开源库),日常编码中也会用到部分新特性,面试时也会频繁地涉及到,学习新特性很有必要)、常用C++开源库的介绍与使用 (比如SQLite、libcurl、libwebsockets、libevent、jsoncpp/RapidJson、Redis、RabbitMQ、MongoDB、MQTT、ZooKeeper、OpenCV、FFmpeg、SDL、GStreamer、Live555、ReactOS等)、代码分享 (调用系统API、使用开源库)、常用编程技术 (动态库、多线程、多进程、数据库及网络编程等)、软件UI编程 (Win32/duilib/QT/MFC)、C++软件调试技术 (引发C++软件异常的常见原因分析与总结、排查C++软件异常的手段与方法、分析C++软件异常的基础知识、使用常用软件分析工具分析C++软件问题、多个项目实战问题分析案例分享等)、设计模式 (单例模式、工厂模式、观察者模式、状态模式等)、网络基础知识与网络问题分析进阶内容(实战问题分析实例分享)等。本专栏的内容都是建立在项目实践的基础上,来源于项目实战,服务于项目实战,很有实战参考价值!

专栏3:【分析C++软件问题的实用软件与高效工具实战案例集锦】

C++常用软件分析工具从入门到精通案例集锦汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/131405795

在C++软件开发与维护的过程中,常用的C++软件辅助分析工具有SPY++、PE工具、Dependency Walker、GDIView、Process Explorer、Process Monitor、API Monitor、Clumsy、Windbg、IDA Pro以及内存泄漏检测工具等,本专栏详细介绍如何使用这些工具去巧妙地分析和解决日常工作中遇到的问题,很有实战参考价值!

专栏4:【VC++常用功能代码封装】

VC++常用功能开发汇总(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/article/details/124272585

将10多年C++开发实践中常用的功能,以高质量的代码展现出来。这些常用的高质量规范代码,可以直接拿到项目中使用,能有效地解决软件开发过程中遇到的问题。

专栏5:【C/C++软件开发从入门到实战】 (本专栏涵盖了C++多方面的内容,是当前重点打造的专栏,专栏文章已经更新到300多篇,持续更新中!欢迎订阅!)

C++ 软件开发从入门到精通(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_12695902.html

根据多年C++软件开发实践,详细地总结了C/C++软件开发相关技术实现细节,分享了大量的实战案例,很有实战参考价值。


4.4、在动态调试的Windbg中使用.dump命令导出dump文件

程序发生异常时进程还在,比如程序发生死循环或多线程死锁,此时可以直接将Windbg挂载到正在运行的目标进程上,然后使用.dump命令导出包含异常上下文信息的dump文件。

软件异常问题是必现的或者比较好复现,可以直接使用Windbg启动软件,和软件一起跑,一旦软件发生异常崩溃,Windbg就会感知到并中断下来,此时用.dump命令将异常上下文信息导出到dump文件中。

使用.dump命令导出dump文件的命令如下:

.dump /ma D:\20221118.dmp

Windbg捕获到异常后会立即中断下来,按讲此时就可以直接分析了,为啥还要手动将异常信息导出到dump文件中呢?可能当时不能立即查出问题,亦或是出问题的电脑是其他同事的或者是客户的,不能长时间占用别人的电脑,这时需要导出到dump文件中,事后拿到dump文件后再进行详细的分析。

建议大家在代码中安装捕获软件异常的模块或代码,比如常用的是google开源的CrashRpt异常捕获库(很多软件比如QQ、钉钉在都使用类似的库),在软件发生崩溃时能实时捕获到异常信息,自动生成dump文件。然后测试人员将取到的dump文件发送给开发人员,开发人员使用Windbg打开dump文件进行分析:

4.5、Windows系统感知到程序发生了异常,自动生成dump文件

有时程序产生的异常崩溃很难复现,并且程序中安装的异常捕获模块并没有感知到、没有生成dump文件(异常捕获模块只能捕获大部分的异常崩溃,但不能不过所有的异常),因为问题很难复现,所以没法通过上述方法手动去获取包含异常上下文信息的dump文件。**此时可以尝试到系统的应用程序日志查看程序运行日志,看看操作系统有没有感知到软件发生异常,有没有帮我们自动生成包含异常上下文的dump文件。**比如项目中某次遇到的程序闪退,程序中安装的异常捕获模块没有感知到,但到系统的应用程序日志中找到系统帮我们自动生成的dump路径,如下所示:

以Win10系统为例,在桌面上右键点击"此电脑",在弹出的右键菜单中点击"管理"菜单项,如下所示:

打开计算机管理窗口后,在系统工具节点下,展开事件查看器节点,在该节点下继续展开Windows日志节点,然后点击应用程序节点,这样右边就显示应用程序相关的系统日志了:

于是按照程序出问题时的时间点,在应用程序日志列表中,找对应时间点的日志记录,可能就能找到了系统帮我们自动生成的dump文件路径了!在软件中安装的异常捕获模块,没法捕获所有场景下的异常,当程序发生闪退崩溃且异常捕获模块没有帮我们生成dump文件时, 可以尝试到系统日志中查看系统有没有自动生成dump文件!这种场景,大家平时估计很少用到,正好前段时间在项目中遇到过,已经整理成完整的案例文章,文章链接如下:

使用Windbg分析从系统应用程序日志中找到的系统自动生成的dump文件去排查问题https://blog.csdn.net/chenlycly/article/details/132024253

5、使用Windbg分析dump文件

Windbg是微软提供的Windows平台下强大的用户态和内核态调试利器,给我们分析Windows上软件的异常提供了极大的便利和有力的支持,比原始的直接查看代码去分析异常的效率要高的多。Windbg在某些方面甚至要比微软的Visual Studio还要强大。作为C++开发人员,必须要掌握常用的调试技巧,必须要能分析和排查软件运行过程中遇到的各种异常,必须要熟悉Windbg或GDB调试器的使用。

Windows平台上主要使用Windbg,Linux平台上主要使用GDB调试器。

Visual Studio可以分析dump文件,但分析dump文件最常用的工具还是Windbg,在分析与调试方面,Windbg要比Visual Studio强大很多。

5.1、Windbg版本与安装

常用的Windbg主要有三个版本:

1)Windbg 6.0免安装的老版本(绿色版本)

此版本比较老,要手动输入各种命令,有些命令很长很复杂,使用起来会很不方便,现在基本不用了。

2)从Windows SDK中摘出来的Windbg 10.0版本

到微软官网中从Windows SDK中获取10.0版本的安装包,然后安装就可以了。此版本比较常用,我日常工作中主要使用该版本。该版本中不再需要输入很多复杂的命令,点击超链接就可以查看想要查看的信息了。

3)从Windows应用商店下载的Windbg Preview版本

可以到Windows系统自带的应用商店,搜索Windbg,可以找到Windbg Preview版本进行安装。此版本是最新版本,UI界面进行了大改版,功能上和Windbg 10.0基本上是一样的。

关于如何下载安装Windbg10.0版本,以及如何使用Windbg,可以查看我的文章:

Windbg安装与使用详解https://blog.csdn.net/chenlycly/article/details/120631007

5.2、Windbg常用命令

使用Windbg分析dump文件,首先要掌握一些常用的Windbg命令 ,我们通过这些命令去操控Windbg去显示我们要看的信息,常用的Windbg命令有切换到异常上下文命令.ecxr、查看函数调用堆栈命令kn/kv/kp、自动分析命令!analyze -v、查看二进制模块信息命令lm、加载pdb符号文件命令.reload等。关于常用的Windbg命令以及更多的Windbg命令汇总,可以查看我的文章:

Windbg常用命令详解https://blog.csdn.net/chenlycly/article/details/125508027Windbg调试命令汇总https://blog.csdn.net/chenlycly/article/details/51711212

5.3、使用Windbg分析dump文件

使用Windbg分析dump文件时一般有几个常用的步骤,打开dump文件后:

**1)**使用.ecxr切换到发生异常的上下文,查看发生崩溃的那条汇编指令以及相关寄存器的值。

**2)**输入kn/kv/kp命令,查看异常发生时的函数调用堆栈,将堆栈与C++源码对照这看,尝试找出问题。

**3)**有时在dump文件中查看相关变量的值,可能是排查问题的关键线索或关键切入点。

**4)**有时甚至要查看发生异常的模块的汇编代码,去辅助定位问题。

关于Windbg静态分析dump文件的一般步骤及要点,我之前写了专门的文章, 可以直接去查看(此处就不再展开了):

使用Windbg分析dump文件的一般步骤及要点详解https://blog.csdn.net/chenlycly/article/details/130873143使用Windbg分析dmp文件的方法以及实战分析实例分享https://blog.csdn.net/chenlycly/article/details/152115653 对于C++程序发生崩溃,如果生成了dump文件,则使用Windbg静态分析dump文件;如果没有dump文件,则可以使用Windbg动态调试目标进程关于如何使用Windbg动态调试目标进程,可以查看我的文章:

使用Windbg调试目标进程的一般步骤及要点详解https://blog.csdn.net/chenlycly/article/details/131029795

6、最后

本文详细介绍了如何让C++程序生成dump文件、生成dump文件的多种方式以及如何使用Windbg分析dump文件,并给出了对应的实战分析案例,有一定的实战参考价值,希望能帮到大家。

相关推荐
小画家~2 小时前
第三十七:类型断言
开发语言·c++·算法·golang
Hard but lovely2 小时前
C++ 11--》初始化
开发语言·c++
昇腾CANN3 小时前
自定义算子开发系列:TilingKey模板化编程介绍
c++·mfc
oioihoii3 小时前
在MFC桌面应用中嵌入现代浏览器内核:原理、选型与实践全解析
c++·mfc
木心爱编程3 小时前
Qt C++ 串口通信+数据可视化:工业设备数据实时采集与界面显示
c++·qt·信息可视化
_OP_CHEN3 小时前
【从零开始的Qt开发指南】(九)Qt 常用控件之显示类控件(下):ProgressBar 与 CalendarWidget 实战进阶
开发语言·c++·qt·gui·前端开发·图形化界面开发·qt常用控件
兵哥工控3 小时前
MFC模拟量转工程量换应用程序实例
c++·mfc·工程量·模拟量
不会代码的小猴3 小时前
C++的第十三天笔记
c++·笔记·算法
OliverH-yishuihan3 小时前
Windows上VScode编译C++
c++·vscode