windbg分析dump操作流程

https://blog.csdn.net/u010275850/article/details/73435545

1、加载pdb:
.reload /i /f

2、查看pdb是否加载成功:
lm

3、自动分析指令(通常分析出的是主线程的堆栈)
!analyze -v

此时通过分析出的堆栈去找有无kernel32!UnhandledExceptionFilter信息
如果有,则此堆栈(主线程堆栈)为异常堆栈;
如果没有,则需查看所有线程堆栈:


4、查看所有线程堆栈:
~*kb

同理去找有无kernel32!UnhandledExceptionFilter信息堆栈

如果有,则此堆栈为异常堆栈;


图示异常出现在3号线程中

注:如果查看到的堆栈都是显示如下的信息:


则表明需要将windbg切换到32位模式,才能分析,指令如下:

    .load wow64exts
    !sw

5、找到异常堆栈分析,切换到异常堆栈的线程ID;
   查看该线程(3号线程)的堆栈:
eg:
0:000> ~3s


6、dd [Args to Child的第一个参数(该例子中是0329e7b0)] (指令是d, 第二个d表示是DWORD:双字,表示4字节数据格式)
   第一个参数指向了_EXCEPTION_POINTERS结构体

注:_EXCEPTION_POINTERS的定义如下:

    typedef struct _EXCEPTION_POINTERS {
        PEXCEPTION_RECORD ExceptionRecord;
        PCONTEXT ContextRecord;
    } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

 

eg:
0:003> dd 0329e7b0
00000000`0329e7b0  0329f3f0 00000000 0329ef00 00000000
00000000`0329e7c0  76f60000 00000000 0329f3f0 00000000
00000000`0329e7d0  00000000 00000000 76f8c541 00000000
00000000`0329e7e0  0329a000 00000000 76f89d2d 00000000
00000000`0329e7f0  032a0000 00000000 0329f830 00000000
00000000`0329e800  0329f830 00000000 770a2dd0 00000000
00000000`0329e810  0329e8b0 00000000 76f791cf 00000000
00000000`0329e820  032a0000 00000000 76f4dda0 00000000


7、.cxr [dd结果的第二个参数,此例中为0329ef00]  -重建堆栈(查看结构体中的PCONTEXT成员)


可以看到他的错误堆栈信息和windows捕捉到的是一致的


8、.exr [dd结果的第一个参数,此例中为0329f3f0] (查看结构体中的 PEXCEPTION_RECORD成员)

 

 

9、kv 查看程序崩溃前调用的最后堆栈信息 【需执行完上述8步后】

 

如果在上述第四步后仍未发现没有任何异常错误堆栈信息,此时有可能是线程之间死锁了
可通过以下指令查看
5、!locks 【需加载相应的windows pdb文件】


6、然后通过死锁的线程id:7d8去 ~*kb里面寻找该线程的堆栈


除了上述的UnhandledExceptionFilter异常和死锁的现象,还有一种_except_handler异常的情况,其处理流程和UnhandledExceptionFilter类似,具体如下:

_except_handler函数的情况


1.有些情况下堆栈中没有UnhandledExceptionFilter,而只有_except_handler函数,这个是SEH异常处理函数。函数原型:EXCEPTION_DISPOSITION __cdecl _except_handler(
                         struct _EXCEPTION_RECORD *ExceptionRecord,
                         void * EstablisherFrame,
                         struct _CONTEXT *ContextRecord,
                         void * DispatcherContext);
这个函数的第一个参数是一个指向 EXCEPTION_RECORD 结构的指针。这个结构在WINNT.H中定义,如下所示:
typedef struct _EXCEPTION_RECORD {
   DWORD ExceptionCode;
   DWORD ExceptionFlags;
   struct _EXCEPTION_RECORD *ExceptionRecord;
   PVOID ExceptionAddress;
   DWORD NumberParameters;
   DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
_except_handler 函数的第二个参数是一个指向establisher帧结构的指针。
_except_handler 回调函数的第三个参数是一个指向 CONTEXT 结构的指针。
typedef struct _CONTEXT
{
    DWORD ContextFlags;
    DWORD Dr0;
    DWORD Dr1;
    DWORD Dr2;
    DWORD Dr3;
    DWORD Dr6;
    DWORD Dr7;
    FLOATING_SAVE_AREA FloatSave;
    DWORD SegGs;
    DWORD SegFs;
    DWORD SegEs;
    DWORD SegDs;
    DWORD Edi;
    DWORD Esi;
    DWORD Ebx;
    DWORD Edx;
    DWORD Ecx;
    DWORD Eax;
    DWORD Ebp;
    DWORD Eip;
    DWORD SegCs;
    DWORD EFlags;
    DWORD Esp;
    DWORD SegSs;
} CONTEXT;
_except_handler 回调函数的第四个参数被称为DispatcherContext。


2.分析dump文件时,在命令提示符处键入 ~*kb 要列出所有进程中线程。


3.标识进行函数调用的线程 Kernel32!_except_handler。 它看起来类似于以下内容:
   9  Id: 918.117c Suspend: 2 Teb: 7ffd8000 Unfrozen
ChildEBP RetAddr  Args to Child            
085df400 7c9232a8 085df4ec 085dffdc 085df50c kernel32!_except_handler3+0x61
085df424 7c92327a 085df4ec 085dffdc 085df50c ntdll!ExecuteHandler2+0x26
085df4d4 7c92e48a 00000000 085df50c 085df4ec ntdll!ExecuteHandler+0x24

4.切换到该线程 (在此示例中,线程是"~ 9s")。

5.Kernel32! !_except_handler第一个参数 dword 值表示异常记录。 若要获取有关异常的类型的信息,请在命令提示符处运行以下:
 .exr first DWORD from step 5
0:009> .exr 085df4ec
ExceptionAddress: 7c812afb (kernel32!RaiseException+0x00000053)  
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 3  
Parameter[0]: 19930520  
Parameter[1]: 085df874  
Parameter[2]: 006c010c

6.Kernel32! !_except_handler第三个参数 dword 值是上下文记录。 要获取的上下文信息,请在命令提示符处运行以下:
.cxr second DWORD from step 6
0:009> .cxr 085df50c
eax=085df7dc ebx=00005d34 ecx=00000000 edx=01240608 esi=085df864 edi=00100000eip=7c812afb esp=085df7d8 ebp=085df82c iopl=0         nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206kernel32!RaiseException+0x53:7c812afb 5e              pop     esi

 7.运行 kv 命令以获得实际的异常的调用堆栈。 这可以帮助您识别可能不具有被正确处理过程中的实际问题
0:009> kv
ChildEBP RetAddr  Args to Child          
WARNING: Stack unwind information not available. Following frames may be wrong.
09a8fa2c 780119ab 09a8fad4 00000000 09a8faa8 MSVCRT!strnicmp+0x92
09a8fa40 7801197c 09a8fad4 00000000 6d7044fd MSVCRT!stricmp+0x3c
09a8fa80 6e5a6ef6 09a8fad4 2193d68d 00e5e298 MSVCRT!stricmp+0xd


参考博文:

WinDbg 查找问题异常堆栈,堆栈跟踪UnhandledExceptionFilter
17.windbg-!cs、~~[TID](经典死锁)

注:切换当前的线程:
~0s  切换到0号线程
~3s  切换到3号线程
---------------------
作者:fzzjoy
来源:CSDN
原文:https://blog.csdn.net/u010275850/article/details/73435545
版权声明:本文为博主原创文章,转载请附上博文链接!

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windbg是Windows平台上的一款强大的调试工具,可以用于分析dump文件。当一个程序崩溃或异常退出时,系统会生成一个dump文件,其中包含了程序在崩溃前的内存状态、寄存器的值以及调用栈等信息。通过分析dump文件,可以帮助我们确定程序崩溃的原因。 使用Windbg分析dump文件的步骤如下: 首先,打开Windbg并选择“File”菜单中的“Open Crash Dump”,然后选择要分析dump文件。打开dump文件后,Windbg会加载其中的调试信息,包括程序、模块、符号等。 在Windbg的命令窗口中,可以输入一系列的命令来分析dump文件。其中一些常用的命令如下: 1. "!analyze -v":分析dump文件并提供详细的分析报告,报告中包含了崩溃的原因和相关的线程堆栈信息。 2. "kb":显示当前线程的调用栈,可以根据调用栈信息来查找崩溃的位置。 3. "lm":显示加载的模块信息,可以查看程序中加载的模块和其对应的版本号。 4. ".exr -1":显示当前异常的记录,包括异常的类型和相关的寄存器的值。 5. ".reload /f":强制重新加载符号文件,以确保符号信息的准确性。 通过分析命令的执行结果,我们可以逐步追踪问题并找到程序崩溃的原因。在分析过程中,还可以使用其他的命令来查看内存的内容、寄存器的值以及线程的信息等。 总的来说,Windbg是一款功能强大的调试工具,通过分析dump文件可以帮助我们深入了解程序崩溃的原因,从而进行相应的调试和修复。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值