目錄
一. 環(huán)境介紹
二. gdb指令
1. 啟動調(diào)試
2. 退出調(diào)試
3. 查看代碼?
4. 運(yùn)行程序
?5. 打斷點
6. 查看斷點
7.? 刪除斷點
8.? 逐過程調(diào)試
9. 逐語句調(diào)試
10.? 查看變量
11. 常顯示變量(監(jiān)視)
12. 取消常顯示變量
13. 運(yùn)行到指定行
14. 執(zhí)行完當(dāng)前函數(shù)的剩余部分
15. 執(zhí)行到下一個斷點
16. 關(guān)閉斷點
17. 開啟斷點
18. 不同文件中打斷點
19. 查看局部變量
20. 修改變量的值
21. 查看函數(shù)的調(diào)用堆棧
GDB(GNU調(diào)試器)是一個功能強(qiáng)大的調(diào)試工具,提供了很多命令用于調(diào)試程序。下面我們來看一下如何使用gdb調(diào)試。
一. 環(huán)境介紹
我們要知道我們的程序有兩種,一種是release 還有一種是 debug 版本的,我們的調(diào)試只有咋 debug 版本下才可以調(diào)試,我們只需要在編譯的時候在后面加 -g 選項就是添加調(diào)試信息,也就是debug 版本。
二. gdb指令
下面我們就來看一下我們的 gdb 的指令
測試程序:
#include<stdio.h>
int addToToop(int top)
{
int ret = 0;
for(int i = 1; i <= top; ++i)
ret += i;
return ret;
}
int main()
{
printf("開始調(diào)試\n");
int sum = 20;
int ret = addToToop(sum);
printf("%d\n", ret);
printf("結(jié)束調(diào)試\n");
return 0;
}
1. 啟動調(diào)試
指令:gdb + 可執(zhí)行程序文件名
[lxy@hecs-165234 test9]$ gdb test_debug?
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.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/>...
Reading symbols from /home/lxy/test/test9/test_debug...done.
(gdb)?
?如果變成上面這樣那么就以及成功了
2. 退出調(diào)試
指令:quit / q
(gdb) quit
[lxy@hecs-165234 test9]$?
?
(gdb) q
[lxy@hecs-165234 test9]$?
3. 查看代碼?
指令:list / l? (后面也可以加 數(shù)字 表示查看該行和上下行的部分代碼)
(gdb) l
10?? ?
11?? ? ?return ret;
12?? ?}
13?? ?
14?? ?
15?? ?
16?? ?
17?? ?int main()
18?? ?{
19?? ? ?printf("開始調(diào)試\n");
(gdb) l 0
1?? ?#include<stdio.h>
2?? ?
3?? ?
4?? ?
5?? ?int addToToop(int top)
6?? ?{
7?? ? ?int ret = 0;
8?? ? ?for(int i = 1; i <= top; ++i)
9?? ? ? ?ret += i;
10?? ?
(gdb)?
gdb 會記住上一次的指令,所以我們在查看的時候我們可以 l 0 然后之一回車
指令: l + 函數(shù)名(顯示函數(shù)代碼)
(gdb) l addToToop
1?? ?#include<stdio.h>
2?? ?
3?? ?
4?? ?
5?? ?int addToToop(int top)
6?? ?{
7?? ? ?int ret = 0;
8?? ? ?for(int i = 1; i <= top; ++i)
9?? ? ? ?ret += i;
10?? ?
(gdb)?
11?? ? ?return ret;
12?? ?}
13?? ?
14?? ?
15?? ?
16?? ?
17?? ?int main()
18?? ?{
19?? ? ?printf("開始調(diào)試\n");
20?? ? ?int sum = 20;
(gdb)?
4. 運(yùn)行程序
指令:run / r
(gdb) r
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試
210
結(jié)束調(diào)試
[Inferior 1 (process 7520) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64
(gdb)?
?5. 打斷點
指令:break / b 后面 + 行號
(gdb) break 21
Breakpoint 1 at 0x4005c4: file test.c, line 21.
(gdb) b 22
Breakpoint 2 at 0x4005d1: file test.c, line 22.
(gdb)?
6. 查看斷點
指令:info? breakpoints / info b / i b
(gdb) info breakpoints
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
1 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
2 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
(gdb) info b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
1 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
2 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
1 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
2 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
(gdb)?
?斷點信息查看介紹:
- NUM:斷點編號
- Type:斷點類型
- Disp:....
- Enb:斷點是否有效(可以將斷點設(shè)置為無效)
- 后面的就不做介紹了
7.? 刪除斷點
指令:delete / d + 斷點編號
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
1 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
2 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
(gdb) delete 1
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
2 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
(gdb) d 2
(gdb) i b
No breakpoints or watchpoints.
(gdb)?
8.? 逐過程調(diào)試
指令:next / n
我們先將斷點打到 20 行的位置,然后我們開始逐語句調(diào)試
(gdb) b 20
Breakpoint 3 at 0x4005bd: file test.c, line 20.
(gdb) r
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 3, main () at test.c:20
20?? ? ?int sum = 20;
(gdb) n
21?? ? ?int ret = ?addToToop(sum);
(gdb) n
22?? ? ?printf("%d\n", ret);
(gdb) n
210
23?? ? ?printf("結(jié)束調(diào)試\n");
(gdb) n
結(jié)束調(diào)試
24?? ? ?return 0;
(gdb) n
25?? ?}
(gdb) n
0x00007ffff7a2f555 in __libc_start_main () from /lib64/libc.so.6
(gdb) n
9. 逐語句調(diào)試
指令:step / s
我們還是在 20 行的位置打斷點,然后我們逐語句調(diào)試,我們會進(jìn)入到函數(shù)里面
(gdb) r
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 3, main () at test.c:20
20?? ? ?int sum = 20;
(gdb) s
21?? ? ?int ret = ?addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7?? ? ?int ret = 0;
(gdb) s
8?? ? ?for(int i = 1; i <= top; ++i)
(gdb) s
9?? ? ? ?ret += i;
(gdb)?
10.? 查看變量
指令:print / p + 變量名
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 3, main () at test.c:20
20?? ? ?int sum = 20;
(gdb) print sum
$4 = 0
(gdb) n
21?? ? ?int ret = ?addToToop(sum);
(gdb) print sum
$5 = 20
(gdb) p sum
$6 = 20
(gdb)?
11. 常顯示變量(監(jiān)視)
指令:display + 變量名
我們將斷點打到 21 行(函數(shù)所在行),然后我們 s 進(jìn)入函數(shù), 我們 display 查看變量 i?
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 4, main () at test.c:21
21?? ? ?int ret = ?addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7?? ? ?int ret = 0;
(gdb) n
8?? ? ?for(int i = 1; i <= top; ++i)
(gdb) display i
1: i = 4195472
(gdb) n
9?? ? ? ?ret += i;
1: i = 1
(gdb) n
8?? ? ?for(int i = 1; i <= top; ++i)
1: i = 1
(gdb) n
9?? ? ? ?ret += i;
1: i = 2
(gdb)?
我們的常顯示變量的前面還有一個數(shù)字,這個就是常顯示變量的 編號?
12. 取消常顯示變量
指令:undisplay + 常顯示變量的編號
還是根據(jù)上面的 顯示 i 變量,然后我們?nèi)∠@示 i 變量?
1: i = 2
(gdb) undisplay 1
(gdb)?
13. 運(yùn)行到指定行
這次我們在進(jìn)入到 函數(shù)中去 然后我們使用指令到指定行
指令:until?+ 行號
開始調(diào)試
Breakpoint 4, main () at test.c:21
21?? ? ?int ret = ?addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7?? ? ?int ret = 0;
(gdb) s
8?? ? ?for(int i = 1; i <= top; ++i)
(gdb) until 11
addToToop (top=20) at test.c:11
11?? ? ?return ret;
(gdb)?
?
14. 執(zhí)行完當(dāng)前函數(shù)的剩余部分
我們繼續(xù)到 該函數(shù)中去
指令:finish(執(zhí)行完當(dāng)前函數(shù)剩余的所有代碼,并且在下一個函數(shù)執(zhí)行前一行停止)
(gdb) run
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 4, main () at test.c:21
21?? ? ?int ret = ?addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7?? ? ?int ret = 0;
(gdb) s
8?? ? ?for(int i = 1; i <= top; ++i)
(gdb) finish
Run till exit from #0 ?addToToop (top=20) at test.c:8
0x00000000004005ce in main () at test.c:21
21?? ? ?int ret = ?addToToop(sum);
Value returned is $8 = 210
(gdb)?
15. 執(zhí)行到下一個斷點
我們多打幾個斷點 20 21 22 ,然后我們 continue
指令:continue
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
4 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
?? ?breakpoint already hit 1 time
(gdb) b 20
Breakpoint 5 at 0x4005bd: file test.c, line 20.
(gdb) b 22
Breakpoint 6 at 0x4005d1: file test.c, line 22.
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
4 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
?? ?breakpoint already hit 1 time
5 ? ? ? breakpoint ? ? keep y ? 0x00000000004005bd in main at test.c:20
6 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22斷點打好了
(gdb) run
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 5, main () at test.c:20
20?? ? ?int sum = 20;
(gdb) continue
Continuing.Breakpoint 4, main () at test.c:21
21?? ? ?int ret = ?addToToop(sum);
(gdb) continue
Continuing.Breakpoint 6, main () at test.c:22
22?? ? ?printf("%d\n", ret);
(gdb) continue
Continuing.
210
結(jié)束調(diào)試
[Inferior 1 (process 7634) exited normally]
(gdb)?
16. 關(guān)閉斷點
指令:disable + 斷點編號
我們現(xiàn)在有 20 21 22 三個斷點,我們現(xiàn)在關(guān)閉掉 21 我們 i b 查看一下
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
4 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
?? ?breakpoint already hit 1 time
5 ? ? ? breakpoint ? ? keep y ? 0x00000000004005bd in main at test.c:20
?? ?breakpoint already hit 1 time
6 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
?? ?breakpoint already hit 1 time
(gdb) disable 4
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
4 ? ? ? breakpoint ? ? keep n ? 0x00000000004005c4 in main at test.c:21
?? ?breakpoint already hit 1 time
5 ? ? ? breakpoint ? ? keep y ? 0x00000000004005bd in main at test.c:20
?? ?breakpoint already hit 1 time
6 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
?? ?breakpoint already hit 1 time
(gdb)?
17. 開啟斷點
指令:enable + 斷點編號
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
4 ? ? ? breakpoint ? ? keep n ? 0x00000000004005c4 in main at test.c:21
?? ?breakpoint already hit 1 time
5 ? ? ? breakpoint ? ? keep y ? 0x00000000004005bd in main at test.c:20
?? ?breakpoint already hit 1 time
6 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
?? ?breakpoint already hit 1 time
(gdb) enable 4
(gdb) i b
Num ? ? Type ? ? ? ? ? Disp Enb Address ? ? ? ? ? ?What
4 ? ? ? breakpoint ? ? keep y ? 0x00000000004005c4 in main at test.c:21
?? ?breakpoint already hit 1 time
5 ? ? ? breakpoint ? ? keep y ? 0x00000000004005bd in main at test.c:20
?? ?breakpoint already hit 1 time
6 ? ? ? breakpoint ? ? keep y ? 0x00000000004005d1 in main at test.c:22
?? ?breakpoint already hit 1 time
(gdb)?
18. 不同文件中打斷點
指令:break / b + 文件名 + :+ 行號
這里就不做演示了....(沒有多個文件)
19. 查看局部變量
指令:info locals / i locals
我們打斷點到 22?行,然后我們查看主函數(shù)里面的變量
(gdb) run
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 7, main () at test.c:22
22?? ? ?printf("%d\n", ret);
(gdb) info locals
sum = 20
ret = 210
(gdb) i locals
sum = 20
ret = 210
(gdb)?
20. 修改變量的值
指令:set var + (變量名 =?值)
我們到 21 行里面的函數(shù)里面,然后直接修改i的值為200,然后查看 i 的值
(gdb) run?
Starting program: /home/lxy/test/test9/test_debug?
開始調(diào)試Breakpoint 8, main () at test.c:21
21?? ? ?int ret = ?addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7?? ? ?int ret = 0;
(gdb) s
8?? ? ?for(int i = 1; i <= top; ++i)
(gdb) p i
$13 = 4195472
(gdb) set var i = 200
(gdb) p i
$14 = 200
(gdb)?
21. 查看函數(shù)的調(diào)用堆棧
指令:bt
我們先到 mian 函數(shù)里面查看調(diào)用堆棧,然后在進(jìn)入到我們自己寫的函數(shù)的里面繼續(xù)查看調(diào)用堆棧,然后我們在 finish 結(jié)束掉我們自己的函數(shù),然后查看調(diào)用堆棧
(gdb) run?
Starting program: /home/lxy/test/test9/test_debug?Breakpoint 9, main () at test.c:19
19?? ? ?printf("開始調(diào)試\n");
(gdb) bt
#0 ?main () at test.c:19
(gdb) s
開始調(diào)試
20?? ? ?int sum = 20;
(gdb) s
21?? ? ?int ret = ?addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7?? ? ?int ret = 0;
(gdb) s
8?? ? ?for(int i = 1; i <= top; ++i)
(gdb) bt
#0 ?addToToop (top=20) at test.c:8
#1 ?0x00000000004005ce in main () at test.c:21
(gdb) s
9?? ? ? ?ret += i;
(gdb) finish
Run till exit from #0 ?addToToop (top=20) at test.c:9
0x00000000004005ce in main () at test.c:21
21?? ? ?int ret = ?addToToop(sum);
Value returned is $15 = 210
(gdb) bt
#0 ?0x00000000004005ce in main () at test.c:21
(gdb)?文章來源:http://www.zghlxwxcb.cn/news/detail-550176.html
上面的就是 gdb 里面常用的命令,我們下期見~?文章來源地址http://www.zghlxwxcb.cn/news/detail-550176.html
到了這里,關(guān)于調(diào)試工具_(dá)gdb使用教程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!