【Qt】為程序增加閃退crash報告日志

背景

隨著軟件代碼量的增加,軟件崩潰閃退的肯能行越來越大,其中一些是難以復現的,比如訪問了訪問了非法地址、被操作系統殺死等。

為此,在軟件出現閃退情況時,盡可能多的記錄閃退發生時信息,對排查閃退原因是非常有幫助的。

實現

因為閃退發生時軟件已經不在運行了,因此需要在閃退前就告訴操作系統閃退后需要執行的操作,在Qt中就是在QApplicationexec()前調用操作系統提供的接口,注冊閃退后的處理函數。

我們以Windows平臺為例,在Windows平臺,時利用SetUnhandledExceptionFilter函數實現異常(閃退)處理函數的注冊的。

簡單代碼如下:

#include <QApplication>#ifdef Q_OS_WIN
#include <windows.h>
#include <psapi.h>
#include <DbgHelp.h>
#include <fstream>
#include <sstream>#pragma comment(lib, "DbgHelp.lib")
LONG WINAPI windowsCrashHandler(EXCEPTION_POINTERS* ex) {SYSTEMTIME time;GetLocalTime(&time);char logName[256];// 文件名格式crash_yyyymmdd_hhmmss.logsprintf(logName, "crash_%04d%02d%02d_%02d%02d%02d.log",time.wYear, time.wMonth, time.wDay,time.wHour, time.wMinute, time.wSecond);// 打開日志文件std::ofstream logFile(logName);if (!logFile.is_open()) return EXCEPTION_EXECUTE_HANDLER;// 記錄異常信息logFile << "=== Exception: "<< ex->ExceptionRecord->ExceptionCode<<" ==="<< std::endl;// 記錄內存占用(Windows)MEMORYSTATUSEX statex;statex.dwLength = sizeof(statex);if (GlobalMemoryStatusEx(&statex)) {logFile << "總內存:" << statex.ullTotalPhys / (1024 * 1024) << " MB" << std::endl;}PROCESS_MEMORY_COUNTERS pmc;GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));logFile << "內存占用: "<< pmc.WorkingSetSize / (1024 * 1024)<< " MB" << std::endl;logFile << "Error Code: 0x" << std::hex << ex->ExceptionRecord->ExceptionCode << std::endl;// 獲取調用堆棧HANDLE process = GetCurrentProcess();HANDLE thread = GetCurrentThread();SymInitialize(process, NULL, TRUE);  // 初始化符號表// 遍歷堆棧幀STACKFRAME64 stackFrame = {{0}};stackFrame.AddrPC.Offset = ex->ContextRecord->Rip;  // x86 用 Eip, x64 用 RipstackFrame.AddrPC.Mode = AddrModeFlat;stackFrame.AddrStack.Offset = ex->ContextRecord->Rsp;  // x86 用 Esp, x64 用 RspstackFrame.AddrStack.Mode = AddrModeFlat;stackFrame.AddrFrame.Offset = ex->ContextRecord->Rbp;  // x86 用 Ebp, x64 用 RbpstackFrame.AddrFrame.Mode = AddrModeFlat;DWORD imageType;
#ifdef _M_IX86imageType = IMAGE_FILE_MACHINE_I386;
#elif _M_X64imageType = IMAGE_FILE_MACHINE_AMD64;
#endiflogFile << "調用堆棧:" << std::endl;int frameNum = 0;while (StackWalk64(imageType, process, thread, &stackFrame, ex->ContextRecord,NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) {// 獲取符號信息BYTE symbolBuffer[sizeof(SYMBOL_INFO) + 256] = {0};SYMBOL_INFO* symbol = (SYMBOL_INFO*)symbolBuffer;symbol->SizeOfStruct = sizeof(SYMBOL_INFO);symbol->MaxNameLen = 255;DWORD64 displacement = 0;if (SymFromAddr(process, stackFrame.AddrPC.Offset, &displacement, symbol)) {logFile << "[" << frameNum << "] " << symbol->Name << std::endl;} else {logFile << "[" << frameNum << "] Unknown Address" << std::endl;}frameNum++;}// 清理符號表SymCleanup(process);logFile.close();// 退出程序return EXCEPTION_EXECUTE_HANDLER;
}
#endifint main(int argc, char *argv[])
{#ifdef Q_OS_WIN// Windows 注冊異常(閃退)處理函數SetUnhandledExceptionFilter(windowsCrashHandler);
#endifQApplication a(argc, argv);return a.exec();
}

這樣在程序出現閃退后,就可以看到閃退時計算機內存的占用情況以及引起閃退的調用堆棧。

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

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

相關文章

C#從入門到精通(35)—如何防止winform程序因為誤操作被關閉

前言: 大家好,我是上位機馬工,碩士畢業4年年入40萬,目前在一家自動化公司擔任軟件經理,從事C#上位機軟件開發8年以上!我們在開發的上位機軟件運行起來以后,一般在右上角都有一個關閉按鈕,正常情況下點擊關閉按鈕就能關閉軟件,但是不排除我們不想關閉軟件,但是因為不…

ffmpeg avdevice_register_all 注冊設備的作用

在 FFmpeg 中&#xff0c;avdevice_register_all() 是一個用于注冊所有輸入和輸出設備的函數。它是 FFmpeg 的 libavdevice 模塊的一部分&#xff0c;專門用于處理音頻和視頻的輸入/輸出設備&#xff08;如攝像頭、麥克風、屏幕捕獲等&#xff09;。 以下是對 avdevice_regist…

[RH342]tcpdump

[RH342]tcpdump 1. 題目2. 解題 1. 題目 服務器serverc 和 servera 之間有進程定期發送一個明文密碼,找出它2. 解題 找出通信端口 抓包分析 tcpdump -X -vv port 6644紅框中就是密碼,所以密碼是root123

連接Sql Server時報錯無法通過使用安全套接字層加密與 SQL Server 建立安全連接

文章目錄 一. 前言二. 解決方案 方案1方案2 三. 總結 一. 前言 在《數據庫原理》這門課的實驗上&#xff0c;需要使用SQL Server&#xff0c;然后使用jdbc連接sql server突然報錯為&#xff1a;SQLServerException: “Encrypt”屬性設置為“true”且 “trustServerCertific…

從 Spring Boot 2 升級到 Spring Boot 3 的終極指南

一、升級前的核心準備 1. JDK 版本升級 Spring Boot 3 強制要求 Java 17 及以上版本。若當前項目使用 Java 8 或 11&#xff0c;需按以下步驟操作&#xff1a; 安裝 JDK 17&#xff1a;從 Oracle 或 OpenJDK 官網下載&#xff0c;配置環境變量&#xff08;如 JAVA_HOME&…

Buildroot 添加自定義模塊-內置文件到文件系統

目錄 概述實現步驟1. 創建包目錄和文件結構2. 配置 Config.in3. 定義 cp_bin_files.mk4. 添加源文件install.shmy.conf 5. 配置與編譯 概述 Buildroot 是一個高度可定制和模塊化的嵌入式 Linux 構建系統&#xff0c;適用于從簡單到復雜的各種嵌入式項目. buildroot的源碼中bui…

物聯網通信應用案例之《智慧農業》

案例概述 在智慧農業方面&#xff0c;一般的應用場景為可以自動檢測溫度濕度等一系列環境情況并且可以自動做出相應的處理措施如簡單的澆水和溫度控制等&#xff0c;且數據情況可遠程查看&#xff0c;以及用戶可以實現遠程控制。 基本實現原理 傳感器通過串口將數據傳遞到Wi…

設計模式| 觀察者模式 Observer Pattern詳解

目錄 一、概述1.1 動機1.2 核心思想1.3 別名 二、角色與實現原理2.1 角色2.2 實現原理2.3 類圖 三、經典接口實現3.1 示例3.1.1 觀察者接口3.1.2 目標接口3.1.3 具體被觀察者3.1.4 具體觀察者3.1.5 Client3.1.6 UML時序圖 3.2 特點 四、其他實現方式4.1 委托與事件&#xff08;…

kotlin 知識點一 變量和函數

在Kotlin中定義變量的方式和Java 區別很大&#xff0c;在Java 中如果想要定義一個變 量&#xff0c;需要在變量前面聲明這個變量的類型&#xff0c;比如說int a表示a是一個整型變量&#xff0c;String b表 示b是一個字符串變量。而Kotlin中定義一個變量&#xff0c;只允許在變量…

基于數據可視化學習的卡路里消耗預測分析

數據分析實操集合&#xff1a; 1、關于房間傳感器監測數據集的探索 2、EEMD-LSTM模型擇時策略 — 1.EEMD分解與LSTM模型搭建 3、EEMD-LSTM模型擇時策略 — 2. 量化回測 4、國際超市電商銷售數據分析 5、基于問卷調查數據的多元統計數據分析與預測&#xff08;因子分析、對應分…

記錄Liunx安裝Jenkins時的Package ‘jenkins‘ has no installation candidate

1、確保是否安裝了Java&#xff0c;如果沒有&#xff0c;可通過以下命令進行安裝&#xff1a; sudo apt update sudo apt install openjdk-21-jre2、安裝Jenkins sudo apt update sudo apt install jenkins執行sudo apt install jenkins時&#xff0c;可能會出現 意思是&…

kiln微調大模型-使用deepseek R1去訓練一個你的具備推理能力的chatGPT 4o

前言 隨著deepseek的爆火&#xff0c;對于LLM的各種內容也逐漸步入我的視野&#xff0c;我個人認為&#xff0c;可能未來很長一段時間&#xff0c;AI將持續爆火&#xff0c;進入一段時間的井噴期&#xff0c;AI也會慢慢的走入我們每個家庭之中&#xff0c;為我們的生活提供便利…

用AI玩游戲1——狼人殺六人局

狼人殺六人局1 狼人殺六人局1&#xff0c;好人陣營有兩個平民&#xff0c;一個預言家&#xff0c;一個守衛&#xff0c;壞人陣營有兩個狼人。狼人每晚可以選擇殺死一個人但第一天晚上不能殺人&#xff0c;狼人晚上可以睜眼識別到同伴和其他好人玩家但不知道他們的身份。預言家…

sqli-labs

Less-8 單引號報錯&#xff0c;雙引號顯示正常 又是You are in......看來還是用盲注 布爾盲注&#xff1a; 如下語句是用來判斷當前數據庫名的第一個字母是不是s&#xff0c;后面的以此類推&#xff0c;比較復雜和麻煩 ?id1 and substr(database(),1,1)s -- 比如這個我們通…

自定義ToolbarView實戰指南(Kotlin版)

一、為什么我們需要造輪子&#xff1f; 看到標題你可能會問&#xff1a;系統自帶Toolbar不香嗎&#xff1f;確實香&#xff0c;但遇到這些場景就抓瞎了&#xff1a; 設計稿要求標題欄帶漸變背景動態波浪線產品經理非要搞個不對稱的返回按鈕布局UI設計師堅持標題和副標題要45度…

微軟推出Office免費版,限制諸多,只能編輯不能保存到本地

易采游戲網2月25日獨家消息&#xff1a;微軟宣布推出一款免費的Office版本&#xff0c;允許用戶進行基礎文檔編輯操作&#xff0c;但限制頗多&#xff0c;其中最引人關注的是用戶無法將文件保存到本地。這一舉措引發了廣泛討論&#xff0c;業界人士對其背后的商業策略和用戶體驗…

PyTorch-基礎(CUDA、Dataset、transforms、卷積神經網絡、VGG16)

PyTorch-基礎 環境準備 CUDA Toolkit安裝&#xff08;核顯跳過此步驟&#xff09; CUDA Toolkit是NVIDIA的開發工具&#xff0c;里面提供了各種工具、如編譯器、調試器和庫 首先通過NVIDIA控制面板查看本機顯卡驅動對應的CUDA版本&#xff0c;如何去下載對應版本的Toolkit工…

Vue2+Element實現Excel文件上傳下載預覽【超詳細圖解】

目錄 一、需求背景 二、落地實現 1.文件上傳 圖片示例 HTML代碼 業務代碼 2.文件下載 圖片示例 方式一&#xff1a;代碼 方式二&#xff1a;代碼 3.文件預覽 圖片示例 方式一&#xff1a;代碼 方式二&#xff1a;代碼 一、需求背景 在一個愉快的年后&#xff…

【Bug】natten:安裝報錯(臨近注意力機制的高效cuda內核實現)

正常安裝natten報錯 pip install natten 報錯 可以嘗試使用以下網站進行安裝 https://shi-labs.com/natten/ 可以根據自己的cuda與pytorch版本進行安裝 之間復制命令即可&#xff0c;不需要進行任何修改

win10把c盤docker虛擬硬盤映射遷移到別的磁盤

c盤空間本身就比較小、如果安裝了docker服務后&#xff0c;安裝的時候沒選擇其他硬盤&#xff0c;虛擬磁盤也在c盤會占用很大的空間&#xff0c;像我的就三十多個G&#xff0c;把它遷移到其他磁盤一下子節約幾十G 1、先輸入下面命令查看 docker 狀態 wsl -l -v 2、如果沒有停止…