windbg入门教程之复杂场景下crash分析

在前一篇文章中,我们介绍了单线程场景下crash分析步骤和基本思路。但在实际项目中,往往是多线程或者更复杂的情况,此时通过!analyze -v命令难以直接找到出问题的点。

以下代码演示了多线程场景下的crash分析过程,需要特别注意的是,我们的工程需要禁用优化,否则分析问题不直观。如下所示:
在这里插入图片描述

示例代码

多线程场景异常示例代码:

#include "utilityAPI.h"
#include <string>

#pragma comment(lib, "utility.lib")

typedef struct  
{
    char szName[128];
    char szAddr[128];
    unsigned usAge;
}STRU_STUDENT_INFO;

//执行函数参数
void GetStudentInfo(char* name, STRU_STUDENT_INFO *pStudent, int count)
{
    printf("student age=%d",pStudent->usAge);
}

//子线程类,其中TTThread为自己封装的线程类
class CMultiThread :public TTThread
{
    virtual unsigned int Process();
};

//子线程函数实现
unsigned int CMultiThread::Process()
{
    STRU_STUDENT_INFO *pStudent = NULL;

    GetStudentInfo("jimmy",pStudent,5);

    return 0;
}

int main(int argc, char const *argv[])
{
    //子线程
    CMultiThread test;
    test.Create();

    //主线程
    for (int i = 0; i < 1000; i++)
    {
        Sleep(100);
    }

    return 0;
}

dump分析过程

1、执行 !analyze -v命令

!analyze -v命令会进程大量的内部分析,并给出当前异常的详细信息记录
在这里插入图片描述
在此次自动分析结论中,windbg认为异常点位于主线程中45行代码,其错误代码段如下:
在这里插入图片描述
很显然,windbg给出的结论并不准确,因此需要进一步确认异常点。

在这个分析报告中我们也没有找到异常上下文地址以及正确的异常记录地址,而这两个信息又是比较重要的。
在这里插入图片描述
2、执行~* kbn命令

在之前文章中说过,当软件异常发生时,如果异常没有被捕获,异常信息会经过UnhandledExceptionFilter函数,然后再通知用户。

为了找出该函数,执行~* kbn命令显示出所有线程的调用栈信息,发现线程1存在未处理的异常点,截图如下:
在这里插入图片描述
地址00b8f980为UnhandledExceptionFilter入参,该地址为_EXCEPTION_POINTERS结构体指针。

3、 dd命令分析

该命令给出了EXCEPTION_POINTERS structure结构体信息,第1个为异常记录点地址和第二个为上下文地址:

0:000> dd 00b8f980 L2
00b8f980  00b8fa80 00b8fa9c
  • 00b8fa80 异常记录点地址
  • 00b8fa9c上下文地址

4、执行 .exr 和.cxr命令

  • .exr (Display Exception Record)
  • .cxr (Display Context Record)

执行完.exr 和.cxr命令,windbg会调出执行异常的源码,windbg将光标定位于printf语句.此时可以认为是空指针造成的。下面进行进一步确认。
在这里插入图片描述
5、kP命令

此时我们可以k命令显示堆栈信息,这里使用kP命令会显示所有参数信息,kP命令显示了函数调用栈以及函数入参值,如下图:
在这里插入图片描述
通过kP命令可以发现,GetStudentInfo函数入参中的pStudent为空指针,结合执行完.cxr 007af90c命令后,光标指向printf("student age=%d",pStudent->usAge);语句。

因此可以得出结论:函数崩溃原因是因为访问空指针对象导致的

总结

在实际项目中,一个应用程序中必然存在多线程的场景,通过windbg自动分析并不能直接定位出程序崩溃点。此时就需要依赖切换实际的出问题的运行上下文才能分析出真正根因。需要注意的是,我们的功能需要禁用优化编译选项,对于启用代码优化的crash分析,大家依照这篇文章自行分析,以便加深印象。

希望这篇文章能够给大家带来实际的帮助,本文参考以下文章:

https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/bug-check-0x1e–kmode-exception-not-handled

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值