【Linux】一步一步学Linux——gdb命令(258)
00. 目錄
文章目錄
- 00. 目錄
- 01. 命令概述
- 02. 命令格式
- 03. 常用選項
- 04. 參考示例
- 05. 附錄
01. 命令概述
gdb命令包含在GNU的gcc開發套件中,是功能強大的程序調試器。
gdb中的命令很多,但我們只需掌握其中十個左右的命令,就大致可以完成日常的基本的程序調試工作。
| file<文件名> | 加載被調試的可執行程序文件。 因為一般都在被調試程序所在目錄下執行GDB,因而文本名不需要帶路徑。 | (gdb) file test |
| r | Run的簡寫,運行被調試的程序。 如果此前沒有下過斷點,則執行完整個程序;如果有斷點,則程序暫停在第一個可用斷點處。 | (gdb) r |
| c | Continue的簡寫,繼續執行被調試程序,直至下一個斷點或程序結束。 | (gdb) c |
| b <行號> b <函數名稱> b *<函數名稱> b *<代碼地址> d [編號] | b: Breakpoint的簡寫,設置斷點。兩可以使用“行號”“函數名稱”“執行地址”等方式指定斷點位置。 其中在函數名稱前面加“*”符號表示將斷點設置在“由編譯器生成的prolog代碼處”。如果不了解匯編,可以不予理會此用法。 d: Delete breakpoint的簡寫,刪除指定編號的某個斷點,或刪除所有斷點。斷點編號從1開始遞增。 | (gdb) b 8 (gdb) b main (gdb) b *main (gdb) b *0x804835c (gdb) d |
| s, n | s: 執行一行源程序代碼,如果此行代碼中有函數調用,則進入該函數; n: 執行一行源程序代碼,此行代碼中的函數調用也一并執行。 s 相當于其它調試器中的“Step Into (單步跟蹤進入)”; n 相當于其它調試器中的“Step Over (單步跟蹤)”。 這兩個命令必須在有源代碼調試信息的情況下才可以使用(GCC編譯時使用“-g”參數)。 | (gdb) s (gdb) n |
| si, ni | si命令類似于s命令,ni命令類似于n命令。所不同的是,這兩個命令(si/ni)所針對的是匯編指令,而s/n針對的是源代碼。 | (gdb) si (gdb) ni |
| p <變量名稱> | Print的簡寫,顯示指定變量(臨時變量或全局變量)的值。 | (gdb) p i (gdb) p nGlobalVar |
| display … undisplay <編號> | display,設置程序中斷后欲顯示的數據及其格式。 例如,如果希望每次程序中斷后可以看到即將被執行的下一條匯編指令,可以使用命令 “display /i $pc” 其中 $pc 代表當前匯編指令,/i 表示以十六進行顯示。當需要關心匯編代碼時,此命令相當有用。 undispaly,取消先前的display設置,編號從1開始遞增。 | (gdb) display /i $pc (gdb) undisplay 1 |
| i | info的簡寫,用于顯示各類信息,詳情請查閱“help i”。 | (gdb) i r |
| q | Quit的簡寫,退出GDB調試環境。 | (gdb) q |
| help [命令名稱] | GDB幫助命令,提供對GDB名種命令的解釋說明。 如果指定了“命令名稱”參數,則顯示該命令的詳細說明;如果沒有指定參數,則分類顯示所有GDB命令,供用戶進一步瀏覽和查詢。 | (gdb) help |
02. 命令格式
用法:gdb [選項] [參數]03. 常用選項
-cd 設置工作目錄 -q 安靜模式,不打印介紹信息和版本信息 -d 添加文件查找路徑 -x 從指定文件中執行GDB指令 -s 設置讀取的符號表文件常用命令
file <文件名> 加載被調試的可執行程序文件 run 重新開始運行文件 start 單步執行,運行程序,停在第一執行語句 list 查看原代碼,簡寫l set 設置變量的值 next 單步調試(逐過程,函數直接執行),簡寫n step 單步調試(逐語句:跳入自定義函數內部執行),簡寫s backtrace 查看函數的調用的棧幀和層級關系,簡寫bt frame 切換函數的棧幀,簡寫f info 查看函數內部局部變量的數值,簡寫i finish 結束當前函數,返回到函數調用點 continue 繼續運行,簡寫c print 打印值及地址,簡寫p quit 退出gdb,簡寫q04. 參考示例
4.1 參考程序
#include <stdio.h> #include <string.h> #include <stdlib.h> int fun(int number) {printf("fun....number = %d\n", number);return 0; }int main(int argc, char **argv) {int i = 0;//argc: 傳遞參數的個數//argv: 參數列表for (i = 0; i < argc; i++){printf("argv[%d]: %s\n", i, argv[i]); }//循環for (i = 0; i < 100; i++){printf("i = %d\n", i); }//調用函數fun(10);return 0; }4.2 生成包含調試信息的可執行文件
[deng@localhost tmp]$ gcc -g test.c -o test [deng@localhost tmp]$4.3 啟動GDB
[deng@localhost tmp]$ gdb test GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.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/deng/tmp/test...done. (gdb)4.4 載入調試程序
(gdb) file test Load new symbol table from "/home/deng/tmp/test"? (y or n) y Reading symbols from /home/deng/tmp/test...done. (gdb)4.5 直接執行到程序結束
(gdb) r Starting program: /home/deng/tmp/test argv[0]: /home/deng/tmp/test i = 0 i = 1 i = 2 i = 3 i = 4 i = 5下面使用“r”命令執行(Run)被調試文件,因為尚未設置任何斷點,將直接執行到程序結束
4.6 設置斷點
[deng@localhost tmp]$ gdb test GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.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/deng/tmp/test...done. (gdb) b main Breakpoint 1 at 0x400552: file test.c, line 13. (gdb)使用“b”命令在 main 函數開頭設置一個斷點(Breakpoint)
上面最后一行提示已經成功設置斷點,并給出了該斷點信息:在源文件 test.c 第13行處設置斷點;這是本程序的第一個斷點(序號為1);斷點處的代碼地址為 0x400552(此值可能僅在本次調試過程中有效)?;剡^頭去看源代碼,第13行中的代碼為“int i = 0”,恰好是 main 函數中的第一個可執行語句(前面的“int n;”為變量定義語句,并非可執行語句)。
再次使用“r”命令執行(Run)被調試程序
(gdb) r Starting program: /home/deng/tmp/test Breakpoint 1, main (argc=1, argv=0x7fffffffe408) at test.c:13 13 int i = 0; Missing separate debuginfos, use: debuginfo-install glibc-2.17-222.el7.x86_64 (gdb)4.7 單步執行語句
(gdb) n 17 for (i = 0; i < argc; i++) (gdb)4.8 查看變量的值
(gdb) p i $1 = 0 (gdb)4.9 設置斷點行號或者函數名
(gdb) b 25 Breakpoint 2 at 0x4005a2: file test.c, line 25. (gdb) b fun Breakpoint 3 at 0x400528: file test.c, line 7. (gdb)4.10 執行到下一個斷點處
(gdb) c Continuing. argv[0]: /home/deng/tmp/testBreakpoint 2, main (argc=1, argv=0x7fffffffe408) at test.c:25 25 printf("i = %d\n", i); (gdb)4.11 設置顯示變量的值
(gdb) display i 1: i = 1 (gdb) n i = 1 23 for (i = 0; i < 100; i++) 1: i = 1 (gdb)4.12 每次中斷都將顯示下一條匯編指令
(gdb) si 0x00000000004005a5 25 printf("i = %d\n", i); 1: i = 2 (gdb) si 0x00000000004005a7 25 printf("i = %d\n", i); 1: i = 2 (gdb)并且以后程序每次中斷都將顯示下一條匯編指定(“si”命令用于執行一條匯編代碼——區別于“s”執行一行C代碼)
4.13 查看斷點信息
(gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400552 in main at test.c:13breakpoint already hit 1 time 2 breakpoint keep y 0x00000000004005a2 in main at test.c:25breakpoint already hit 3 times 3 breakpoint keep y 0x0000000000400528 in fun at test.c:7 (gdb)4.14 刪除斷點
(gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000400552 in main at test.c:13breakpoint already hit 1 time 2 breakpoint keep y 0x00000000004005a2 in main at test.c:25breakpoint already hit 3 times 3 breakpoint keep y 0x0000000000400528 in fun at test.c:7 (gdb) d 1 (gdb) info break Num Type Disp Enb Address What 2 breakpoint keep y 0x00000000004005a2 in main at test.c:25breakpoint already hit 3 times 3 breakpoint keep y 0x0000000000400528 in fun at test.c:7 (gdb)4.15 顯示寄存器的值
(gdb) i r rax 0x2 2 rbx 0x0 0 rcx 0x5 5 rdx 0x7ffff7dd6a00 140737351870976 rsi 0x2 2 rdi 0x0 0 rbp 0x7fffffffe320 0x7fffffffe320 rsp 0x7fffffffe300 0x7fffffffe300 r8 0x0 0 r9 0x7ffff7a5b16d 140737348219245 r10 0x22 34 r11 0x246 582 r12 0x400430 4195376 r13 0x7fffffffe400 140737488348160 r14 0x0 0 r15 0x0 0 rip 0x4005a7 0x4005a7 <main+100> eflags 0x297 [ CF PF AF SF IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb)4.16 顯示具體寄存器的值
(gdb) i r rax rax 0x2 2 (gdb)4.17 退出GDB
(gdb) quit A debugging session is active.Inferior 1 [process 77076] will be killed.Quit anyway? (y or n) y [deng@localhost tmp]$05. 附錄
參考:【Linux】一步一步學Linux系列教程匯總
總結
以上是生活随笔為你收集整理的【Linux】一步一步学Linux——gdb命令(258)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux】一步一步学Linux——g
- 下一篇: 【Linux】一步一步学Linux——m