調試——GDB、日志

調試——GDB、日志

    • 1. gdb常用指令
    • 2. 如何生成core文件并調試?
    • 3. 如何調試正在運行的程序
    • 4. 調試多進程程序
    • 5. 調試多線程程序
    • 6. log日志

  • gcc編譯器可以幫我們發現語法錯誤,但是對業務邏輯錯誤卻無能為力。當我們想找出邏輯錯誤時,就需要調試,也就是要用gdb調試
  • GDB(gdb)全稱“GNU symbolic debugger”,是 Linux 下常用的程序調試器。 為了能夠使用 gdb 調試,需要在代碼編譯的時候加上-g,如
g++ -g -o test test.cpp

1. gdb常用指令

b(break) 10	:在第10行打上斷點
r(run) :開始運行程序,直到遇到斷點,并在斷點這一行停下來(第一個運行的命令)
c(continue) :繼續運行,一般先停下來,再用continue繼續運行,直到遇到下一個斷點
n(next) :執行當前這一行(徹底執行完,如果當前這一行是函數調用,則執行完這個函數)
p(print) name :顯示變量name的值
p name++ :后面可以寫一行代碼,也就是一個表達式(什么都行,包括改變變量、輸出都行)
set var name="仲書頡" :set var可以設置變量的值,這里設置name的值為仲書頡
set args 參數1 參數2:set args可以設置main(args,argv[])函數的參數,參數1就是argv[1]的值,參數2就是argv[2]的值-注意,當參數1內有空格時,要這樣表示:set args "參數1" 參數2
s(step) :執行當前這一行-這一行不是函數時,和n(next)一樣-這一行是函數時,s會進入函數的內部,執行函數內部的第一行(想進入函數里面,必須要用step)-注意,s并不能進入庫函數或第三方函數,只能進入我們自己定義的函數(有函數源碼)
l(list) :顯示10行代碼(基本不用,因為我們會另開一個窗口看源代碼,一般不用list來看)
bt :查看執行到目前這一行為止,函數的調用棧
info b :顯示斷點的信息(有幾個,哪幾個)
info threads :顯示已創建的線程的信息,帶*號的就是當前被調試的線程
thread 2 :切換到id為2的線程來調試

2. 如何生成core文件并調試?

當程序出現段錯誤(core dump)時,用gdb調試core文件,可以立即定位到段錯誤所在行****,非常方便但是core文件默認是不生成的如何生成core文件呢?

在程序出現段錯誤后,我們需要在Linux中輸入:
ulimit -a

會顯示這樣的結果:

我們只需要關注第一行,上面顯示core文件大小為0

將core文件大小改為unlimited
ulimit -c unlimited

再出入ulimit -a后,顯示:

gdb打開core文件

設置完core文件大小后,我們重新運行源程序,就會生成core文件。我們可以通過 **ls **來查看。

然后就用gdb調試即可:

gdb 可執行文件 core文件
#如:gdb book core19356

會顯示:

可見,直接顯示在第7行出現段錯誤

注:什么是段錯誤

**訪問未分配或權限不足的內存 所產生的錯誤,就是段錯誤。有以下幾種情況:

**

3. 如何調試正在運行的程序

如果我們使用gdb調試一個這個在運行的程序,那么這個程序就會立即停止運行。此時為了查看程序運行到說明地方,我們需要用 bt 命令,來查看函數的調用棧——最上面的就是正在運行的函數。

我們可用使用其他調試命令,如n、s等,可以讓原本停下的程序繼續運行一行。通過組合使用 n、s 和 bt 命令,可以調試正在運行的程序

4. 調試多進程程序

注:被調試的進程會停止運行,將在調試命令下一步一步執行。

調試父進程(默認)

默認就是調試父進程,或者也可以顯示指定:

set follow-fork-mode parent

此時子進程將自動執行;而父進程會阻塞(因為先前設置了斷點),等待我們的調試

調試子進程

需要顯示指定:

set follow-fork-mode child

此時父進程將自動執行;而子進程會阻塞(因為先前設置了斷點),等待我們的調試

調試模式

在確定調試子進程還是父進程后,就可以設置調試模式了,一共有兩種調試模式:

調試當前進程時,其他進程繼續運行

這是默認的情況,也可以顯示指定:

set detach-on-fork on 
調試當前進程時,其他進程被gdb掛起,不能運行

需要顯示指定:

set detach-on-fork off

如果我們是在調試父進程時采用了第二種調試模式,那么在調試父進程時,子進程不會自動運行。即使父進程調試執行完,子進程也不會運行。

查看和切換被調試的進程

設置第二種調試模式之后(即 set detach-on-fork off),我們才能查看和切換被調試的進程。

查看被調試的進程
info inferiors

序號1的前面有*號,表示我們正在調試的進程是 序號為1的進程

**切換要調試的進程**
inferior 進程id
#如 inferior 2,表示改為調試進程2,不再調試進程1

5. 調試多線程程序

注:如果使用的是POSIX線程庫的話,在編譯時還要加上 -l pthread

查看進程、線程以及線程之間的關系
//shell命令(非gdb命令):
ps aux | grep 過濾條件  #查看當前運行的進程ps -aL | grep 過濾條件  #查看當前運行的線程pstree -p 主線程id  #查看主線程和子線程之間的關系

線程調試的基礎命令
info threads #顯示已創建的線程的信息,帶*號的就是當前被調試的線程thread 3 #切換到id為3的線程來調試

設置線程調試模式
**調試當前線程時,其他線程繼續運行**

默認的情況,也可以顯示指定:

set scheduler-locking off
**調試當前線程時,其他線程全部阻塞**

需要顯示指定:

set scheduler-locking on
讓指定線程執行指定命令
thread apply 線程id 命令
#如:thread apply 2 n,表示讓線程3往下執行一次(即使當前調試的不是線程2,也可以執行該語句)

另,也可以讓所有線程執行同一個語句:

thread apply all 命令

6. log日志

設置斷點和單步調試 會嚴重影響線程之間的競爭狀態。因為當一個線程在斷點處停住了,而讓另一個線程跑,就會導致并發被破壞,此時我們看到的只是一個和諧的假象。而log日志,就可以避免斷點和單步的副作用。我們可以輸出log日志,讓程序每一步運行的時間都可以在日志文件中查到。

開源日志框架——freecplus

項目里需要同時包含_cmpublic.h、_freecplus.h、_freecplus.cpp這三個文件。第一個里全是程序用到的頭文件;第二個文件包含了第一個文件,它定義了函數和類的聲明;第三個文件包含了第二個文件,它是對函數和類的具體實現。_cmpublic.h_freecplus.cpp_freecplus.h

具體使用過程:

  1. 包含#include<_freecplus.h>(第一個文件就不用寫了,因為已經包含了)
  2. 定義日志文件類(全局):
CLogFile logfile;
  1. 創建日志文件
logfile.Open("/tmp/gdbfork.log","w+");
/* 
/tmp/gdbfork.log是日志文件名,可以自己定義; w+是打開文件的方式,直接寫上就好
*/
  1. 將所有的輸出語句(printf、cout等)改為輸出到日志文件
logfile.Write("Hello World");
  1. 編譯并運行項目
g++ gdbfork.cpp _freecplus.cpp -o gdbfork
./gdbfork  #此時日志已經把所有的內容 輸出的日志文件里面了
  1. 最后打開日志文件來查看即可
vi /tmp/gdbfork.log

我們也可以一邊讓程序運行,一邊打開事先創建的日志文件,這樣就可以觀測** 程序運行的實時狀態**。

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

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

相關文章

redis----通用命令

文章目錄 前言一、運行redis二、help [command]三、通用命令 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 學習一些通用命令 以下操作在windows中演示 提示&#xff1a;以下是本篇文章正文內容&#xff0c;下面案例可供參考 一、運行redis 我們先c…

CatBoost算法原理及Python實現

一、概述 CatBoost 是在傳統GBDT基礎上改進和優化的一種算法&#xff0c;由俄羅斯 Yandex 公司開發&#xff0c;于2017 年開源&#xff0c;在處理類別型特征和防止過擬合方面有獨特優勢。 在實際數據中&#xff0c;存在大量的類別型特征&#xff0c;如性別、顏色、類別等&#…

五一假期作業

sub_process.c #include <stdio.h> // 標準輸入輸出庫 #include <pthread.h> // POSIX線程庫 #include <sys/ipc.h> // IPC基礎定義&#xff08;如消息隊列/共享內存&#xff09; #include <sys/msg.h> // 消息隊列操作相關…

Liunx安裝Apache Tomcat

目錄 一、了解tomcat 二、下載 三、啟動tomcat 四、網頁訪問tomcat 五、Tomcat修改默認8080端口 六、Tomcat創建項目步驟-實現項目對外訪問 一、了解tomcat Apache Tomcat 是一個開源的 Java Servlet 容器 和 Web 服務器&#xff0c;主要用于運行基于 Java 的 Web 應用…

破局者手冊 Ⅰ:測試開發核心基礎,解鎖未來測試密鑰!

目錄 一、引入背景 二、軟件測試基礎概念 2.1 軟件測試的定義 2.2 軟件測試的重要性 2.3 軟件測試的原則 三、測試類型 3.1 功能測試 3.2 接口測試 3.2.1 接口測試的概念 3.2.2 接口測試的重要性 3.2.3 接口測試的要點 3.2.4 接口測試代碼示例&#xff08;Python r…

C++ 適配器模式詳解

適配器模式&#xff08;Adapter Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許不兼容的接口之間能夠協同工作。 概念解析 適配器模式的核心思想是&#xff1a; 接口轉換&#xff1a;將一個類的接口轉換成客戶希望的另一個接口 兼容性&#xff1a;使原本由于接…

【NLP】 28. 語言模型的評估方式:MRR, PERPLEXITY, BLEU, WER從困惑度到實際效果

語言模型的評估方式&#xff1a;從困惑度到實際效果 評估語言模型&#xff08;LLM&#xff09;是否有效&#xff0c;并不僅僅是看它生成句子是否“聽起來通順”&#xff0c;我們需要定量的指標對模型性能做出系統性評價。評估方法主要分為兩大類&#xff1a; 內在評價&#x…

Java 企業級開發設計模式全解析

Java 企業級開發設計模式全解析 在 Java 企業級開發的復雜領域中&#xff0c;設計模式如同精湛的工匠工具&#xff0c;能夠幫助開發者構建高效、可維護、靈活且健壯的軟件系統。它們是無數開發者在長期實踐中總結出的解決常見問題的最佳方案&#xff0c;掌握這些模式對于提升開…

小剛說C語言刷題—1038編程求解數學中的分段函數

1.題目描述 編程求解數學中的分段函數。 …………x1 (當 x>0 )。 yf(x)…0 (當 x0 )。 ………x?1 (當 x<0 )。 上面描述的意思是&#xff1a; 當x>0 時 yx1 ; 當 x0 時 y0 ; 當 x<0 時 yx?1 。 輸入 輸入一行&#xff0c;只有一個整數x(?30000≤x≤30…

滾珠螺桿的精度如何保持?

滾珠螺桿通常用于需要精確定位的地方&#xff0c;高機械效率、低傳遞扭矩和幾乎為零的軸向游隙&#xff0c;使滾珠螺桿成為工具定位和飛機副翼驅動等應用中的重要設備。但是&#xff0c;連續工作產生的阻力和熱量會導致較大的摩擦力和定位誤差。那么&#xff0c;滾珠螺桿的精度…

在 Laravel 中深度集成 Casbin 到原生 Auth 系統

在 Laravel 中深度集成 Casbin 到原生 Auth 系統需要實現多層次的融合&#xff0c;以下是專業級實現方案&#xff1a; 一、核心集成架構 #mermaid-svg-WYM1aoAyHrR5bCdp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-…

JavaScript 實現輸入框的撤銷功能

在 Web 開發中&#xff0c;為輸入框添加撤銷功能可以極大地提升用戶體驗&#xff0c;方便用戶快速回滾到之前的輸入狀態。本文將通過一段簡單的 HTML、CSS 和 JavaScript 代碼&#xff0c;詳細介紹如何實現輸入框的撤銷功能。 整體實現思路 利用 JavaScript 監聽輸入框的inpu…

計算機視覺與深度學習 | 點云配準算法綜述(1992-2025)

點云配準算法綜述(1992-2025) 點云配準 點云配準算法綜述(1992-2025)一、傳統方法(1992-2020)1. **ICP(Iterative Closest Point)**2. **NDT(Normal Distributions Transform)**3. **4PCS(4-Points Congruent Sets)**二、深度學習驅動的方法(2018-2025)1. **Poin…

數據庫的二級索引

二級索引 10.1 二級索引作為額外的鍵 表結構 正如第8章提到的&#xff0c;二級索引本質上是包含主鍵的額外鍵值對。每個索引通過B樹中的鍵前綴來區分。 type TableDef struct {// 用戶定義的部分Name stringTypes []uint32 // 列類型Cols []string // 列名Indexes …

Java IO流核心處理方式詳解

一、IO流概述 Java IO&#xff08;Input/Output&#xff09;流是處理輸入輸出操作的核心機制&#xff0c;通過流&#xff08;Stream&#xff09;的形式實現設備間的數據傳輸。所有操作都基于以下兩個核心抽象&#xff1a; InputStream/OutputStream&#xff1a;字節流基類 Re…

WidowX-250s 機械臂的簡單數字孿生案例

前面一段時間記錄了一下WidowX-250s機械臂的學習與遙操作演示&#xff0c;相關鏈接如下&#xff1a; WidowX-250s 機械臂學習記錄&#xff1a; https://blog.csdn.net/qq_54900679/article/details/145556979 WidowX-250s 機械臂遙操作演示記錄&#xff1a; https://blog.c…

uniapp 云開發全集 云開發的概念

一、云開發的概念 1.1 云開發介紹 云開發 unicloud 是 DCloud 聯合阿里云、騰訊云、支付寶云&#xff0c;為開發者提供的基于 serverless 模式和 js 編程的云開發平臺&#xff0c;可以使用極小的成本代價開發具輕松實現前后臺整體業務。 1.2 云開發的核心組成 云開發的核心組…

GGD獨立站的優勢

GGD模式(基于Google生態的獨立站模式)越來越受歡迎&#xff0c;主要有以下原因&#xff1a; 1. 全球化覆蓋 GGD獨立站依托Google強大的生態系統&#xff0c;能夠幫助企業輕松觸達全球用戶&#xff0c;實現國際化布局&#xff0c;拓展業務范圍。Google作為全球最大的搜索引擎&…

簽名去背景圖像處理實例

一、前言 在生活中我們經常用到電子簽名&#xff0c;但有時候我們所獲取的圖像的彩色圖像&#xff0c;我們需要獲取白底黑字的電子簽名&#xff0c;我們可以通過下面程序對彩色圖像進行處理達到我們的處理目的。 原始彩色圖像如下&#xff1a; 二、程序和運行結果 clear all;c…

WebAssembly(Wasm):現代Web開發的超級加速器

在當今的Web開發領域&#xff0c;性能和效率是開發者們永恒的追求目標。隨著Web應用的復雜度不斷增加&#xff0c;傳統的JavaScript在某些場景下已經難以滿足高性能計算和復雜邏輯處理的需求。此時&#xff0c;WebAssembly&#xff08;Wasm&#xff09;作為一種新興的Web技術&a…