溫馨提示×

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

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

GDB 的秘密(九)

發(fā)布時(shí)間:2020-07-19 14:15:40 來(lái)源:網(wǎng)絡(luò) 閱讀:357 作者:上帝之子521 欄目:系統(tǒng)運(yùn)維

        在上節(jié)博客中,我們學(xué)習(xí)了鏈接器的知識(shí)。那么本節(jié)課我們繼續(xù)學(xué)習(xí)嵌入式開發(fā)中的一些常用的操作,今天我們學(xué)習(xí)的是在 GNU 開發(fā)中,必不可少的調(diào)試?yán)?GDB??赡芨愕讓拥耐净蚨嗷蛏俚穆犨^(guò) GDB,但是覺(jué)得它總是那么的神秘,很模糊。那么我們今天就來(lái)看看 GDB。

        先從它的概念開始介紹,什么是 GDB 呢?它是 GNU項(xiàng)目中的調(diào)試器(gnu debuger),它的作用是能追蹤程序的執(zhí)行,也能恢復(fù)程序崩潰前的狀態(tài)。那么我們?yōu)槭裁葱枰?GDB 呢?在我們?nèi)粘5能浖_發(fā)中,難免會(huì)寫出一些難以發(fā)現(xiàn)的 bug,那么這些 bug 又是曇花一現(xiàn),馬上就結(jié)束了。我們來(lái)不及反應(yīng)程序就崩潰了,因此我們找不到 bug 的來(lái)源。因此我們需要在軟件開發(fā)的過(guò)程中進(jìn)行調(diào)試,這也便是 gdb 的由來(lái)。

        下來(lái)我們來(lái)看看 GDB 的一些常規(guī)性應(yīng)用,一般包括以下幾方面:

                1、自定義程序的啟動(dòng)方式(指定影響程序運(yùn)行的參數(shù));

                2、設(shè)置條件斷點(diǎn)(在條件滿足時(shí)暫停程序的執(zhí)行);

                3、回溯檢查導(dǎo)致程序異常結(jié)束的原因(Core Dump);

                4、動(dòng)態(tài)改變程序執(zhí)行流(定位問(wèn)題的輔助方式)。

        那么 GDB 又是怎樣進(jìn)行啟動(dòng)的呢?它的啟動(dòng)方式可以大致分為兩種:直接啟動(dòng)和動(dòng)態(tài)連接。直接啟動(dòng)又分為三種:gdb;   gdb test.out;   gdb test.out core;  動(dòng)態(tài)連接:gdb test.out pid

        下來(lái)我們來(lái)看看 GDB 應(yīng)用的一個(gè)示例,如下

GDB 的秘密(九)

  GDB 的秘密(九)

        介紹了它的啟動(dòng)方式后,我們?cè)賮?lái)看看用它如何進(jìn)行斷點(diǎn)調(diào)試。在介紹斷點(diǎn)調(diào)試之前,我們首先來(lái)看看在 GNU 中的斷點(diǎn)類型。它分為三種:軟件斷點(diǎn)、硬件斷點(diǎn)、數(shù)據(jù)斷點(diǎn)。軟件斷點(diǎn)是由非法指令異常實(shí)現(xiàn)的(也即是通過(guò)軟件實(shí)現(xiàn)),硬件斷點(diǎn)和數(shù)據(jù)斷點(diǎn)則是由硬件特性實(shí)現(xiàn)(共同的特點(diǎn)是數(shù)量有限)。

        接下來(lái)我們來(lái)看看軟件斷點(diǎn)的相關(guān)操作:

                1、通過(guò)函數(shù)名設(shè)置斷點(diǎn):

                        如 a> break func_name [ if var = value ]

                            b> tbreak func_name [ if var = value ]

                2、通過(guò)文件名行號(hào)設(shè)置斷點(diǎn):

                        如 a> break func_name:line_num [ if var = value ]

                            b> tbreak func_name:line_num [ if var = value ]

        上面的 break 和 tbreak 兩種方式的區(qū)別是,tbreak 設(shè)置的是臨時(shí)斷點(diǎn),而 break 設(shè)置的則是永久斷點(diǎn)。下面我們繼續(xù)來(lái)看看斷點(diǎn)操作的一些常用命令

GDB 的秘密(九)

GDB 的秘密(九)

        介紹了軟件斷點(diǎn)的相關(guān)操作之后,我們來(lái)繼續(xù)介紹硬件斷點(diǎn)的操作及應(yīng)用。那么我們是在什么樣的情況下才會(huì)去使用硬件斷點(diǎn)呢?1、當(dāng)代碼位于只讀存儲(chǔ)器(Flash)時(shí),只能通過(guò)硬件斷點(diǎn)調(diào)試;2、硬件斷點(diǎn)需要硬件支持,數(shù)量有限;3、GDB 中通過(guò) hbreak 命令支持硬件斷點(diǎn);4、hbreak 與 break 的使用方式是完全一致的。

        我們先來(lái)看看數(shù)據(jù)斷點(diǎn):在 GDB 中支持?jǐn)?shù)據(jù)斷點(diǎn)的設(shè)置,watch 命令用于監(jiān)視變量是否被改變(其本質(zhì)也為硬件斷點(diǎn))。watch 命令的用法:watch var_name,在 GDB 中可以檢查任意內(nèi)存區(qū)域中的數(shù)據(jù)。命令語(yǔ)法:x /Nuf experssion ,其中 N 是需要打印的單元數(shù),u 指的是每個(gè)單元的大小,f 指的是數(shù)據(jù)打印的格式。我們來(lái)看看 x 命令中參數(shù) u 對(duì)應(yīng)的單位,如下所示

GDB 的秘密(九)

        接下來(lái)我們來(lái)看看 GDB 中的打印格式,如下圖所示

GDB 的秘密(九)

        在這塊我們可以利用這個(gè)特性用來(lái)判斷系統(tǒng)大小端,示例代碼如下

GDB 的秘密(九)

        如果是上面的那種情況,那么此系統(tǒng)就是小端;反之則是大端。接下來(lái)看看函數(shù)調(diào)用棧的查看(backtrace 和 frame)。

        backtrace 是用來(lái)查看函數(shù)調(diào)用的順序(函數(shù)調(diào)用棧的信息);frame N 則是切換到棧編號(hào)為 N 的上下文中;info frame 是用來(lái)查看當(dāng)前函數(shù)站調(diào)用的棧幀信息的。棧幀信息就是我們之前在 C 語(yǔ)言中講到的函數(shù)活動(dòng)記錄,如下

GDB 的秘密(九)

        我們?cè)賮?lái)深入的看看 info 命令,如下

GDB 的秘密(九)

        那么在調(diào)試中還有一些小技巧,比如在斷點(diǎn)處自動(dòng)打?。篸isplay /f expression,相應(yīng)的去除打印就是:undisplay;查看程序中的符號(hào):whatis,ptype;GDB 中的代碼查看:list,set listsize N;GDB 中的 shell 操作:shell??纯磾帱c(diǎn)出自動(dòng)打印的示例,如下

GDB 的秘密(九)

        符號(hào)查看的示例如下

GDB 的秘密(九)

        通過(guò)今天對(duì) GDB 的學(xué)習(xí),總結(jié)如下:1、GDB 支持?jǐn)?shù)據(jù)斷點(diǎn)的設(shè)置(一種類型的硬件斷點(diǎn));2、watch 用于監(jiān)視變量是否被改變,x 用于查看內(nèi)存中的數(shù)據(jù);3、GDB 支持函數(shù)調(diào)用棧的查看(backtrace,info frames);4、GDB  支持運(yùn)行時(shí)對(duì)程序中的符號(hào)進(jìn)行查看(whatis,ptype)。

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

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI