What is gdb
GDB的全稱是“GNU symbolic debugger”,從名稱可以看出,它屬於 GNU 計劃(同時誕生的還有 GCC、Emacs 等),是 Linux 下常用的程序調試器。當下的 GDB 支持調試多種編程語言編寫的程序,包括 C、C++、Go、Objective-C、OpenCL、Ada 等。實際場景中,GDB 更常用來調試 C 和 C++ 程序。
gdb的安裝
#install gdb $ sudo apt-get install -y gdb #print gdb's version $ gdb -v
gdb的簡單調試
以下面一段代碼main.c爲例子
#include <stdio.h> int main () { unsigned long long int n, sum; n = 1; sum = 0; while (n <= 100) { sum = sum + n; n = n + 1; } return 0; }
啓動gdb
# 編譯,-g參數打開gdb調試功能 $ gcc main.c -o main.exe -g $ gdb main.exe GNU gdb (GDB) 8.0.1 Copyright (C) 2017 Free Software Foundation, Inc. ...... (gdb)
注意,該指令在啓動 GDB 的同時,會打印出一堆免責條款。通過添加 --silent(或者 -q、--quiet)選項,可將比部分信息屏蔽掉:
$ gdb main.exe --silent Reading symbols from main.exe...(no debugging symbols found)...done. (gdb)
gdb常用調試命令
調試指令 作 用
(gdb) break xxx
(gdb) b xxx 在源代碼指定的某一行設置斷點,其中 xxx 用於指定具體打斷點的位置。
(gdb) run
(gdb) r 執行被調試的程序,其會自動在第一個斷點處暫停執行。
(gdb) continue
(gdb) c 當程序在某一斷點處停止運行後,使用該指令可以繼續執行,直至遇到下一個斷點或者程序結束。
(gdb) next
(gdb) n 令程序一行代碼一行代碼的執行。
(gdb) print xxx
(gdb) p xxx 打印指定變量的值,其中 xxx 指的就是某一變量名。
(gdb) list
(gdb) l 顯示源程序代碼的內容,包括各行代碼所在的行號。
(gdb) quit
(gdb) q 終止調試。
如上所示,每一個指令既可以使用全拼,也可以使用其首字母表示。另外,表 1 中羅列的指令僅是冰山一角,GDB 還提供有大量的選項,可以通過 help 選項來查看。
下面以 main.exe 可執行程序爲例,接下來爲演示部分選項的功能和用法
(gdb) l <-- 顯示帶行號的源代碼 1 #include <stdio.h> 2 int main () 3 { 4 unsigned long long int n, sum; 5 n = 1; 6 sum = 0; 7 while (n <= 100) 8 { 9 sum = sum + n; 10 n = n + 1; (gdb) <-- 默認情況下,l 選項只顯示 10 行源代碼,如果查看後續代碼,安裝 Enter 回車即可 11 } 12 return 0; 13 } (gdb) b 7 <-- 在第 7 行源代碼處打斷點 Breakpoint 1 at 0x400504: file main.c, line 7. (gdb) r <-- 運行程序,遇到斷點停止 Starting program: /home/mozhiyan/demo1/main.exe Breakpoint 1, main () at main.c:7 7 while (n <= 100) Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7.x86_64 (gdb) p n <-- 查看代碼中變量 n 的值 $1 = 1 <-- 當前 n 的值爲 1,$1 表示該變量所在存儲區的名稱 (gdb) b 12 <-- 在程序第 12 行處打斷點 Breakpoint 2 at 0x40051a: file main.c, line 12. (gdb) c <-- 繼續執行程序 Continuing. Breakpoint 2, main () at main.c:12 12 return 0; (gdb) p n <-- 查看當前 n 變量的值 $2 = 101 <-- 當前 n 的值爲 101 (gdb) q <-- 退出調試 A debugging session is active. Inferior 1 [process 3080] will be killed. Quit anyway? (y or n) y <-- 確實是否退出調試,y 爲退出,n 爲不退出 [root@bogon demo]#