Windows Dump文件解析:从崩溃到定位

365足球打水封号还严重嘛 📅 2025-08-13 12:07:22 👤 admin 👁️ 7856 ❤️ 140
Windows Dump文件解析:从崩溃到定位

Windows Dump文件解析:从崩溃到定位

#Dump文件是Windows平台上分析程序崩溃的重要工具。本文将深入解析dump文件的内部结构,帮助你理解如何通过dump文件准确定位程序崩溃的原因。

大多数开发者应该都知道,Windows程序崩溃,可以自己调用API或者系统生成对应的dmp,我们拿到dmp后,可以用于调试定位问题,一般情况下都可以定位到具体是哪行代码出现的崩溃。拿到了dmp,为什么可以定位到具体哪里出现的崩溃呢?dmp具体都包含哪些信息呢?看下dmp的结构。先看header:

typedef struct _MINIDUMP_HEADER {

ULONG32 Signature;

ULONG32 Version;

ULONG32 NumberOfStreams;

RVA StreamDirectoryRva;

ULONG32 CheckSum;

union {

ULONG32 Reserved;

ULONG32 TimeDateStamp;

};

ULONG64 Flags;

} MINIDUMP_HEADER, *PMINIDUMP_HEADER;

header算是整个dmp的引导头,从header中可以看到dmp中包含很多stream,header中描述了每个stream在文件中的位置,我们可以去对应的offset处,读取对应的stream。dmp中包含了很多stream,每个stream存储对应的信息,具体信息在Win的官方文档上几乎都可以看到。https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ne-minidumpapiset-minidump_stream_type,这里有给出 dmp 中 stream 的类型:

typedef enum _MINIDUMP_STREAM_TYPE {

UnusedStream = 0,

ReservedStream0 = 1,

ReservedStream1 = 2,

ThreadListStream = 3,

ModuleListStream = 4,

MemoryListStream = 5,

ExceptionStream = 6,

SystemInfoStream = 7,

ThreadExListStream = 8,

Memory64ListStream = 9,

CommentStreamA = 10,

CommentStreamW = 11,

HandleDataStream = 12,

FunctionTableStream = 13,

UnloadedModuleListStream = 14,

MiscInfoStream = 15,

MemoryInfoListStream = 16,

ThreadInfoListStream = 17,

HandleOperationListStream = 18,

TokenStream = 19,

JavaScriptDataStream = 20,

SystemMemoryInfoStream = 21,

ProcessVmCountersStream = 22,

IptTraceStream = 23,

ThreadNamesStream = 24,

ceStreamNull = 0x8000,

ceStreamSystemInfo = 0x8001,

ceStreamException = 0x8002,

ceStreamModuleList = 0x8003,

ceStreamProcessList = 0x8004,

ceStreamThreadList = 0x8005,

ceStreamThreadContextList = 0x8006,

ceStreamThreadCallStackList = 0x8007,

ceStreamMemoryVirtualList = 0x8008,

ceStreamMemoryPhysicalList = 0x8009,

ceStreamBucketParameters = 0x800A,

ceStreamProcessModuleMap = 0x800B,

ceStreamDiagnosisList = 0x800C,

LastReservedStream = 0xffff

} MINIDUMP_STREAM_TYPE;

有些stream比较冷门,先不关注,这里只关注一些对我们来说非常有意义的stream:

ThreadListStreamModuleListStreamExceptionStreamSystemInfoStreamMiscInfoStream下面具体看下每个Stream中都包含哪些信息:

ThreadListStream

#typedef struct _MINIDUMP_THREAD {

ULONG32 ThreadId;

ULONG32 SuspendCount;

ULONG32 PriorityClass;

ULONG32 Priority;

ULONG64 Teb;

MINIDUMP_MEMORY_DESCRIPTOR Stack;

MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;

} MINIDUMP_THREAD, *PMINIDUMP_THREAD;

其中ThreadId和Priority以及Stack对我们排查问题都有帮助,我们可以知道崩溃时刻整个程序有多少个线程,比如崩溃时有10000个线程,那这程序不崩才怪。

ModuleListStream

#typedef struct _MINIDUMP_MODULE {

ULONG64 BaseOfImage;

ULONG32 SizeOfImage;

ULONG32 CheckSum;

ULONG32 TimeDateStamp;

RVA ModuleNameRva;

VS_FIXEDFILEINFO VersionInfo;

MINIDUMP_LOCATION_DESCRIPTOR CvRecord;

MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;

ULONG64 Reserved0;

ULONG64 Reserved1;

} MINIDUMP_MODULE, *PMINIDUMP_MODULE;

这个Stream很重要,它包含了崩溃进程加载过的所有PE模块的信息,信息包括PE文件的各种ID、以及版本号以及对应的符号表的信息。根据这个Stream,我们debug时,才能准确的匹配到加载的DLL所对应的pdb文件。

ExceptionStream

#typedef struct _MINIDUMP_EXCEPTION {

ULONG32 ExceptionCode;

ULONG32 ExceptionFlags;

ULONG64 ExceptionRecord;

ULONG64 ExceptionAddress;

ULONG32 NumberParameters;

ULONG32 __unusedAlignment;

ULONG64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];

} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION;

typedef struct _MINIDUMP_EXCEPTION_INFORMATION {

DWORD ThreadId;

PEXCEPTION_POINTERS ExceptionPointers;

BOOL ClientPointers;

} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;

这个stream就是崩溃线程的那个stream,它包含了崩溃线程的ID、以及崩溃的Code以及Address,解析工具根据这个address,再配合符号表,就可以解析出对应的调用栈,也就是知道崩溃时当前线程整个调用的链路,以及对应的代码位置,行号,函数名,一般情况下都可以获得。

SystemInfoStream

#typedef struct _MINIDUMP_SYSTEM_INFO {

USHORT ProcessorArchitecture;

USHORT ProcessorLevel;

USHORT ProcessorRevision;

union {

USHORT Reserved0;

struct {

UCHAR NumberOfProcessors;

UCHAR ProductType;

};

};

ULONG32 MajorVersion;

ULONG32 MinorVersion;

ULONG32 BuildNumber;

ULONG32 PlatformId;

RVA CSDVersionRva;

union {

ULONG32 Reserved1;

struct {

USHORT SuiteMask;

USHORT Reserved2;

};

};

CPU_INFORMATION Cpu;

} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO;

这个stream会标识崩溃进程所在的系统环境,最主要的就是系统版本号和cpu信息了。

MiscInfoStream

#typedef struct _MINIDUMP_MISC_INFO {

ULONG32 SizeOfInfo;

ULONG32 Flags1;

ULONG32 ProcessId;

ULONG32 ProcessCreateTime;

ULONG32 ProcessUserTime;

ULONG32 ProcessKernelTime;

} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO;

包括进程ID、进程创建时间等等。在dmp的header中其实有个时间戳,我们可以理解为是创建dmp的时间,有了dmp创建时间,又有进程创建时间,我们还可以计算出程序的运行时间。

typedef struct _MINIDUMP_HEADER {

ULONG32 Signature;

ULONG32 Version;

ULONG32 NumberOfStreams;

RVA StreamDirectoryRva;

ULONG32 CheckSum;

union {

ULONG32 Reserved;

ULONG32 TimeDateStamp;

};

ULONG64 Flags;

} MINIDUMP_HEADER, *PMINIDUMP_HEADER;

更多内容可以查看Windows官方文档:https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/其实官网介绍的还不够全面,dmp里还有很多有用的信息,比如MemoryInfoStream,这里面有很多内存以及磁盘相关的信息,方便我们了解崩溃时刻的内存情况。

参考资料

#minidump的格式PDB文件匹配调试信息系列文章PDB格式文档MSF格式说明Microsoft PDB仓库Stack Walking文档Stack Trace实现比较

相关推荐

办公室电脑看图软件有哪些
game365备用网址

办公室电脑看图软件有哪些

📅 07-16 👁️ 5948
最壮阳强肾的3种运动
365050

最壮阳强肾的3种运动

📅 07-29 👁️ 2183
电脑32位的浏览器有哪些软件好用
game365备用网址

电脑32位的浏览器有哪些软件好用

📅 07-15 👁️ 8228