多線程場景下的dump分析過程

示例代碼

多線程場景異常示例代碼:

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

#include <Windows.h>
#include <tchar.h>

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認爲異常點位於主線程中46行代碼,其錯誤代碼段如下:
在這裏插入圖片描述
很顯然,windbg給出的結論並不準確,因此需要進一步確認異常點。

2、執行~* kbn命令

執行~* kbn命令顯示所有線程的調用棧信息,發現線程1存在未處理的異常點,截圖如下:
在這裏插入圖片描述
內存地址爲007af7f0有異常行爲

3、 dd命令分析

使用dd命令獲取異常記錄點地址和上下文地址:

  • 007af8f0 異常記錄點地址
  • 007af90c 上下文地址
    在這裏插入圖片描述

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自動分析並不能直接定位出程序崩潰點。此時就需要依賴切換實際的運行上下文才能分析出真正根因。

希望這篇文章能夠給大家帶來實際的幫助,本文參考以下兩篇文章:

https://www.cnblogs.com/gaochundong/p/windbg_cheat_sheet.html#thread_info_cmds

https://zhuanlan.zhihu.com/p/43972006

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章