Windows下定位Mingw編譯的Qt程序崩潰堆棧

一、dump和pdb是什么

????????在Windows系統下,當我們寫的程序跑在客戶的機器上,因為一個bug,導致程序崩潰,我們該如何定位并修復這個bug呢?

????????有人會說記錄日志,即便有日志,也是不好定位的,因為你只能推測出大概的模塊或者位置,無法定位到具體出錯的代碼行。

????????此時,我們可以讓程序崩潰后,自動生成一個*.dmp文件,并配合在編譯該程序時生成的pdb文件,來準確定位到調用堆棧、代碼行上。這樣很輕易就可以找到該bug。

  • dump文件,后綴*.dmp,是程序崩潰時的內存轉儲文件;

  • pdb文件,后綴*.pdb,是程序的符號文件。

二、Breakpad與qbreakpad簡介

????????Breakpad是由Google開發的開源跨平臺崩潰報告系統,用于捕獲程序崩潰時的內存狀態并生成輕量級minidump文件(.dmp)。其核心功能包括崩潰攔截、堆棧記錄和寄存器狀態捕獲,適用于C++應用的多平臺部署(Windows/Linux/macOS)?。

????????QBreakpad是Breakpad的?Qt專用封裝庫?,它將Breakpad的復雜集成簡化為Qt模塊,提供更便捷的API和跨平臺兼容性,專門服務于Qt應用程序的崩潰管理?。

????????BreakPad工作原理示意圖:

表達的意思就是:

  • 我們在編譯的時候,需要在Release版程序中生成調試信息。

  • 使用Breakpad提供的dump_syms工具或者cv2pdb工具,從release版本程序導出符號文件。

  • 當程序崩潰時,breakpad會捕捉崩潰,并生成dump文件。

  • dump文件可以直接發送到指定服務器,或者由用戶手動發給開發者。

  • 收到dump文件后,結合符號文件,可通過minidump_stackwalk工具或Visual Studio工具生成堆棧調用信息文件,這個文件可以直接閱讀,定位bug。

三、開發環境說明

? ? ? ? 本人使用的開發環境如下:

? ? ? ? 操作系統:Windows10

? ? ? ? IDE:Qt Creator4.4.1

? ? ? ? 編譯器:mingw53_32

? ? ? ? Qt庫:Qt5.9.3?

四、源碼準備

????????我們知道qBreakpad是對Breakpad的封裝,所以qBreakpad的編譯,還依賴2套源碼Breakpad、LSS。

(1)下載Breakpad源碼

下載地址:https://github.com/google/breakpad

(2)下載LSS源碼

下載地址:https://github.com/ithaibo/linux-syscall-support

(3)下載qBreakpad源碼

下載地址:https://github.com/buzzySmile/qBreakpad

?(4)下載cv2pdb工具

下載地址:

注意:這個工具最好下載最新版本的,作者發布本文時,最新版本是cv2pdb 0.53

五、編譯qBreakpad

(1)將Breakpad、LSS源碼放入third_party目錄

????????解壓qBreakpad源碼后,在qBreakpad-master\third_party目錄下,有如下2個目錄,如下:

????????分別解壓Breakpad、LSS源碼至breakpad和lss目錄,此2個目錄下源碼需要參與qBreakpad的編譯。放置好后,如下所示:

(2)qBreakpad工程介紹

????????在qBreakpad源碼目錄下,使用QtCreator打開qBreakpad.pro工程,如下:

  • demo工程下,有2個演示程序program和reporter,分別實現了演示生成dump文件,上報dump文件的功能。

  • handler為靜態庫工程,該工程封裝了Breakpad,直接編譯此工程,可生成qBreakpad.lib。

  • tests為一個簡單的測試工程。

(3)編譯生成qBreakpad.lib

????????分別在Debug、Release模式下,編譯handler工程,生成2個版本的qBreakpad.lib靜態庫。

因為程序調用qBreakpad.lib時,只能debug版程序鏈接debug版庫,release版程序鏈接release版庫。debug版程序鏈接release版庫會報錯。

(4)編譯生成demo

? ? ? 在program.pro文件添加下圖所示內容,目的是編譯release版程序時生成調試信息:

############ for qBreakpad ############
# qBreakpad中需要使用到network模塊
QT += network# 啟用多線程、異常、RTTI、STL支持
CONFIG += thread exceptions rtti stl# without c++11 & AppKit library compiler can't solve address for symbols
CONFIG += c++11
macx: LIBS += -framework AppKit# 啟用調試信息(關鍵!)
QMAKE_CXXFLAGS += -g
QMAKE_CXXFLAGS_RELEASE += -g
QMAKE_CFLAGS_RELEASE += -g
#release在最后link時默認有"-s”參數,表示"Omit all symbol information from the output file",因此要去掉該參數
QMAKE_LFLAGS_RELEASE = -mthreads -Wl,# 配置頭文件搜索路徑和鏈接庫路徑
INCLUDEPATH += $$PWD/qBreakpad/include
CONFIG(debug, debug|release) {
LIBS += -L$$PWD/qBreakpad/lib/debug -lqBreakpad
} else {
LIBS += -L$$PWD/qBreakpad/lib/release -lqBreakpad
}
############ for qBreakpad ############

?

? ? ? 在main函數添加以下內容,啟用崩潰時生成.dmp文件的功能:

六、生成.pdb文件

? ? ? ? 將program這個demo程序編譯出release版本:

? ? ? ? 可見這個demo程序編譯出來后體積是比較大的:

????????然后將前面下載的cv2pdb工具解壓放到目標程序同一個目錄:

? ? ? ? 在這個目錄打開終端,執行命令生成.pdb文件:

cv2pdb.exe? ?目標程序.exe

? ? ? ? 執行成功后,會在目標程序的同級目錄下生成.pdb文件,同時也可以看到目標程序的體積變小了:

七、通過.dmp文件追蹤程序崩潰的堆棧信息

? ? ? ? 運行前面生成的test.exe文件,程序崩潰后會生成.dmp文件:

????????使用Visual Studio打開.dmp文件,這里以Visual Studio2022為例:

????????點擊上圖中的“設置符號路徑”,將.pdb文件所在路徑添加進去:

????????擊下圖中的“使用僅限本機進行調試”:

????????如下圖所示,可以看到程序崩潰時的堆棧調用情況:

????????雙擊堆棧調用的行內容,將源碼文件路徑設置一下,便可查看源碼及變量的實時值。

八、總結

? ? ? ? 在Windows系統下,使用Mingw編譯器編譯出來的程序,重點和難點是如何生成.pdb文件。而生成.pdb文件的重點有兩方面,一是在.pro文件添加-g編譯參數,二是使用cv2pdb工具的最新版本,舊版本的cv2pdb工具可能無法生成.pdb文件(這一點困擾了我好久)。

? ? ? ? 如果應用程序調用了很多自己開發的動態庫,那么動態庫的.pro文件也需要添加-g編譯參數,并且動態庫也需要用cv2pdb工具生成.pdb文件。

? ? ? ? 最后,為了方便提取多個文件的.pdb文件,本人寫了2個批處理腳本,一個用于提取.exe文件,另一個用于提取.dll文件,我將腳本給出,供大家參考:

? ? ? ? 批量提取D:\package\bin目錄下所有exe文件的pdb:

@echo off
echo Hello,I am processing pdb files...set OBJECT_HOME=D:\packageset CV2PDB_HOME=%~dp0
CHDIR /D  %OBJECT_HOME%set COMPILE_BIN=%OBJECT_HOME%\binecho "step1: del *.pdb..."
del *.pdbecho "step2: create *.pdb..."set FILE_TYPE_EXE=*.exe
for /r "%COMPILE_BIN%" %%i in (%FILE_TYPE_EXE%)do ( if exist %%i %CV2PDB_HOME%/cv2pdb.exe "%%i" )

? ? ? ? 批量提取D:\package\lib目錄下所有dll文件的pdb:

@echo off
echo Hello,I am processing pdb files...set OBJECT_HOME=D:\packageset CV2PDB_HOME=%~dp0
CHDIR /D  %OBJECT_HOME%set COMPILE_LIB=%OBJECT_HOME%\libecho "step1: del *.pdb..."
del *.pdbecho "step2: create *.pdb..."set FILE_TYPE_EXE=*.dll
for /r "%COMPILE_LIB%" %%i in (%FILE_TYPE_EXE%)do ( if exist %%i %CV2PDB_HOME%/cv2pdb.exe "%%i" )

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917530.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917530.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917530.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

.net依賴注入框架 Autofac和MEF的對比

Autofac 默認需要顯式注冊每個類型,這是它與MEF在模塊化設計上的主要區別。以下是具體對比說明:1. Autofac 的基本注冊方式 Autofac 必須通過代碼明確注冊每個需要注入的類型(除非使用特殊掃描機制): var builder new…

Python 使用 asyncio 包處理并 發(使用asyncio包編寫服務器)

使用asyncio包編寫服務器 演示 TCP 服務器時通常使用回顯服務器。我們要構建更好玩一點的示 例服務器,用于查找 Unicode 字符,分別使用簡單的 TCP 協議和 HTTP 協議實現。這兩個服務器的作用是,讓客戶端使用 4.8 節討論過的 unicodedata 模塊…

Node.js (Express) + MySQL + Redis構建項目流程

以下是使用 Node.js (Express) MySQL Redis 構建完整項目的詳細流程,涵蓋環境搭建、架構設計、核心代碼實現和部署優化:一、項目初始化 1. 創建項目目錄 mkdir my-project cd my-project npm init -y2. 安裝基礎依賴 npm install express mysql2 redis…

Python3 中使用zipfile進行文件(夾)的壓縮、解壓縮

一、文件壓縮與解壓縮模塊 zipfile簡介 zipfile 是 Python 標準庫中用于處理 ZIP 壓縮文件的模塊,提供了創建、讀取、寫入、解壓 ZIP 文件的完整功能。它支持多種壓縮算法,無需安裝額外依賴,是處理 ZIP 格式的首選工具。 核心功能與常用類 zi…

在Java客戶端使用Redis

目錄 第一步:開放Redis外部連接配置 第二步:配置端口轉發 第三步:在IDEA中導入依賴 第四步:編寫代碼命令 連接環境:Java客戶端為本地IDEA,Redis服務器安裝在云服務器Ubuntu系統中。 第一步:開…

【MySQL】MySQL索引—B樹/B+樹

目錄 1. 數據庫索引 1.1 索引的概念 1.2 索引的特點 1.3 索引查詢對比普通的查詢 1.4 索引的操作 1.5 索引的原理 1.6 B樹 1.7 B樹 1.8 B樹的優點 1. 數據庫索引 1.1 索引的概念 數據庫的索引是一種特殊的數據結構,里面包含著數據表中所有記錄的引用&…

jQuery Mobile 面板詳解

jQuery Mobile 面板詳解 引言 隨著移動設備的普及,移動網頁開發變得越來越重要。jQuery Mobile 是一個基于 jQuery 的移動網頁開發框架,它提供了一套豐富的 UI 組件和主題,使得開發者可以快速構建出美觀、響應式的移動網頁。在 jQuery Mobile 中,面板(Panel)是一個非常…

Python中的import和from...import有什么區別?

文章目錄 前言 一、import導入模塊 導入模塊并給它一個別名 語法格式 二、from...import導入特定項 1.導入模塊中的特定項 2.導入模塊中的所有項 2.1 命名空間核污染 2.2 性能影響 總結 前言 在Python編程中,模塊和包的導入機制是編寫可維護、可擴展代碼的核心。深入理解Pyth…

vscode提示“無法使用 compilerPath 解析配置”解決辦法

0 問題描述 使用vscode的Remote-SSH插件連接安裝在虛擬機上的Windows10進行遠程開發時,出現如下提示:無法使用 compilerPath 解析配置:“D:\mingw64\bin\gcc.exe” 所有包含C庫頭文件的文件都被標紅提示錯誤:1 問題原因 vscode沒有設置正確的…

信噪比(Signal-to-Noise Ratio, SNR)詳細介紹

信噪比(Signal-to-Noise Ratio, SNR)信噪比(Signal-to-Noise Ratio,SNR)是衡量信號質量的重要參數,表示有用信號的功率與背景噪聲功率的比值。SNR在通信、音頻處理、視頻處理以及其他電子信號處理領域中具有…

Nginx 相關實驗(1)

nginx源碼編譯 本實驗采用nginx源碼編譯的安裝方式,需要準備一個tar包,可從nginx官網上下載。 下載地址:nginx: downloadhttps://nginx.org/en/download.html 將下載好的壓縮包傳到虛擬機中的自定義目錄下 [rootwebserver ~]# ls anacond…

【選型】HK32L088 與 STM32F0/L0 系列 MCU 參數對比與選型建議(ST 原廠 vs 國產芯片)(單片機選型主要考慮的參數與因素)

國產 vs ST 單片機在工業控制中的性能對比分析 HK32L088 與 STM32F0/L0 系列 MCU 參數對比與選型建議 工業控制領域 MCU 選型:國產航順 HK32 與 ST 原廠芯片深入比較 國產 MCU 是否可替代 ST?基于發電機控制應用的深入評估 從數據手冊看 MCU 制造工藝差異:HK32L088 vs S…

LLM Prompt與開源模型資源(1)提示詞工程介紹

學習材料:https://www.hiascend.com/developer/courses/detail/1935520434893606913學習時長: 預計 30 分鐘學習目的: 了解提示工程的定義與作用 熟悉提示工程的關鍵技術相關概念 掌握基于昇騰適配的大模型提示工程的入門及進階指南 提示…

kafka與其他消息隊列(如 RabbitMQ, ActiveMQ)相比,有什么優缺點?

Kafka、RabbitMQ 和 ActiveMQ 是三種最主流的消息中間件,它們的設計和適用場景有所不同。 我們可以通過一個簡單的表格來快速了解它們的核心區別: 核心對比一覽特性 / 維度KafkaRabbitMQActiveMQ核心模型分布式、持久化的日志系統 (Dumb Broker / Smart …

Kubernetes架構和部署

k8s組件 master節點:管理節點 管理平面組件 api server : api gateway controller manager scheduler etcd 數據庫 worker節點:被管理節點,運行容器 kubelet:k8s agent container runtime:docker,containerd,cri-o kube-proxy:service 網絡 ????????…

建造者模式及優化

建造者模式是一種創建型設計模式,它將復雜對象的構建過程與表示分離,使得同樣的構建過程可以創建不同的表示。核心思想是指揮者定流程,建造者填細節,通過多個步驟逐步構建對象,并允許靈活組合這些步驟以生成不同配置的…

【09】C++實戰篇——C++ 生成靜態庫.lib 及 C++調用lib,及實際項目中的使用技巧

文章目錄1 C 靜態庫.lib 生成1.1 靜態庫lib的生成方法和使用方法1.2 創建靜態庫項目1.3 編寫.h 和 .cpp文件1.4 設置 及 生成 DLL2 調用 C 靜態庫lib2.1 新建LIBtest及測試代碼2.2 靜態庫配置 及代碼調用測試3 實際項目中的使用技巧、及通用設置3.1 設置lib輸出路徑3.2 設置頭文…

飛算JavaAI:從寫不出代碼到絲滑開發,飛算JavaAI把小白從編程深淵撈進了正軌---它都讓我懷疑自己是不是多余的!

開篇介紹 對于很多初學者來說,編程是一項既有趣又充滿挑戰的任務。面對復雜的代碼和繁瑣的開發流程,常常會感到無從下手。不過,現在有了飛算JavaAI,這一切都將變得簡單起來。 它有啥實用功能呢? 比如: …

關于tresos Studio(EB)的MCAL配置之GtmCfg

Generic Time Module通用時鐘模塊GeneralGtmCfg_DevErrorDetect開發者錯誤檢測開關GtmCfg_DemErrorReporting診斷錯誤報告開關GtmCfg_VersionInfoApi獲取版本信息的接口開關GtmCfg_ConfigSetClockManagementUnitGlobal_Clock_Control_Numerator全局時鐘分頻器的分子Global_Cloc…

深入探索Weaviate:構建高效AI應用的數據庫解決方案

在當今數據驅動的世界中,高效地存儲、檢索和處理大規模數據成為了AI應用開發的關鍵挑戰。Weaviate作為一個開源的向量搜索引擎,憑借其強大的功能和靈活的架構,正逐漸成為開發者構建智能AI應用的首選工具。本文將深入探討Weaviate的核心概念、…