gdb調試

1. 加斷點

  • break <function>    在進入指定函數時停住
  • break <linenum>    在指定行號停住。
  • break +/-offset    在當前行號的前面或後面的offset行停住。offiset爲自然數。
  • break filename:linenum    在源文件filename的linenum行處停住。
  • break classname::functionname
  • break filename:function  制定文件中的函數
  • break ... if <condition>    ...可以是上述的參數,condition表示條件,在條件成立時停住。比如在循環境體中,可以設置break if i=100,表示當i爲100時停住程序。

2. 可以通過info breakpoints [n]命令查看當前斷點信息。此外,還有如下幾個配套的常用命令:

  • delete     刪除所有斷點
  • delete breakpoint n    d n刪除某個斷點
  • disable breakpoint n    disable n禁用某個斷點
  • enable breakpoint n    enable n使能某個斷點

3. 在特定線程中中斷

你可以定義你的斷點是否在所有的線程上,或是在某個特定的線程。GDB很容易幫你完成這一工作。

  • break <linespec> thread <threadno>
  • break <linespec> thread <threadno> if ...

linespec指定了斷點設置在的源程序的行號。threadno指定了線程的ID,注意,這個ID是GDB分配的,你可以通過"info threads"命令來查看正在運行程序中的線程信息。如果你不指定thread <threadno>則表示你的斷點設在所有線程上面。你還可以爲某線程指定斷點條件。如:

     (gdb) break frik.c:13 thread 28 if bartab > lim

當你的程序被GDB停住時,所有的運行線程都會被停住。這方便你你查看運行程序的總體情況。而在你恢復程序運行時,所有的線程也會被恢復運行。那怕是主進程在被單步調試時。

4. 恢復程序運行和單步調試

在gdb中,和調試步進相關的命令主要有如下幾條:

  • continue    繼續運行程序直到下一個斷點(類似於VS裏的F5)
  • next        逐過程步進,不會進入子函數(類似VS裏的F10)
  • setp        逐語句步進,會進入子函數(類似VS裏的F11)
  • until        運行至當前語句塊結束
  • finish       運行至函數結束並跳出,並打印函數的返回值(類似VS的Shift+F11)
  • return      Make selected stack frame return to its caller
  • up            Select and print stack frame that called this one
  • down Select and print stack frame called by this one
  • frame       Select and print a stack frame
  • reverse-continue -- Continue program being debugged but run it in reverse
  • reverse-finish -- Execute backward until just before selected stack frame is called
  • reverse-next -- Step program backward
  • thread apply all -- Apply a command to all threads
  • thread apply -- Apply a command to a list of threads
  • info args -- Argument variables of current stack frame
  • info frame -- All about selected stack frame
  • info locals -- Local variables of current stack frame
  • info vector -- Print the status of the vector unit
  • info stack -- Backtrace of the stack
  • show backtrace -- Show backtrace specific variables
  • tsave -- Save the trace data to a file

PS:這些命令大部分可以簡寫爲第一個字母,在日常使用過程中,往往只會輸入第一個字符即可執行該命令,我標紅的即是通常的使用方式。這幾條命令使用非常頻繁,並且可以帶一些附加參數以實現高級功能,需要熟練掌握。


5.

layout:用於分割窗口,可以一邊查看代碼,一邊測試。主要有以下幾種用法:
layout src:顯示源代碼窗口
layout asm:顯示彙編窗口
layout regs:顯示源代碼/彙編和寄存器窗口
layout split:顯示源代碼和彙編窗口
layout next:顯示下一個layout
layout prev:顯示上一個layout
Ctrl + L:刷新窗口
Ctrl + x,再按1:單窗口模式,顯示一個窗口
Ctrl + x,再按2:雙窗口模式,顯示兩個窗口

Ctrl + x,再按a:回到傳統模式,即退出layout,回到執行layout之前的調試窗口。


6.生成core:

1)sudo gdb
2)shell gcore 24425
3) detach

7. 調試運行時進程:
1)通過–-pid參數來綁定指定的進程程序。
gdb --pid 25552
2)通過程序和進程號來綁定
gdb test 25552
3)先啓動gdb後,通過attach來綁定pid
gdb
gdb) attach 25552

8. 指定源代碼
1) gdb --pid 25552 -d ~/workspace/
2) directory ~/workspace/


9. 調試core file:
1) ar p bds-triton-sd_4.0.1.623-squeeze1_amd64.deb data.tar.gz | tar zxf -
2) schroot -c squeeze64
3) gdb ./usr/sbin/sd core.11077 --dir ../tms/t3/
4) thread apply all bt
5) t 2
6) f 2
調試子進程:set follow-fork-mode child
source ./.stl-views.gdb

5. 觀察點(WatchPoint):

在變量讀、寫或變化時中斷,這類方式常用來定位bug。

  • watch <expr>    變量發生變化時中斷
  • rwatch <expr>    變量被讀時中斷
  • awatch <expr>     變量值被讀或被寫時中斷

可以通過info watchpoints [n]命令查看當前觀察點信息

6. 捕捉點(CatchPoint):

捕捉點用來補捉程序運行時的一些事件。如:載入共享庫(動態鏈接庫)、C++的異常等。通常也是用來定位bug。

捕捉點的命令格式是:catch <event>event可以是下面的內容

throw     C++拋出的異常時中斷
catch     C++捕捉到的異常時中斷
exec     調用系統調用exec時(只在某些操作系統下有用)
fork     調用系統調用fork時(只在某些操作系統下有用)
vfork     調用系統調用vfork時(只在某些操作系統下有用)
load 或 load <libname>     載入共享庫時(只在某些操作系統下有用)
unload 或 unload <libname>     卸載共享庫時(只在某些操作系統下有用)

backtrace(或bt)       查看各級函數調用及參數
finish   連續運行到當前函數返回爲止,然後停下來等待命令
frame(或f) 幀編號 選擇棧幀
info(或i) locals 查看當前棧幀局部變量的值
list(或l) 列出源代碼,接着上次的位置往下列,每次列10行
list 行號 列出從第幾行開始的源代碼
list 函數名 列出某個函數的源代碼
set var 修改變量的值
start 開始執行程序,停在main函數第一行語句前面等待命令
break ... if ... 設置條件斷點
display 變量名 跟蹤查看某個變量,每次停下來都顯示它的值
info(或i)breakpoints 查看當前設置了哪些斷點
run(或r) 從頭開始連續運行程序
undisplay 跟蹤顯示號 取消跟蹤顯示
watch 設置觀察點     
info(或i) watchpoints 查看當前設置了哪些觀察點  
x 從某個位置開始打印存儲單元的內容,全部當成字節來看,而不區分哪個字節屬於哪個變量

設置打印全部字符:set print element 0

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章