歡迎光臨
每天分享高質量文章

三步上手 GDB | Linux 中國

除錯 C 程式,曾讓我很困擾。然而當我之前在寫我的作業系統時,我有很多的 Bug 需要除錯。我很幸運的使用上了 qemu 模擬器,它允許我將除錯器附加到我的作業系統。這個除錯器就是 gdb。
— Julia Evans


本文導航
編譯自 | https://jvns.ca/blog/2014/02/10/three-steps-to-learning-gdb/ 
 作者 | Julia Evans
 譯者 | Torival

除錯 C 程式,曾讓我很困擾。然而當我之前在寫我的作業系統[1]時,我有很多的 Bug 需要除錯。我很幸運的使用上了 qemu 模擬器,它允許我將除錯器附加到我的作業系統。這個除錯器就是 gdb

我得解釋一下,你可以使用 gdb 先做一些小事情,因為我發現初學它的時候真的很混亂。我們接下來會在一個小程式中,設定斷點,檢視記憶體。

1、 設斷點

如果你曾經使用過除錯器,那你可能已經會設定斷點了。

下麵是一個我們要除錯的程式(雖然沒有任何 Bug):

  1. #include <stdio.h>

  2. void do_thing() {

  3.    printf("Hi!\n");

  4. }

  5. int main() {

  6.    do_thing();

  7. }

另存為 hello.c. 我們可以使用 dbg 除錯它,像這樣:

  1. bork@kiwi ~> gcc -g hello.c -o hello

  2. bork@kiwi ~> gdb ./hello

以上是帶除錯資訊編譯 hello.c(為了 gdb 可以更好工作),並且它會給我們醒目的提示符,就像這樣:

  1. (gdb)

我們可以使用 break 命令設定斷點,然後使用 run 開始除錯程式。

  1. (gdb) break do_thing

  2. Breakpoint 1 at 0x4004f8

  3. (gdb) run

  4. Starting program: /home/bork/hello

  5. Breakpoint 1, 0x00000000004004f8 in do_thing ()

程式暫停在了 do_thing 開始的地方。

我們可以透過 where 檢視我們所在的呼叫棧。

  1. (gdb) where

  2. #0  do_thing () at hello.c:3

  3. #1  0x08050cdb in main () at hello.c:6

  4. (gdb)

2、 閱讀彙編程式碼

使用 disassemble 命令,我們可以看到這個函式的彙編程式碼。棒級了,這是 x86 彙編程式碼。雖然我不是很懂它,但是 callq 這一行是 printf 函式呼叫。

  1. (gdb) disassemble do_thing

  2. Dump of assembler code for function do_thing:

  3.   0x00000000004004f4 0>:     push   %rbp

  4.   0x00000000004004f5 1>:     mov    %rsp,%rbp

  5. => 0x00000000004004f8 4>:     mov    $0x40060c,%edi

  6.   0x00000000004004fd 9>:     callq  0x4003f0

  7.   0x0000000000400502 14>:    pop    %rbp

  8.   0x0000000000400503 15>:    retq

你也可以使用 disassemble 的縮寫 disas

3、 檢視記憶體

當除錯我的核心時,我使用 gdb 的主要原因是,以確保記憶體佈局是如我所想的那樣。檢查記憶體的命令是 examine,或者使用縮寫 x。我們將使用x

透過閱讀上面的彙編程式碼,似乎 0x40060c 可能是我們所要列印的字串地址。我們來試一下。

  1. (gdb) x/s 0x40060c

  2. 0x40060c:        "Hi!"

的確是這樣。x/s 中 /s 部分,意思是“把它作為字串展示”。我也可以“展示 10 個字元”,像這樣:

  1. (gdb) x/10c 0x40060c

  2. 0x40060c:       72 'H'  105 'i' 33 '!'  0 '\000'        1 '\001'        27 '\033'       3 '\003'        59 ';'

  3. 0x400614:       52 '4'  0 '\000'

你可以看到前四個字元是 Hi! 和 \0,並且它們之後的是一些不相關的東西。

我知道 gdb 很多其他的東西,但是我仍然不是很瞭解它,其中 x 和 break 讓我獲得很多。你還可以閱讀 do umentation for examining memory[2]


via: https://jvns.ca/blog/2014/02/10/three-steps-to-learning-gdb/

作者:Julia Evans[4] 譯者:Torival 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

LCTT 譯者

Torival ? ?
共計翻譯:2 篇
貢獻時間:151 天


推薦文章

< 左右滑動檢視相關文章 >

點選圖片、輸入文章 ID 或識別二維碼直達

贊(0)

分享創造快樂