iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 1
0
Software Development

深入淺出 Debugger系列 第 2

Day 2 - [INFO] GDB 基礎操作

GDB 這東西已經有太多人介紹過怎麼操作,這部分是有點無聊,但在了解原理前,還是學會怎麼使用吧

我常用的指令

  • 主要參考資料
  • run
    • file 若是一開始沒載入檔案用這個指令載入,再來 run
    • set args
  • break/br: break point 設定中斷點
    • b main breakpoint by function
    • b *main+10 breakpoint by address
    • b 40 breakpoint at line 40
    • 斷點操作
      • clear
      • delete
      • disable
      • enable
      • condition
    • continue/c: 繼續執行直到下個斷點
    • step : 在這個斷點時,一步一步執行
    • stepi 追進副程式
    • next 執行完副程式
    • until 直到跑完一個迴圈
b 目前位置
b 100
b function
b 100 if (var == 5)
br 100
commands
    silent
    printf "x is %d\n", x
end
clear 1 清除1號中斷點
  • print/p : 印出變數
    • whatis var
    • ptype var(看 struct)
    • p/x 印出 hex 值
    • p/u
    • p/d
    • display 一直顯示某個變數
    • undisplay
p variable
p variable[1]@5    印出 variable[1] - variable[5]
p variable=5       要修改變數可以直接使用 print,它也有 eval 的功能然後就只是多了印出
  • x 看記憶體位置的數值
    • convience variable
      • $_ : x指令的最後一個位置
      • $__: x指令最後一個位置的值
x/4 &a
x/4 0x8000000
  • info: info break, info frame
  • show: show os, show args
  • backtrace/bt: 回溯
  • 看程式碼
    • list
    • disas 看 machine code
    • examine/x 看記憶體
  • convience variable
    • $pc: program counter
  • 進入 process
    • signal process-id
    • attach process-id
    • detach process-id

完整的操作

#include <stdio.h>

int main() {
    int x = 10;
    x = 12;
    printf("x = %d\n", x);
    printf("x = %d\n", x);
    return 0;
}

可以拿編譯出來的檔案,用 GDB 下去跑跑看,編譯的時候記得下 -g ,才會有 debug info

下面做的事很簡單,有兩行輸出,我把斷點下在第七行,這時只有第一個 printf 會執行,接著我使用 print 來修改 x 的數值,再讓他繼續執行,就可以發現 x 數值真的被改動了

GDB debug 通常不是拿來改數值,而是拿來觀看數值,以及 function 之間是如何呼叫,也就是 backtrace 來看 stack 的內容,這可以自行下去摸索

> gdb ./sample 
(gdb) list
1	#include <stdio.h>
2	
3	int main() {
4	    int x = 10;
5	    x = 12;
6	    printf("x = %d\n", x);
7	    printf("x = %d\n", x);
8	    return 0;
9	}
(gdb) b 7
Breakpoint 1 at 0x676: file sample.c, line 7.
(gdb) r
Starting program: /home/chungyi/gitPro/ithome2020/day1/sample 
x = 12

Breakpoint 1, main () at sample.c:7
7	    printf("x = %d\n", x);
(gdb) p x=133
$1 = 133
(gdb) c
Continuing.
x = 133
[Inferior 1 (process 5043) exited normally]

Misc

像是 .bashrc 一樣,GDB 也有設定檔可以使用,那就是 .gdbinit,根據 gdbinit man 裡所敘述,我們可以把 .gdbinit 放在在家目錄或是當前目錄,都會被自動讀取,以下就介紹一些,我常用到的功能

  • 指令歷史紀錄: 像是 bash_history,不用每次都重打上一組指令
set history save on
set history filename ~/.gdb-history
set history size 1000
  • Remote Protocol Debug: 可以拿來看每個封包的每個 bit 到底傳輸了什麼
set debug remote 1

Next

明天打算講 Bomb Lab ,我會寫一個非常簡單的版本,不會像 CS:APP 課程那麼麻煩,像這篇文章(Bomb Lab 實作紀錄) 的簡化版本,但我們不玩 ARM 就玩 x86_64


上一篇
Day1 - Overview
下一篇
Day 3 - [LAB] Bomb lab
系列文
深入淺出 Debugger3

尚未有邦友留言

立即登入留言