# Day 2 - [INFO] GDB 基礎操作 ###### tags: `ithome2020` GDB 這東西已經有太多人介紹過怎麼操作,這部分是有點無聊,但在了解原理前,還是學會怎麼使用吧 ## 我常用的指令 * 主要參考資料 * [[轉貼]GDB 介紹](http://b8807053.pixnet.net/blog/post/336154079-%5B%E8%BD%89%E8%B2%BC%5Dgdb-%E4%BB%8B%E7%B4%B9) * [遠端除錯 - 基礎 gdb](http://www.study-area.org/cyril/opentools/opentools/x1253.html) * [遠端除錯 - 進階 gdb](http://www.study-area.org/cyril/opentools/opentools/x1265.html) * [Debugging with GDB](https://sourceware.org/gdb/onlinedocs/gdb/index.html#Top) * 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 直到跑完一個迴圈 ```shell 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 ```shell p variable p variable[1]@5 印出 variable[1] - variable[5] p variable=5 要修改變數可以直接使用 print,它也有 eval 的功能然後就只是多了印出 ``` * x 看記憶體位置的數值 * convience variable * $_ : x指令的最後一個位置 * $__: x指令最後一個位置的值 ```shell= 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 ## 完整的操作 * [sample.c](https://github.com/ian910297/ithome2020/blob/master/day2/sample.c) ```clike= #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 的內容,這可以自行下去摸索 ```shell > 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](https://sourceware.org/gdb/current/onlinedocs/gdb/gdbinit-man.html) 裡所敘述,我們可以把 `.gdbinit` 放在在家目錄或是當前目錄,都會被自動讀取,以下就介紹一些,我常用到的功能 * 指令歷史紀錄 ```shell set history save on set history filename ~/.gdb-history set history size 1000 ``` * Remote Protocol Debug ```shell set debug remote 1 ``` ## Next 明天打算講 Bomb Lab ,我會寫一個非常簡單的版本,不會像 CS:APP 課程那麼麻煩,像這篇文章([Bomb Lab 實作紀錄](https://hackmd.io/@posutsai/SyNzl72f4?type=view)) 的簡化版本,但我們不玩 ARM 就玩 x86_64