您好,登錄后才能下訂單哦!
本篇文章為大家展示了如何進(jìn)行C程序調(diào)試與GDB入門,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。
引用自<assert.h>
的函數(shù)assert(int expression)
,當(dāng)表達(dá)式的值為0則返回failed
。
gdb是GUN的提供在unix上的調(diào)試工具。
安裝:sudo apt install gdb
如果是windows,則尋找對應(yīng)的exe安裝即可,同時需要配置環(huán)境變量
# 編譯,得到executable程序 # -g指令會列出行號、注釋信息 gcc -g -o executable one.c two.c other.c # gdb調(diào)試 gdb executable # 指定某行打斷點(diǎn),或者指定某個函數(shù)為斷點(diǎn) break one:17 break main #運(yùn)行 run [args] # 顯示待驗(yàn)證的變量值,此后每次停下來都會顯示這些變量值 display var1 display var2 # 快進(jìn)到下一個斷點(diǎn)/或者運(yùn)行到結(jié)尾 continue # 退出 quit
著重說一下斷點(diǎn)的標(biāo)識和查詢。
怎么打斷點(diǎn)
# 直接在函數(shù)上打斷點(diǎn) break <function_name> # 作用在指定行上,如果是多文件,可以使用filename指定特定的源文件 break <filename>:line_num
斷點(diǎn)信息查詢以及斷點(diǎn)的刪除、禁用等
# 查詢?nèi)康臄帱c(diǎn),顯示信息的第一列是每一個斷點(diǎn)id info breakpoints #刪除斷點(diǎn) delete break_id # 禁用斷點(diǎn) disable break_id #重啟被禁用的斷點(diǎn) enable break_id #忽略斷點(diǎn)times次 #也就意味著,在運(yùn)行到斷點(diǎn)times次以后,斷點(diǎn)會再次生效 ignore break_id times
條件中斷
條件中斷,即滿足指定條件才會觸發(fā)中斷的斷點(diǎn),某些時候這非常有用,譬如某些信號量達(dá)到預(yù)定值才會觸發(fā)中斷,如果Java中的異常中斷一樣。
# 設(shè)置條件斷點(diǎn) break line_num if [expression]
譬如,break swap if m > 100
,需要注意只有在斷點(diǎn)處m變量生效,該條件才會生效。
對于已經(jīng)設(shè)置的斷點(diǎn)可以使用condition
指定:
# 給break_id斷點(diǎn)設(shè)置中斷條件 condition break_id [expresion] # 取消中斷條件,只要后面什么條件也不跟即可 condition break_id
help-幫助指令 run-運(yùn)行 quit-退出 break-打斷點(diǎn),可以斷某個行或者某個函數(shù)如`break main` next-下一行,簡寫`n` step-也是下一行,不同于next的是,如果某個行本身引用了函數(shù),則會step into到該函數(shù)內(nèi)部去,簡寫`s` finish-跳出當(dāng)前函數(shù)/或者打到下一個斷點(diǎn) continue,下一個斷點(diǎn)或者運(yùn)行到結(jié)尾,簡寫`c` display-跟蹤打印某個變量的值 print-一次打印當(dāng)前狀態(tài)下所指定變量的值 detele-刪除全部斷點(diǎn) info breakpoint-全部斷點(diǎn)信息 clear-清楚斷點(diǎn),clear function,清楚函數(shù)斷點(diǎn) until-類似于next,但是在循環(huán)中時,它可以一步到位直接到循環(huán)結(jié)束,而不像next一樣執(zhí)行每一次迭代 list-列出當(dāng)前行上下的代碼,list function列出函數(shù)的代碼
補(bǔ)充兩點(diǎn)內(nèi)容。
我們知道系統(tǒng)會使用棧(Stack)數(shù)據(jù)結(jié)構(gòu)存儲調(diào)用函數(shù),運(yùn)行中的函數(shù)入棧,運(yùn)行完畢則出棧。棧元素主要被包含函數(shù)地址、局部變量、參數(shù)名等。當(dāng)我們需要了解程序的調(diào)用路徑的時候,可以使用info stack
等語句追蹤函數(shù)運(yùn)行軌跡。
第二點(diǎn)涉及到觀測點(diǎn)(watchpoint)或者說監(jiān)測點(diǎn)。觀測點(diǎn)設(shè)置后會被當(dāng)作斷點(diǎn)一樣對待。與普通斷點(diǎn)(breakpoint)不同的是,觀測點(diǎn)主要關(guān)注一個或者多個被聲明的變量,當(dāng)這些變量變動或者這些變量被調(diào)用時,則觸發(fā)【觀測點(diǎn)】。
當(dāng)?shù)竭_(dá)一個斷點(diǎn)的時候,想查看此時的調(diào)用棧?
# backtrace顯示當(dāng)前程序的調(diào)用棧,或者使用bt指令 backtrace # 顯示一個棧幀詳情,frame_id就是bt查詢結(jié)果的第一列數(shù)值 frame [farme_id]
當(dāng)程序運(yùn)行到某個函數(shù)時,該函數(shù)位于棧結(jié)構(gòu)的頂部——即當(dāng)前棧,可以使用info
指令查詢當(dāng)前棧的詳情:
# 當(dāng)前棧頂詳情 # 其中會有eip和ebp兩個數(shù)值,eip表示下一個指令地址;ebp表示當(dāng)前棧幀地址 info frame # 查詢當(dāng)前棧幀的局部變量 info locals # 查詢當(dāng)前棧幀的入?yún)? info args
首先需要注意的是,只有相應(yīng)的變量對當(dāng)前棧幀可見,才可以在這個時候定義該變量的觀測點(diǎn)。
有三種創(chuàng)建觀測點(diǎn)的方法,側(cè)重點(diǎn)各不相同,指令格式為watch [expresion]
。
# 表達(dá)式內(nèi)的變量都會被監(jiān)測到 #所以a、b的值有變動,就會觸發(fā)觀測點(diǎn),此時暫時程序下來,如同斷點(diǎn)觸發(fā)一樣 watch a+b
# b被讀取即觸發(fā)斷點(diǎn) rwatch b
# a或者b被讀取、修改、參與計(jì)算都會觸發(fā)斷點(diǎn) awatch a+b
一般情況下,使用watch
指令足夠了。
上述內(nèi)容就是如何進(jìn)行C程序調(diào)試與GDB入門,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。