GDB除錯基礎使用方法
阿新 • • 發佈:2020-11-06
> 儘管目前使用的VS code可以使用外掛一鍵構建和執行程式,但GDB作為除錯利器,還是值得花時間去學習的。
**概述**
**GDB(GNU Debugger)** 是一個由GNU開源組織釋出的、UNIX/LINUX作業系統下的、基於命令列的、功能強大的程式除錯工具。
參考: [gdb除錯利器](https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/gdb.html)
## 進入GDB環境除錯
### 載入編譯選項” –g”
以便在GDB除錯環境中能夠顯示出具體的錯誤位置。
例:
```
g++ filename.cpp –g –o filename
```
在cmake編譯中,可以通過可選項 `-DCMAKE_VERBOSE_MAKEFILE=1` ,具體顯示編譯過程,保證-g選項在編譯過程中使用。
### 載入可執行檔案到GDB中
在執行檔案所在資料夾裡,使用 `gdb` 命令進入到GDB除錯環境中。之後使用 `file filename`
或者使用 `gdb filename` (filename可執行檔名)。
### 對執行檔案進行輸入引數的設定
使用命令 `set args parameter` (parameter為輸入的引數),載入執行所需的引數。通過 `show args` 檢視載入引數的情況。
例:
```
set args /home/hello.png 2016 12
```
使用’show args’後:
```
/home/hello.png 2016 12
```
### GDB內使用make
外部檔案有修改的情況下,直接在GDB環境中使用“make”進行編譯。
### 檔案執行
使用 `r` 即可對檔案進行執行。
### 退出GDB除錯環境
使用 `q` 退出除錯環境。
## 斷點設定
### 斷點設定的方法
- 使用行號:`b linenumber` 例:“b 2017”
- 使用函式名 `b function` 例:“b hello”
- 使用地址 `b *address` 例:“b *0x404”
> 若在不同檔案上打斷點,在行號或函式名前加上檔名和冒號“filename:”。
例:
```
b hello.cpp:hello
b hello.cpp:2017
```
### 條件斷點
在1小點方法後面加入條件,斷點在條件成立時起停止作用。
例:
```
b 12 if x > y // 在x > y情況下,斷點起作用。
```
### 斷點條件更改
將指定斷點號的條件進行修改:
```
condition breakpointnumber expression
```
例:
```
condition 12 if x = y
```
> `condition breakpointnumber` 停止使用條件,斷點不受條件限制使用。
例:
```
condition 12
```
### 斷點資訊檢視
- 檢視所有的斷點資訊: `info b`
- 檢視指定斷點號斷點資訊: `info b number`
### 斷點的使能
- 停止該號斷點。但未刪除: `dis breakpointnumber`
- 使能改號斷點: `enable breakpointnumber`
## 除錯的方式
### 列印變數 `p`
- 列印變數值:`p variable` 例: “p x”
- 列印變數地址:`p &variable` 例: “p &x”
- 列印指標內容:`p *point` 例: “p *pData”
### 單步除錯 `s`
類似於 **step in**
- 單步執行,遇到函式,進入到函式內部執行。
`s number` 進行多步執行
### 單步執行 `n`
類似 **step over** 執行,遇到函式,不進入函式內部,直接執行完函式。
`n number` 進行多步執行
### 繼續執行 `c`
在程式在執行中遇到斷點後,使用 `c` 繼續執行
### 執行完當前函式並打印出資訊 `finish`
在函式內部使用 `finish` ,執行完當前整個函式列印返回資訊
### 設定變數值除錯
`set var variable = x` 將變數設定為x後進行除錯
例:
```
set var tmp = 5
```
將變數 tmp 設定為5,var關鍵詞確保不產生衝突
## 段錯誤的查詢
### 段回溯 `bt`
- 在出現 segment fault 時,使用命令進行段錯誤的檢視。
- 可以得到錯誤坐在的函式。像得到某人家庭地址。
- 也可使用 `where`
### 進入錯誤段
- 在檢視到錯誤的位置之後,使用 `frame number` 進入到該段內部。
- 進入內部之後便可以進行區域性變數的列印除錯。
例:
```
frame 5
```
就進入到段5.
- 切換到上一層段: `up`
- 切換到下一層段: `down`
### 程式碼顯示
- 顯示當前程式碼: `l`
- 顯示當前之前的程式碼: `l -`
- 顯示該行周圍程式碼: `l number`
- 顯示該函數週圍程式碼: `l function` (C++程式碼需要在函式名前加類名,過載函式需要在函式內加引數型別)
- 顯示指定檔案指定行周圍程式碼: `l filename:linenumber`
例:
```
l hello.cpp:1 // 從hello.cpp第一行開始顯示
```
- 顯示指定檔案指定函數週圍程式碼: `l filename:function`
例:
```
l hello.cpp:Util::hello // 顯示hello.cpp檔案下,Util類的函式hello
```
- 顯示起始終止行內程式碼: `l fisrt,last`
例:
```
l 1,30 // 從第0行顯示到第30行的內容
```
---
關於GDB除錯的相關文章:https://www.cnblogs.com/acceptedzhs/p/13161