C編譯: 使用gdb除錯
gdb是 的簡稱。它是一款UNIX平臺的偵錯程式(debugger),可用於為C, C++, Objective-C, Java, Fortran等程式debug。
在gdb中,你可以透過設定 斷點(break point)來控制程式執行的進度,並檢視斷點時的變數和函式呼叫狀況,從而發現可能的問題。在許多IDE中,gdb擁有圖形化介面。
這裡主要介紹gdb的命令列使用,並以C程式為例。測試使用的計算機是Mac OS系統。
啟動gdb
下面的有兩個C檔案。(並沒有bug。我們使用gdb來檢視程式執行的細節)
程式的一個為 test.c,其中有主程式 main()。 mean.c程式中定義了 mean()函式,並在main()中呼叫。
test.c
#define ARRAYSIZE 4float mean(float, float);int main() { int i; float a=4.5; float b=5.5; float rlt=0.0; float array_a[ARRAYSIZE]={1.0, 2.0, 3.0, 4.0}; float array_b[ARRAYSIZE]={4.0, 3.0, 2.0, 1.0}; float array_rlt[ARRAYSIZE]; for(i = 0; i < ARRAYSIZE - 1; i++) { array_rlt[i] = mean(array_a[i], array_b[i]); } rlt = mean(a, b); return 0; }
mean.c
float mean(float a, float b) { return (a + b)/2.0; }
使用gcc同時編譯上面兩個程式。為了使用gdb對進行除錯,必須使用 -g選項(在編譯時生成debugging資訊):
$gcc -g -o test test.c mean.c
生成main可執行檔案。
(如有必要,使用:
$chmod +x test
來增加使用者的執行許可權。)
進入gdb,準備除錯程式:
$gdb test
進入gdb的互動命令列。
顯示程式
我們可以直接顯示某一行的程式,比如檢視第9行程式:
(gdb) list 9
將顯示以第9行為中心,總共10行的程式。我們實際上編譯了兩個檔案,在沒有說明的情況下,預設為主程式檔案test.c:
4 5 int main() 6 { 7 int i; 8 float a=4.5; 9 float b=5.5; 10 float rlt=0.0; 11 12 float array_a[ARRAYSIZE]={1.0, 2.0, 3.0, 4.0}; 13 float array_b[ARRAYSIZE]={4.0, 3.0, 2.0, 1.0};
如果要檢視mean.c中的內容,需要說明檔名:
(gdb) list mean.c:1
可以具體說明所要列出的程式行的範圍:
(gdb) list 5, 15
即顯示5-15行的程式。
顯示某個函式,比如:
(gdb) list mean
設定斷點
我們可以執行程式:
(gdb) run
程式正常結束。
執行程式並沒有什麼有趣的地方。gdb的主要功能在於能讓程式在中途暫停。
斷點(break point)是程式執行中的一個位置。在gdb中,當程式執行到該位置時,程式會暫停,我們可以檢視此時的程式狀況,比如變數的值。
我們可以在程式的某一行設定斷點,比如:
(gdb) break 16
將在test.c的第16行設定斷點。
你可以檢視自己設定的斷點:
(gdb) info break
每個斷點有一個識別序號。我們可以根據序號刪除某個斷點:
(gdb) delete 1
也可以刪除所有斷點:
(gdb) delete breakpoints
檢視斷點
設定斷點,並使用run執行程式,程式將執行到16行時暫停。gdb顯示:
Breakpoint 1, main () at test.c:16 16 for(i = 0; i < ARRAYSIZE - 1; i++) {
檢視斷點所在行:
(gdb) list
檢視斷點處的某個變數值:
(gdb) print a
(gdb) print array_a
檢視所有的區域性變數:
(gdb) info local
檢視此時的棧狀態 (反映了函式呼叫,見 Linux從程式到程式):
(gdb) info stack
可以更改變數的值。
(gdb) set var a=0.0
(gdb) set var array_a={0.0, 0.0, 1.0, 1.0}
當程式繼續執行時,將使用更改後的值。
如果我們將斷點設定在:
(gdb) break mean.c:2
此時棧中有兩個a,一個屬於main(),一個屬於mean()。我們可以用function::variable的方式區分:
(gdb) print mean::a
執行控制
讓程式從斷點開始,再多執行一行:
(gdb) step
也可以使用下面命令,從斷點恢復執行,直到下一個斷點:
(gdb) continue
使用 run重新開始執行。
幫助
你可以透過gdb的幫助學到更多:
(gdb) help
或者更具體的命令:
(gdb) help info
退出
使用下面命令退出gdb:
(gdb) quit
debug
下面是一個有bug的C程式,demo.c
#include <stdio.h>struct node { int element; }; typedef struct node *PNode;int main() { int i; PNode np=NULL; for (i=0; i<10; i++) { printf("Hello World!"); } printf("%d \n", np->element); }
程式可以成功編譯,但執行將返回:
Segmentation fault
可以使用gdb來查詢問題。
Updata:
經 提醒: gdb命令可以只輸入首字母的縮寫,比如c代表continue,b代表break,q代表quit。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31543790/viewspace-2663158/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 嵌入式GDB除錯Linux C程式或交叉編譯(開發板)除錯LinuxC程式編譯
- C語言——gdb除錯C語言除錯
- vscode+C 編譯除錯VSCode編譯除錯
- GDB 除錯 Mysql 實戰(一)原始碼編譯安裝除錯MySql原始碼編譯
- Linux核心使用gdb除錯Linux除錯
- GDB除錯使用記錄除錯
- Ubuntu中用VScode編譯除錯C\C++UbuntuVSCode編譯除錯C++
- 在Linux上使用vscode編譯除錯C/C++程式碼LinuxVSCode編譯除錯C++
- gdb除錯除錯
- Linux中使用GDB除錯程式Linux除錯
- c/c++ gdb 除錯帶引數的程式C++除錯
- GDB除錯指令除錯
- GDB除錯基礎使用方法除錯
- OpenHarmony系統使用gdb除錯init除錯
- GDB交叉編譯編譯
- 在windows上配置vs code編譯除錯c/c++Windows編譯除錯C++
- GDB 除錯程式碼除錯
- gdb除錯多程序除錯
- gdb除錯總結除錯
- gdb除錯快速上手除錯
- 使用GDB除錯Android Native 層程式碼除錯Android
- 在MacOS上使用gdb(cgdb)除錯Golang程式Mac除錯Golang
- 介紹 GDB 除錯 Go除錯Go
- 用GDB除錯程式(六)除錯
- GDB除錯命令詳解除錯
- gdb高階除錯命令高階除錯
- gdb除錯coredump檔案除錯
- 【譯】使用可編輯表示式改進除錯除錯
- 在海思晶片上使用GDB遠端除錯晶片除錯
- gdb除錯傳入引數除錯
- 實現交叉編譯gdb和gdbserver(gdb-7.6)編譯Server
- # Xcode 編譯器除錯命令(所有)XCode編譯除錯
- gdb除錯正在執行的程式除錯
- NASM 與 GDB 簡易除錯指南ASM除錯
- Linux—gdb除錯簡單實現Linux除錯
- 編譯除錯Net6原始碼編譯除錯原始碼
- linux環境下vscode 中C/C++編譯及除錯環境的搭建LinuxVSCodeC++編譯除錯
- [docker+gdb] 除錯 PHP 原始碼,看 strval 函式 C 實現Docker除錯PHP原始碼函式