一、常見gdb調試指令
指令 | 描述 |
backtrace(或bt) | 檢視各級函數調用及參數 |
finish | 連續運作到目前函數傳回為止,然後停下來等待指令 |
frame(或f) 幀編号 | 選擇棧幀 |
info(或i) locals | 檢視目前棧幀局部變量的值 |
list(或l) | 列出源代碼,接着上次的位置往下列,每次列10行 |
continue(c) | 列出從第幾行開始的源代碼 |
list 函數名 | 繼續執行 |
next(或n) | 執行下一行語句 |
print(或p) | 列印表達式的值,通過表達式可以修改變量的值或者調用函數 |
quit(或q) | 退出 調試環境 |
set var | 修改變量的值 |
start | 開始執行程式,停在 函數第一行語句前面等待指令 |
step(或s) | 執行下一行語句,如果有函數調用則進入到函數中 |
break(b) | 設定斷點 |
delete(d) | 删除斷點 |
attach <pid> | attach到程序 ID 為 pid 的程序 |
二、info調試指令
指令 | 描述 |
info registers | 檢視除了浮點寄存器以外的寄存器 |
info all-registers | 檢視所有寄存器,包括浮點寄存器 |
info registers <regname …> | 檢視所指定的寄存器 |
info break | 檢視斷點資訊 |
info watchpoints | 列出目前所設定的所有觀察點 |
info signals info handle | 檢視有哪些信号正在被GDB檢測 |
info frame | 檢視目前程式棧的資訊 |
info threads | 可以看多線程 |
info args | 檢視目前函數參數資訊 |
info locals | 檢視目前程式棧的局部變量 |
三、記憶體檢視
3.1 列印記憶體資料
gdb檢視指定位址的記憶體位址的值:examine 簡寫 x-----使用gdb> help x 來檢視使用方式
x/ (n,f,u為可選參數)
n: 需要顯示的記憶體單元個數,也就是從目前位址向後顯示幾個記憶體單元的内容,一個記憶體單元的大小由後面的u定義
f:顯示格式
x(hex) 按十六進制格式顯示變量。
d(decimal) 按十進制格式顯示變量。
u(unsigned decimal) 按十進制格式顯示無符号整型。
o(octal) 按八進制格式顯示變量。
t(binary) 按二進制格式顯示變量。
a(address) 按十六進制格式顯示變量。
c(char) 按字元格式顯示變量。
f(float) 按浮點數格式顯示變量
u:每個單元的大小,按位元組數來計算。預設是4 bytes。GDB會從指定記憶體位址開始讀取指定位元組,并把其當作一個值取出來,并使用格式f來顯示
b:1 byte h:2 bytes w:4 bytes g:8 bytes
比如x/3uh 0x54320表示從記憶體位址0x54320讀取内容,h表示以雙位元組為機關,3表示輸出3個機關,u表示按照十六進制顯示。
3.2 列印數組
比如我有一個數組的定義 :int a[] = {1, 2, 3, 4, 5};
那麼想要顯示的時候就可以寫:
p *[email protected]
這樣就會顯示數組a中的所有元素。
也可以使用display在一部調試的時候都顯示:
display *[email protected]
四、多線程調試指令
指令 | 描述 |
info threads | 顯示目前可調試的所有線程,每個線程會有一個GDB為其配置設定的ID,後面操作線程的時候會用到這個ID。 前面有*的是目前調試的線程 |
thread ID(1,2,3…) | 切換目前調試的線程為指定ID的線程 |
break thread_test.c:123 thread all(例:在相應函數的位置設定斷點break pthread_run1) | 在所有線程中相應的行上設定斷點 |
thread apply ID1 ID2 command | 讓一個或者多個線程執行GDB指令command |
thread apply all command | 讓所有被調試線程執行GDB指令command |
set scheduler-locking 選項 command | 設定線程是以什麼方式來執行指令 |
set scheduler-locking off | 不鎖定任何線程,也就是所有線程都執行,這是預設值 |
set scheduler-locking on | 隻有目前被調試程式會執行 |
set scheduler-locking on step | 在單步的時候,除了next過一個函數的情況(熟悉情況的人可能知道,這其實是一個設定斷點然後continue的行為)以外,隻有目前線程會執行 |
參考:線程的檢視以及利用gdb調試多線程