文章目錄
-
- gcc 編譯
- 啟動 gdb
- 帶參數調試
- 檢視轉儲檔案
- 調試已經運作的程序
- 顯示源代碼
- 列印數組
- 檢視目前執行位置
- 列印字元串
- 修改變量
- 線程的附着和分離
- 查詢所有線程
- 查詢所有線程的堆棧資訊
- 切換線程
- 切換棧幀
- 檢視目前棧幀的棧資訊
gcc 編譯
gcc -g hello.c -o a.out // 編譯并在目标檔案中添加調試資訊
啟動 gdb
- 直接指定檔案啟動
$ gdb a.out
- 先啟動gdb,再載入檔案
$ gdb
(gdb) file a.out // 載入檔案
帶參數調試
參考:Your Program’s Arguments
$ gdb a.out // 先正常啟動gdb調試
(gdb) run [arg1] [arg2] [...] // 以指定參數重新運作目前已經加載的程式
(gdb) run // 采用和上次run相同的參數,或者 set args 指定的參數
檢視轉儲檔案
gdb [exec_file] [core_file]
gdb -c [core_file] [exec_file]
調試已經運作的程序
(gdb) attach process-id // 将程序附加到目前的 gdb
(gdb) detach // 将程序從 gdb 釋放
顯示源代碼
更詳細參考 Printing Source Lines
預設顯示行數為10行。
list // 顯示目前行附近的代碼,如果再次執行list,則接着上次顯示的代碼繼續顯示
list linenum
list function
list first,last // 包括 last 行
list - // Print lines just before the lines last printed.
list + //Print lines just after the lines last printed.
列印數組
- 靜态數組
int x[25];
(gdb) print x // 可以輸出整個數組
- 動态數組
int *x;
x = (int*) malloc(25 * sizeof(int));
(gdb) print x // 列印數組位址
(gdb) print *x // 列印第一個元素
//可以使用下面兩種方法輸出整個數組
(gdb) print *[email protected] // 人工數組 (artificial array)
(gdb) print (int [25]) *x // 強制類型轉換
檢視目前執行位置
使用指令 frame 或 where。
(gdb) frame
#0 unpack (
sha1=0x7fffffffdcf0 "...") at read-tree.c:16
16 unsigned char *sha1 = buffer + len;
(gdb) where
#0 unpack (
sha1=0x7fffffffdcf0 "...") at read-tree.c:16
列印字元串
參考 gdb中三種輸出 print, x, display 的差別
char *a = "hello world";
char b[] = "hello world";
void *c = "hello world";
x 對于變量a, b, c 均能正确顯示:
(gdb) x/s c
0x555555556004: "hello world"
對于變量 a,b,指令 print 能正确顯示,但是對于變量 c 需要強制類型轉換。
(gdb) print/s a
$7 = 0x555555556004 "hello world"
(gdb) print/s c
$5 = (void *) 0x555555556004
(gdb) print/s (char*)c
$7 = 0x555555556004 "hello world"
修改變量
(gdb) set variable i = 10
線程的附着和分離
(gdb) attach pid_num
(gdb) detach
查詢所有線程
info threads
查詢所有線程的堆棧資訊
thread apply all bt
切換線程
thread num
切換棧幀
frame num
檢視目前棧幀的棧資訊
info frame