調用gdb編譯需要在cc後面加 -g參數再加-o;
那麼可以使用下面這些命令方便地使程序一直執行到swap()的入口:
until 13
until swap
until swapflaw.c:13
until swapflaw.c:swap監視點是一種特殊類型的斷點,區別在於監視點沒有“住在”某一行源代碼中,而是指示GDB每當某個表達式改變了值就暫停執行。
設置監視點:watch z(變量名)也可以是複雜的表達式
注意只能監視存在且在作用域內的變量。一旦變量不再存在調用棧的任何幀中,GDB會自動刪除監視點。(gdb) list line1,line2
查看源代碼
list lineNum 在lineNum的前後源代碼顯示出來
list + 列出當前行的後面代碼行
list - 列出當前行的前面代碼行
list function
set listsize count
設置顯示代碼的行數
show listsize
顯示打印代碼的行數
list first,last
顯示從first到last的源代碼行finish命令指示GDB恢復執行,直到恰好在當前幀完成之後爲止。
until命令通常用來在不進一步在循環中暫停(除了循環中的中間斷點)的情況下完成正在執行的循環。until會執行循環的其餘部分(如果遇到斷點,還是會暫停),讓GDB在循環後面的第一行代碼處暫停。
until命令也可以接受源代碼中的位置作爲參數,其用法與break命令同。printf命令和C中printf函數類似,只是括號是可選的
讓GDB在每次到達某個斷點時自動執行一組命令,從而自動完成某一任務。
使用commands命令設置命令列表:
commands breakpoint_number
…
commands
…
end將正常斷點轉變爲條件斷點:condition break_p_num(斷點編號) cond(條件)
在有效的C條件語句中幾乎可以用任何表達式。也可以用自己的函數或者庫函數,只要他們被鏈接到程序中。
如:condition 1 num_y == 1
只有當滿足條件num_y == 1時,GDB纔會在斷點1處暫停程序的執行。
如果以後要刪除條件,但是保持斷點,只需鍵入:cond break_p_num(斷點編號)
用break if可以將break和condition命令組合成一個步驟:
break line_num(行號) if cond(條件)
例子:(gdb) nreak 30 if num_y == 1
注意,條件語句可以用括號()括起來,也可以不用。
查看棧幀:frame num(棧幀編號)
注意棧幀編號規則,當前正在執行的函數的幀被編號爲0,其父幀(即該函數的調用者的棧幀)被編號爲1,父幀的父幀被編號爲2,以此類推。
跳到調用棧中的下一個父幀:up
引向相反方向:down顯示整個棧,即當前存在的所有幀的集合:backtrace
常用命令
[root@redhat home]#gdb 調試文件:啓動gdb
(gdb) l
:(字母l)從第一行開始列出源碼
原文鏈接
(gdb) break n
:在第n行處設置斷點(gdb) break func
:在函數func()的入口處設置斷點(gdb) info break
: 查看斷點信息(gdb) r
:運行程序(gdb) n
:單步執行(gdb) c
:繼續運行(gdb) p
變量 :打印變量的值(gdb) bt
:查看函數堆棧(gdb) finish
:退出函數(gdb) shell
命令行:執行shell命令行(gdb) set args
參數:指定運行時的參數(gdb) show args
:查看設置好的參數(gdb) show paths
:查看程序運行路徑;set environment varname [=value]
設置環境變量。如:set env USER=hchen;show environment [varname]
查看環境變量;(gdb) cd
相當於shell的cd;(gdb)pwd
:顯示當前所在目錄(gdb)info program
: 來查看程序的是否在運行,進程號,被暫停的原因。(gdb)clear 行號n
:清除第n行的斷點(gdb)delete 斷點號n
:刪除第n個斷點(gdb)disable 斷點號n
:暫停第n個斷點(gdb)enable 斷點號n
:開啓第n個斷點(gdb)step:
單步調試如果有函數調用,則進入函數;與命令n不同,n是不進入調用的函數的list :簡記爲 l
,其作用就是列出程序的源代碼,默認每次顯示10行。list 行號:
將顯示當前文件以“行號”爲中心的前後10行代碼,如:list 12list 函數名
:將顯示“函數名”所在函數的源代碼,如:list mainlist
:不帶參數,將接着上一次 list 命令的,輸出下邊的內容。
注意 :如果運行list 命令得到類似如下的打印,那是因爲在編譯程序時沒有加入 -g 選項:(gdb) list
1 ../sysdeps/i386/elf/start.S: No such file or directory.
in ../sysdeps/i386/elf/start.Srun
:簡記爲 r ,其作用是運行程序,當遇到斷點後,程序會在斷點處停止運行,等待用戶輸入下一步的命令。
回車:重複上一條命令。set args
:設置運行程序時的命令行參數,如:set args 33 55show args
:顯示命令行參數continue
:簡訊爲 c ,其作用是繼續運行被斷點中斷的程序。break
:爲程序設置斷點。break 行號
:在當前文件的“行號”處設置斷點,如:break 33break 函數名
:在用戶定義的函數“函數名”處設置斷點,如:break cb_buttoninfo breakpoints
:顯示當前程序的斷點設置情況disable breakpoints Num
:關閉斷點“Num”,使其無效,其中“Num”爲 info breakpoints 中顯示的對應值enable breakpoints Num
:打開斷點“Num”,使其重新生效step
:簡記爲 s ,單步跟蹤程序,當遇到函數調用時,則進入此函數體(一般只進入用戶自定義函數)。next
:簡記爲 n,單步跟蹤程序,當遇到函數調用時,也不進入此函數體;此命令同 step 的主要區別是,step 遇到用戶自定義的函數,將步進到函數中去運行,而 next 則直接調用函數,不會進入到函數體內。until
:當你厭倦了在一個循環體內單步跟蹤時,這個命令可以運行程序直到退出循環體。finish
: 運行程序,直到當前函數完成返回,並打印函數返回時的堆棧地址和返回值及參數值等信息。stepi或nexti
:單步跟蹤一些機器指令。print 表達式
:簡記爲 p ,其中“表達式”可以是任何當前正在被測試程序的有效表達式,比如當前正在調試C語言的程序,那麼“表達式”可以是任何C語言的有效表達式,包括數字,變量甚至是函數調用。print a:
將顯示整數 a 的值print ++a:
將把 a 中的值加1,並顯示出來print name
:將顯示字符串 name 的值print gdb_test(22)
:將以整數22作爲參數調用 gdb_test() 函數print gdb_test(a)
:將以變量 a 作爲參數調用 gdb_test() 函數bt
:顯示當前程序的函數調用堆棧。display 表達式
:在單步運行時將非常有用,使用display命令設置一個表達式後,它將在每次單步進行指令後,緊接着輸出被設置的表達式及值。如: display awatch 表達式
:設置一個監視點,一旦被監視的“表達式”的值改變,gdb將強行終止正在被調試的程序。如: watch akill
:將強行終止當前正在調試的程序help 命令
:help 命令將顯示“命令”的常用幫助信息call 函數(參數)
:調用“函數”,並傳遞“參數”,如:call gdb_test(55)layout
:用於分割窗口,可以一邊查看代碼,一邊測試:layout src
:顯示源代碼窗口layout asm
:顯示反彙編窗口layout regs
:顯示源代碼/反彙編和CPU寄存器窗口layout split
:顯示源代碼和反彙編窗口Ctrl + L
:刷新窗口quit
:簡記爲 q ,退出gdb
當然,gdb的功能遠不止這些,包括多進程/多線程/信號/遠程調試等功能在這裏均沒有提及,有需要的讀者可以參考其它信息