關(guān)于GDB你需要知道的技巧
掃描二維碼
隨時隨地手機看文章
gdb基本上是每個unix環(huán)境開發(fā)者都會使用的調(diào)試工具,使用gdb基本上可以按照自己的需求隨心所欲的運行程序,可讓被調(diào)試的程序在自己所指定的斷點處停住,同時可以檢查程序當(dāng)前的狀態(tài),檢查各種變量及寄存器的值,也可以動態(tài)的改變程序的執(zhí)行環(huán)境。本期純干貨,無廢話,準(zhǔn)備好開始咯~
-
gdb filename:run開始、quit結(jié)束
-
gdb attach pid:程序已經(jīng)運行后,可使用attach跟蹤進程,attach目標(biāo)進程后,調(diào)試器會暫停下來,需要continue才繼續(xù),停止調(diào)試后使用detach命令分離調(diào)試器,quit結(jié)束
-
gdb filename corename:默認(rèn)不開啟core,需要設(shè)置core文件大小,使用ulimit -a可查看core文件大小,使用ulimit -c [n]設(shè)置core文件最大n字節(jié),使用ulimit -c unlimited表示修改為不限制大小。
core文件的默認(rèn)路徑和名稱為當(dāng)前工作目錄下生成的"core",通過如下方式可修改core的目錄和文件名稱:
echo "/root/test/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
%p->pid
%u->uid
%g->gid
%s->signal
%t->timestamp
%h->hostname
%e->exectable name
-
run(r): 運行一個程序
-
start: 執(zhí)行程序,停在main函數(shù)處
-
continue(c): 讓暫停的程序繼續(xù)執(zhí)行,continue默認(rèn)遇到斷點時候會暫停執(zhí)行,可以使用continue n表示繼續(xù)執(zhí)行一定次數(shù)
-
next(n): 運行到下一行
-
step(s): 進入到調(diào)用函數(shù)內(nèi)部
-
until(u): 運行到指定行停下來
-
finish(fi): 結(jié)束當(dāng)前調(diào)用函數(shù),到上一層函數(shù)調(diào)用處
-
return: 結(jié)束當(dāng)前調(diào)用函數(shù)并返回指定值到上一層函數(shù)調(diào)用處
finish命令會執(zhí)行函數(shù)到正常退出函數(shù),return會立即結(jié)束當(dāng)前函數(shù)并返回 -
jump(j): 執(zhí)行流跳轉(zhuǎn)到指定行或地址
-
print(p): 打印變量或寄存器值,也可以修改變量或寄存器值,默認(rèn)顯示有最大長度,設(shè)置set print element 0可設(shè)置將打印結(jié)果顯示完整
-
backtrace(bt): 當(dāng)前線程調(diào)用堆棧
bt n:顯示棧頂?shù)膎個幀信息
bt -n: 顯示棧底的n個幀信息
bt full: 顯示棧中所有幀的所有信息:函數(shù)參數(shù)、本地變量等 -
frame(f): 切換到調(diào)用線程的制定堆棧
-
thread id: 切換到指定線程
-
break(b): 添加斷點
-
tbradk: 添加臨時斷點(temporary)
-
rbreak [regex]在滿足正則表達式的函數(shù)處添加斷點
-
條件斷點1:break [linenumber] if [condition]
-
條件斷點2: 先break [linenumber]再condition [linenumber] [condition]
-
delete(del): 刪除斷點
-
enable: 啟用某個斷點
-
disable: 禁用某個斷點
-
enable once [num]:斷點只啟用一次
-
捕獲: catch和tcatch表示捕獲xxx停止程序運行
catch syscall close 產(chǎn)生close系統(tǒng)調(diào)用后停止程序運行 -
display: 每次程序中斷下來都會自動輸出變量的值
delete display
info display
delete display id -
watch: 監(jiān)視某一變量或內(nèi)存地址值是否發(fā)生變化,當(dāng)變化時gdb就會停下
watch [expr/field]:發(fā)生變化時暫停執(zhí)行
awatch [expr/field]:被訪問或者發(fā)生變化時暫停執(zhí)行
rwatch [expr/field]:被訪問時暫停執(zhí)行
watch expr thread [threadid]:監(jiān)視某個線程的變量表達式 -
list(l): 顯示源碼
list + 向后看源碼
list - 向前看源碼
默認(rèn)只顯示10行代碼,可以查看行數(shù)show listsize
可以設(shè)置行數(shù)set listsize [num]
list [first],[last]
list [function]
list [filename:function] -
info: 查看斷點線程等信息
-
ptype: 查看變量類型
whatis field 打印出field的結(jié)構(gòu)定義
ptype field 更詳細(xì)的打印field的類型 -
set variable [field]=[expression]改變變量的值
-
set $r0=[value] 改變寄存器的值
-
disassemble(dis): 查看匯編代碼
-
show disassembly-flavor:顯示反匯編指令格式
-
set disassembly-flavor intel 設(shè)置反匯編格式為intel格式
-
set args: 設(shè)置程序啟動命令行參數(shù)
-
show args: 查看設(shè)置的命令行參數(shù)
-
info break:查看斷點信息
-
info thread:查看線程信息
-
info sharedlibrary:顯示加載的動態(tài)鏈接庫信息
LWP:Light Weight Process輕量級進程 -
signal SIGSEGV: 可以使用signal SIGSEGV手動給程序發(fā)送信號
handle SIGSEGV 使用handle表示gdb調(diào)試時忽略某個信號 -
show scheduler-locking:顯示當(dāng)前線程scheduler-locking狀態(tài)
-
set scheduler-locking on調(diào)試時將程序執(zhí)行流鎖定在當(dāng)前線程,禁止上下文切換
-
set scheduler-locking off:不鎖定任何線程,所有線程都執(zhí)行
-
set scheduler-locking step: 阻止其它線程在當(dāng)前線程單步調(diào)試時搶占當(dāng)前線程,當(dāng)next、continue、until、finish等其它線程才會執(zhí)行
-
checkpoint搭配restart [id]: 相當(dāng)于給在當(dāng)前進程檢查點加一個快照,適合調(diào)試難以復(fù)現(xiàn)的bug,預(yù)感將要發(fā)生bug前,添加個checkpoint
-
多線程調(diào)試
thread id 多線程時,默認(rèn)是主線程,這里可以切換當(dāng)前調(diào)試的線程為指定id的線程號
thread apply all [cmd] 所有線程執(zhí)行命令
thread apply 1 2 3 [cmd] 1 2 3線程執(zhí)行命令
thread apply 1 2 3 bt: 查看1 2 3線程堆棧信息
tui調(diào)試是gdb自帶的功能,ctrl+X+A可以開啟TUI模式,開啟TUI模式后默認(rèn)會有兩個窗口,上窗口是當(dāng)前執(zhí)行位置的代碼,下窗口是gdb環(huán)境
cgdbcgdb是一個更高級的調(diào)試工具,和gdb使用方式完全相同,默認(rèn)就會開啟tui功能查看代碼
gdb調(diào)試原理gdb調(diào)試原理是使用ptrace系統(tǒng)調(diào)用,可自行搜索相關(guān)文章。





