概述
GDB是GNU發(fā)布的一個(gè)調(diào)試工具掀泳。gdb 是基于UNIX/Linux 命令行的哆档,功能強(qiáng)大,可與windows平臺(tái)的visual studio 媲美。
基本命令
GDB的命令非常多鬼店,但我們只要掌握幾個(gè)常見(jiàn)的,就可以滿足日城辏基本程序的調(diào)試需求妇智。
命令 | 解釋 | 示例 |
---|---|---|
file <文件名> | 加載被調(diào)試的可執(zhí)行文件 如果執(zhí)行g(shù)db與被調(diào)試的程序不在同個(gè)目錄滥玷,則需要帶上路徑 |
(gdb) file gdb_sample |
l <行號(hào)> | List 的縮寫,打印源碼 在gcc/g++ 編譯程序時(shí)巍棱,需要加上-g 選項(xiàng) |
(gdb) l 1 |
r | Run 的縮寫惑畴,運(yùn)行程序 | (gdb) r |
c | Continue 的縮寫,繼續(xù)執(zhí)行程序航徙,直到下一個(gè)斷點(diǎn)或程序結(jié)束 | (gdb) c |
b <行號(hào)> b <函數(shù)名稱> |
Breakpoint 的縮寫如贷,設(shè)置斷點(diǎn) | (gdb) b 8 (gdb) b main |
d <斷點(diǎn)編號(hào)> | Delete 的縮寫,刪除斷點(diǎn) | (gdb) d 2 |
s | Step Into (單步跟蹤進(jìn)入) 執(zhí)行一行源程序代碼到踏,如果此行代碼有函數(shù)調(diào)用杠袱,則進(jìn)入該函數(shù) |
(gdb) s |
n | Step Over (單步跟蹤) 執(zhí)行一行源程序代碼,如果此行代碼有函數(shù)調(diào)用窝稿,也一并執(zhí)行 |
(gdb) n |
p <變量名稱> | Print 的縮寫楣富, 打印變量的值 | (gdb) p i |
bt | Backtrace 的縮寫,查看堆棧信息 | (gdb) bt |
q | Quit 的縮寫伴榔,退出gdb 調(diào)試環(huán)境 | (gdb) q |
help <命令名稱> | 可以查看各個(gè)命令的用法 | (gdb) help r |
舉例
先看一個(gè)簡(jiǎn)單的程序
#include <stdio.h>
int sum(int n)
{
int sum=0, i;
for (i=0; i<n; ++i)
{
sum+=i;
}
return sum;
}
int main(int argc, char ** argv)
{
int i=1;
++i;
int result=0;
result=sum(i);
printf("sum[%d]\n", result);
return 0;
}
將上面代碼保存到 gdb_sample.c
文件纹蝴,然后用 gcc 編譯:
gcc gdb_sample.c -g -o gdb_sample
上面的命令,用參數(shù) -g
將源代碼信息編譯到可執(zhí)行文件中踪少,如果不指定塘安,將無(wú)法在 gdb 里面查看代碼,可以看看使用 -g
和不使用秉馏,編譯后可執(zhí)行文件的大邪业:
[huanghaibin@huanghaibin 17:10:17 ] gcc gdb_sample.c -g -o gdb_sample
[huanghaibin@huanghaibin 17:19:35 ] gcc gdb_sample.c -o gdb_sample_2
[huanghaibin@huanghaibin 17:19:54 ] ll gdb_sample gdb_sample_2
-rwxrwxr-x 1 huanghaibin 8.4K 3月 9 17:19 gdb_sample_2
-rwxrwxr-x 1 huanghaibin 9.7K 3月 9 17:19 gdb_sample
可以用 gdb gdb_sample
直接進(jìn)入調(diào)試環(huán)境,也可以先啟動(dòng)gdb
萝究,再打開可執(zhí)行文件:
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file gdb_sample
Reading symbols from /data1/hellerhuang/test_c/gdb_sample...done.
(gdb)
上面表示可執(zhí)行文件已經(jīng)加載成功免都,(gdb)
是gdb內(nèi)部命令引導(dǎo)符,等待用戶輸入命令
下面使用l
命令來(lái)查看源碼帆竹,可以指定行號(hào)绕娘,回車可以繼續(xù)往下查看:
(gdb) l 1
1 /*======================================================================
2 @file gdb_sample.c
3 @brief
4 @author huanghaibin
5 @version 1.0
6 @date 2018-03-09
7 @copyright Copyright (c) 2015 Tencent Inc. All Rights Reserved.
8 ======================================================================*/
9
10 #include <stdio.h>
(gdb)
11
12 int sum(int n)
13 {
14 int sum=0, i;
15 for (i=0; i<n; ++i)
16 {
17 sum+=i;
18 }
19 return sum;
20 }
(gdb)
21
22 int main(int argc, char ** argv)
23 {
24 int i=1;
25 ++i;
26
27 int result=0;
28 result=sum(i);
29
30 printf("sum[%d]\n", result);
(gdb)
31 return 0;
32 }
33
(gdb)
下面使用r
命令執(zhí)行程序,因?yàn)闆](méi)有設(shè)置斷點(diǎn)栽连,所以程序執(zhí)行到程序結(jié)束:
Starting program: /data1/hellerhuang/test_c/gdb_sample
sum[1]
[Inferior 1 (process 6401) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.tl2.2.x86_64
(gdb)
下面使用b
設(shè)置斷點(diǎn)险领,在24行int i=1;
設(shè)置斷點(diǎn),后執(zhí)行r
秒紧,再進(jìn)入單步調(diào)試n s
:
(gdb) b 24
Breakpoint 1 at 0x40056d: file gdb_sample.c, line 24. // 設(shè)置斷點(diǎn)
(gdb) r
Starting program: /data1/hellerhuang/test_c/gdb_sample
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:24 // 程序中斷在24行
24 int i=1;
(gdb) n
25 ++i;
(gdb) s
27 int result=0;
(gdb)
上面程序先執(zhí)行到斷點(diǎn)處(24行)绢陌,然后單步調(diào)試,對(duì)于非函數(shù)熔恢,n
和 s
執(zhí)行結(jié)果一樣
下面在28行設(shè)置第二個(gè)斷點(diǎn)脐湾,用明令c
直接運(yùn)行到第二處斷點(diǎn),對(duì)比n
和 s
執(zhí)行函數(shù)的結(jié)果:
(gdb) b 28 // 設(shè)置第二處斷點(diǎn)
Breakpoint 2 at 0x40057f: file gdb_sample.c, line 28.
(gdb) c // 直接運(yùn)行到第二個(gè)斷點(diǎn)
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28 result=sum(i);
(gdb) n // 執(zhí)行整個(gè)函數(shù)
30 printf("sum[%d]\n", result);
(gdb) p result // 打印變量
$1 = 1
(gdb) r // 重新運(yùn)行程序
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /data1/hellerhuang/test_c/gdb_sample
Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:24
24 int i=1;
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28 result=sum(i);
(gdb) s // 單步調(diào)試進(jìn)入函數(shù)
sum (n=2) at gdb_sample.c:14
14 int sum=0, i;
(gdb) bt // 查看堆棧信息
#0 sum (n=2) at gdb_sample.c:14
#1 0x0000000000400589 in main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
(gdb) finish
Run till exit from #0 sum (n=2) at gdb_sample.c:14
0x0000000000400589 in main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28 result=sum(i);
Value returned is $2 = 1
(gdb) n
30 printf("sum[%d]\n", result);
(gdb) p result
$3 = 1
(gdb) q
A debugging session is active.
Inferior 1 [process 10635] will be killed.
Quit anyway? (y or n) y
上面bt
可查看程序的堆棧信息叙淌,然后通過(guò)finish
命令執(zhí)行完該函數(shù)秤掌,最后用命令q
退出調(diào)試愁铺。