C++(Qt)軟件調試---bug排查記錄(36)

C++(Qt)軟件調試—bug排查記錄(36)


文章目錄

  • C++(Qt)軟件調試---bug排查記錄(36)
    • @[toc]
    • 1 無返回值函數風險
    • 2 空指針調用隱患
    • 3 Debug/Release差異
    • 4 ARM架構char符號問題
    • 5 linux下找不到動態庫

更多精彩內容
👉內容導航 👈
👉C++軟件調試 👈

1 無返回值函數風險

  • 如果一個函數的返回值為void,則編譯器會自動插入一個默認return;

  • 如果非void的函數沒有寫return,有些版本的編譯器會默認插入一個ret(例如gcc7.3,高版本gcc會插入ud2),不過這個代碼還是不安全的。

  • 如果一個函數的返回值不為void,但是忘記寫return語句了,會破壞棧幀的出棧,導致未定義異常,可能會軟件崩潰,也可能不會崩潰,調用者會試圖從棧上的某個位置讀取返回值。由于這個位置沒有被正確設置,讀取的內容將是隨機的數據,這可能導致程序繼續運行但行為異常;

  • Release版本與Debug版本的差異:在Debug版本中,由于內存受到保護,即使函數沒有return語句,也可能不會立即導致程序崩潰。但在Release版本中,由于所有保護都被移除,訪問錯誤內存或寄存器值很可能導致程序異常退出或崩潰。

  • 使用基本數據類型有可能不會導致程序崩潰。

  • 例如:

int fun1()
{int a = 123;
}
QByteArray fun2()
{QByteArray arr("123");
}
int main()
{fun1();fun2();return 0;
}
  • 并且這種情況導致的程序崩潰使用調試工具很難定位,定位的位置非常隨機。

  • 不過要視編譯器而定,有些編譯器會編譯報錯,例如MSVC,有些不會,例如gcc默認只是會報警告-Wreturn-type

  • gcc可以通過-Werror=return-type選項將警告設置為錯誤信息,防止忽略;gcc編譯選項

  • 或者使用MSVC編譯器編譯程序,也可以檢測出未寫return的錯誤。

  • QMake可以通過下面配置將缺失返回值警告設置為錯誤。

    QMAKE_CC += -Werror=return-type
    QMAKE_CXX += -Werror=return-type
    
  • 如下圖所示,如果非void返回值函數沒有寫return語句,則在函數匯編中缺失popret指令;

    • pop 通常用于恢復先前保存的寄存器值(如 ebp 或者 rbp 在 x86 架構上),或者彈出參數等。如果沒有執行 pop 操作,那么這些值將不會被正確地恢復,這可能會導致后續函數調用或程序邏輯出現問題。
    • 當函數調用發生時,返回地址會被壓入棧中。如果函數結束時沒有使用 ret 來處理這個返回地址,棧指針將指向錯誤的位置,破壞棧的結構,影響后續的函數調用和返回操作。
    • 缺少正確的 popret 指令使得調試更加復雜,因為正常的調用堆棧信息不再可靠。

在這里插入圖片描述


2 空指針調用隱患

  • 當一個對象為空指針或者野指針時如果調用成員函數,可能會出現未定義異常導致崩潰,也可能不會崩潰;
  • 如果調用的成員函數沒有使用this指針寫入數據,則不會導致崩潰;
    • 情況1:沒有使用到任何成員變量;
    • 情況2:調用的是static成員函數;
    • 情況3:只是讀取成員變量,沒有寫入成員變量。
  • 這種不崩潰是危險的
    • 不可預測性:行為依賴于編譯器、平臺和運行時狀態
    • 隱蔽性:錯誤可能在生產環境中突然出現
    • 調試困難:問題表現不穩定,難以復現
#include <iostream>
using namespace std;
class A {
public :void f(int x) {int a = x;// m_a = 123;   // 崩潰for(int i = 0; i < x; i++){cout << i << endl;}cout << a <<" " << &m_a <<" "<<this << endl;}
private:int m_a;
};int main() {A* a ;a -> f(10);a->f(2);return 0;
}

3 Debug/Release差異

Debug模式下通常會有更多的內存保護機制,這有助于捕獲潛在的內存錯誤。

這些保護機制在Release模式下可能被禁用或簡化,從而導致某些問題在Debug模式下不明顯但在Release模式下暴露出來。具體來說:

  • 內存初始化

    • Debug模式下,編譯器可能會自動將未初始化的變量設置為特定值(如0或特殊標記值),以幫助檢測未初始化變量的使用。
    • Release模式下,未初始化的變量保持未初始化狀態,可能導致不可預測的行為。
  • 邊界檢查

    • Debug模式下,可能會啟用額外的數組和指針邊界檢查,防止越界訪問。
    • Release模式下,這些檢查通常被移除以提高性能,因此越界訪問可能導致崩潰或未定義行為。
  • 堆棧保護

    • Debug模式下,堆棧可能會有更多的保護措施,例如填充“安全”值來檢測堆棧溢出。
    • Release模式下,這些保護措施可能被移除或簡化。
  • 調試信息

    • Debug模式下,程序會包含更多的調試信息和符號表,便于調試工具(如GDB、Visual Studio Debugger)進行更詳細的分析。
    • Release模式下,這些調試信息通常被移除,導致難以通過調試工具捕捉到問題。

解決方法

  1. 使用靜態分析工具

    • 使用靜態分析工具(如Clang Static Analyzer、Cppcheck)來檢測代碼中的潛在問題。
  2. 啟用運行時檢查

    • 在Release模式下啟用運行時檢查工具,如AddressSanitizer、Valgrind等,可以幫助檢測內存錯誤。
  3. 確保一致的初始化

    • 確保所有變量在使用前都已正確初始化,避免依賴Debug模式下的默認初始化行為。
  4. 檢查內存分配和釋放

    • 檢查動態內存分配和釋放是否正確,確保沒有內存泄漏或雙重釋放的問題。
  5. 審查多線程代碼

    • 如果程序涉及多線程,確保線程同步機制正確無誤,避免競爭條件和死鎖。
  6. 對比宏定義

    • 檢查Debug和Release模式下的宏定義差異,確保兩種模式下的行為一致,特別是與內存管理相關的宏定義。

4 ARM架構char符號問題

  • 在vs編譯器、x86架構linux中的gcc編譯器ux中的gcc編譯器都是把char定義為signed char;

  • arm-linux-gcc把char定義為unsigned char;

  • 所以直接使用char有移植性問題,例如在x86架構中開發的程序,在arm架構系統(例如國產銀河麒麟、樹莓派、Android等)中可能就會出現問題,并且這種情況很隱蔽,比較難排查;

  • 例如在cppreference中的定義:

    在這里插入圖片描述

  • 解決辦法:

    1. 在編譯時加上選項-fsigned-char
    2. 不使用char,改成使用int8_t或者qint8;

5 linux下找不到動態庫

  1. 使用ldd命令查看可執行程序或者動態庫的鏈接路徑,是否找得到動態庫;

  2. 使用下面命令查看、修改動態庫鏈接路徑

    patchelf --set-rpath '$ORIGIN/lib/' ./RadarServer     # 設置程序動態庫鏈接路徑
    patchelf --print-rpath ./RadarServer   # 打印鏈接路徑
    


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

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

相關文章

人工智能領域、圖歐科技、IMYAI智能助手2025年8月更新月報

IMYAI 平臺 2025 年 8 月功能更新與模型上新匯總 2025年08月31日 功能更新&#xff1a; 對話與繪畫板塊現已支持多文件批量上傳。用戶可通過點擊或拖拽方式一次性上傳多個圖片或文件&#xff0c;操作更加便捷。2025年08月25日近期更新亮點&#xff1a; 文檔導出功能增強&#x…

2025獨立站技術風向:無頭電商+PWA架構實戰指南

根據 Gitnux 的統計數據&#xff0c;預計到 2025 年&#xff0c;北美將有 60% 的大型零售商采用無頭平臺。而仍在傳統架構上運營的獨立站&#xff0c;平均頁面加載速度落后1.8秒&#xff0c;轉化率低32%。無獨有偶&#xff0c;Magento Association 的一項調查顯示&#xff0c;7…

淘寶京東拼多多爬蟲實戰:反爬對抗、避坑技巧與數據安全要點

一、先搞懂&#xff1a;電商爬蟲的 3 大核心挑戰&#xff08;比普通爬蟲更復雜的原因&#xff09; 做電商爬蟲前&#xff0c;必須先明確「為什么難」—— 淘寶、京東、拼多多的反爬體系是「多層級、動態化、行為導向」的&#xff0c;絕非簡單的 UA 驗證或 IP 封禁&#xff1a;…

【1】MOS管的結構及其工作原理

以nmos舉例&#xff0c;mos管由三個電極&#xff1a;G極&#xff08;gate&#xff09;、D極&#xff08;drain&#xff09;、S極&#xff08;source&#xff09;和一個襯底組成&#xff0c;而這三個電極之間通過絕緣層相隔開&#xff1b;①既然GDS三個電極之間兩兩相互絕緣&…

如何保存訓練的最優模型和使用最優模型文件

一 保存最優模型主要就是我們在for循環中加上一個test測試&#xff0c;并且我還在test函數后面加上了返回值&#xff0c;可以返回準確率&#xff0c;然后每次進行一次對比&#xff0c;然后取大的。然后這里有兩種保存方式&#xff0c;一種是保存了整個模型&#xff0c;另一個是…

vue3+ts+echarts多Y軸折線圖

因為放在了子組件才監聽&#xff0c;加載渲染調用&#xff0c;有暗黑模式才調用&#xff0c;<!-- 溫濕度傳感器 --><el-row v-if"deviceTypeId 2"><el-col :xs"24" :sm"24" :md"24" :lg"24" :xl"24&qu…

基于Taro4打造的一款最新版微信小程序、H5的多端開發簡單模板

基于Taro4、Vue3、TypeScript、Webpack5打造的一款最新版微信小程序、H5的多端開發簡單模板 特色 &#x1f6e0;? Taro4, Vue 3, Webpack5, pnpm10 &#x1f4aa; TypeScript 全新類型系統支持 &#x1f34d; 使用 Pinia 的狀態管理 &#x1f3a8; Tailwindcss4 - 目前最流…

ITU-R P.372 無線電噪聲預測庫調用方法

代碼功能概述&#xff08;ITURNoise.c&#xff09;該代碼是一個 ITU-R P.372 無線電噪聲預測 的計算程序&#xff0c;能夠基于 月份、時間、頻率、地理位置、人為噪聲水平 計算特定地點的 大氣噪聲、銀河噪聲、人為噪聲及其總和&#xff0c;并以 CSV 或標準輸出 方式提供結果。…

《從報錯到運行:STM32G4 工程在 Keil 中的頭文件配置與調試實戰》

《從報錯到運行&#xff1a;STM32G4 工程在 Keil 中的頭文件配置與調試實戰》文章提綱一、引言? 闡述 STM32G4 在嵌入式領域的應用價值&#xff0c;說明 Keil 是開發 STM32G4 工程的常用工具? 指出頭文件配置是 STM32G4 工程在 Keil 中開發的關鍵基礎環節&#xff0c;且…

Spring 事務提交成功后執行額外邏輯

1. 場景與要解決的問題在業務代碼里&#xff0c;常見訴求是&#xff1a;只有當數據庫事務真正提交成功后&#xff0c;才去執行某些“后置動作”&#xff0c;例如&#xff1a;發送 MQ、推送消息、寫審計/埋點日志、刷新緩存、通知外部系統等。如果這些動作在事務提交前就執行&am…

Clickhouse MCP@Mac+Cherry Studio部署與調試

一、需求背景 已經部署測試了Mysql、Drois的MCP Server,想進一步測試Clickhouse MCP的表現。 二、環境 1)操作系統 MacOS+Apple芯片 2)Clickhouse v25.7.6.21-stable、Clickhouse MCP 0.1.11 3)工具Cherry Studio 1.5.7、Docker Desktop 4.43.2(199162) 4)Python 3.1…

Java Serializable 接口:明明就一個空的接口嘛

對于 Java 的序列化,我之前一直停留在最淺層次的認知上——把那個要序列化的類實現 Serializbale 接口就可以了嘛。 我似乎不愿意做更深入的研究,因為會用就行了嘛。 但隨著時間的推移,見到 Serializbale 的次數越來越多,我便對它產生了濃厚的興趣。是時候花點時間研究研…

野火STM32Modbus主機讀取寄存器/線圈失敗(三)-嘗試將存貯事件的地方改成數組(非必要解決方案)(附源碼)

背景 盡管crc校驗正確了&#xff0c;也成功發送了EV_MASTER_EXECUTE事件&#xff0c;但是eMBMasterPoll( void )中總是接收的事件是EV_MASTER_FRAME_RECEIVED或者EV_MASTER_FRAME_SENT&#xff0c;一次都沒有執行EV_MASTER_EXECUTE。EV_MASTER_EXECUTE事件被別的事件給覆蓋了&…

微信小程序校園助手程序(源碼+文檔)

源碼題目&#xff1a;微信小程序校園助手程序&#xff08;源碼文檔&#xff09;?? 文末聯系獲取&#xff08;含源碼、技術文檔&#xff09;博主簡介&#xff1a;10年高級軟件工程師、JAVA技術指導員、Python講師、文章撰寫修改專家、Springboot高級&#xff0c;歡迎高校老師、…

59-python中的類和對象、構造方法

1. 認識一下對象 世間萬物皆是"對象" student_1{ "姓名":"小樸", "愛好":"唱、跳、主持" ......... }白紙填寫太落伍了 設計表格填寫先進一些些 終極目標是程序使用對象去組織數據程序中設計表格&#xff0c;我們稱為 設計類…

向成電子驚艷亮相2025物聯網展,攜工控主板等系列產品引領智造新風向

2025年8月27-29日&#xff0c;IOTE 2025 第二十四屆國際物聯網展深圳站在深圳國際會展中心&#xff08;寶安&#xff09;盛大啟幕&#xff01;作為全球規模領先的物聯網盛會之一&#xff0c;本屆展會以“生態智能&#xff0c;物聯全球”為核心&#xff0c;匯聚超1000家全球頭部…

陣列信號處理之均勻面陣波束合成方向圖的繪制與特點解讀

陣列信號處理之均勻面陣波束合成方向圖的繪制與特點解讀 文章目錄前言一、方向圖函數二、方向圖繪制三、副瓣電平四、陣元個數對主瓣寬度的影響五、陣元間距對主瓣寬度的影響六、MATLAB源代碼總結前言 \;\;\;\;\;均勻面陣&#xff08;Uniform Planar Array&#xff0c;UPA&…

算法在前端框架中的集成

引言 算法是前端開發中提升性能和用戶體驗的重要工具。隨著 Web 應用復雜性的增加&#xff0c;現代前端框架如 React、Vue 和 Angular 提供了強大的工具集&#xff0c;使得將算法與框架特性&#xff08;如狀態管理、虛擬 DOM 和組件化&#xff09;無縫集成成為可能。從排序算法…

網絡爬蟲是自動從互聯網上采集數據的程序

網絡爬蟲是自動從互聯網上采集數據的程序網絡爬蟲是自動從互聯網上采集數據的程序&#xff0c;Python憑借其豐富的庫生態系統和簡潔語法&#xff0c;成為了爬蟲開發的首選語言。本文將全面介紹如何使用Python構建高效、合規的網絡爬蟲。一、爬蟲基礎與工作原理 網絡爬蟲本質上是…

Qt Model/View/Delegate 架構詳解

Qt Model/View/Delegate 架構詳解 Qt的Model/View/Delegate架構是Qt框架中一個重要的設計模式&#xff0c;它實現了數據存儲、數據顯示和數據編輯的分離。這種架構不僅提高了代碼的可維護性和可重用性&#xff0c;還提供了極大的靈活性。 1. 架構概述 Model/View/Delegate架構將…