Linux技術——gdb除錯基礎

readyao發表於2016-04-03

gdb即GNU debugger。
gcc編譯選項-g,這樣生成的目的碼中就新增了除錯資訊。
gcc -g –o hello hello.c
gdb完成的大部分工作都可以用很少的命令集合完成。

啟動gdb
gdb 程式名 [corefile]
corefile是可選的,但能增強gdb的除錯能力。
Linux預設是不生成corefile的,所以需要在使用者profile檔案中新增
ulimit -c unlimited
修改完成之後讓profile檔案及時生效

一個有錯的程式

#include <stdio.h>
void test(void)
{
    int *i = NULL;
    *i = 2;
}

int main(void)
{
    printf(“hello world\n”);
    test();
    return 0;
}

編譯這個程式
gcc –g –o hello hello.c
執行hello
Segmentation fault (core dumped)
程式崩潰
ls
core.3563 hello hello.c
我們看到除了hello檔案和hello.c檔案之外多了core檔案

啟動gdb
gdb hello core
如果你不喜歡一大堆的軟體資訊,可以通過-q引數關閉軟體資訊
gdb -q hello core
0 0x08048394 in test () at hello.c:5
5 *i = 2;
可以看到gdb通過core告訴你,程式哪條語句出現問題

我們做的第一件事就是在gdb環境中執行這個程式
gdb hello
run命令。
Starting program: /home/test/1/hello
hello world

Program received signal SIGSEGV, Segmentation fault.
0x08048394 in test () at hello.c:5
5 *i = 2;
gdb不但能顯示出錯行號,還能說明出錯出現時的記憶體地址,這個也是潛在的有用資訊。

test函式到底出了什麼問題?
where命令,顯示導致段錯誤的執行函式樹
0 0x08048394 in test () at hello.c:5
1 0x080483be in main () at hello.c:11
問題出在hello.c檔案的第5行。

知道函式出錯行的上下文對除錯程式是很有幫助的。
list [m,n],m,n是要顯示包含錯誤首次出現位置的起始行和結尾行。不帶引數的list將顯示附近的10行程式碼

gdb最有用的功能之一就是它可以顯示被除錯程式中任何表示式、變數的值。
print 變數,表示式。
print ‘file’::變數,表示式,‘’是必須的,以便讓gdb知道指的是一個檔名。
print funcname::變數,表示式
(gdb) print i
$1 = (int *) 0x0
顯示指標變數i的值為0。
whatis 命令可以告訴你變數的型別, ptype 告訴你結構的定義。
(gdb) whatis i
type = int *

break命令設定斷點
break linenum
break funcname
break filename:linenum
break filename:funcname

退出gdb,重新進入除錯模式
gdb -q hello
(gdb) break 4
Breakpoint 1 at 0x804838a: file hello.c, line 4.
(gdb) run
Starting program: /home/test/1/hello
hello world

Breakpoint 1, test () at hello.c:4
4 int *i = NULL;
gdb在第4行停止。

continue命令從斷點以後繼續執行。
delete刪除一個斷點。
如果設定了很多斷點,忘記了哪些斷點已經觸發,可以使用info break。
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0804838a in test at hello.c:4
breakpoint already hit 1 time

改變一個變數的值。
set variable varname = value
varname是變數名稱,value是變數的新值。

單步除錯
step命令
當遇到一個函式的時候,step將進入函式,每次執行一條語句,相當於step into
next命令
當遇到一個函式的時候,next將執行整個函式,相當於step over
return [value]命令
停止執行當前函式,將value返回給呼叫者,相當於step return
如果需要重複執行一條命令,不需要每次都鍵入命令,gdb記住了最後一個被執行的命令,只要簡單的按enter鍵就可以重複執行最後的命令

更多詳情參考:
Linux GDB 程式除錯工具使用詳解

相關文章