溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何進(jìn)行C程序調(diào)試與GDB入門

發(fā)布時間:2021-11-17 09:16:35 來源:億速云 閱讀:171 作者:柒染 欄目:大數(shù)據(jù)

本篇文章為大家展示了如何進(jìn)行C程序調(diào)試與GDB入門,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

1、Assert

引用自<assert.h>的函數(shù)assert(int expression),當(dāng)表達(dá)式的值為0則返回failed。

2、GDB

gdb是GUN的提供在unix上的調(diào)試工具。

安裝sudo apt install gdb

如果是windows,則尋找對應(yīng)的exe安裝即可,同時需要配置環(huán)境變量

2.1 使用流程

# 編譯,得到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

2.2 斷點(diǎn)和條件中斷

著重說一下斷點(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

2.3 常用的指令

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ù)的代碼

2.4 一些補(bǔ)充——棧幀觀察、監(jiān)測點(diǎn)

補(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)】。

1 調(diào)用棧查詢

當(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
2 觀測點(diǎn)

首先需要注意的是,只有相應(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è)資訊頻道。

向AI問一下細(xì)節(jié)

免責(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)容。

AI