日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 嵌入式 > 嵌入式教程
[導讀]調試是所有程序員都會面臨的問題。如何提高程序員的調試效率,更好、更快地定位程序中的問題從而加快程序開發(fā)的進度,是大家都很關注的問題。就如讀者熟知的Windows下的一些調試工具,如Visual Studio自帶的設置斷點、單步跟蹤等,都受到了廣大用戶的贊賞。

3.4gdb調試器

調試是所有程序員都會面臨的問題。如何提高程序員的調試效率,更好、更快地定位程序中的問題從而加快程序開發(fā)的進度,是大家都很關注的問題。就如讀者熟知的Windows下的一些調試工具,如VisualStudio自帶的設置斷點、單步跟蹤等,都受到了廣大用戶的贊賞。那么,在Linux下有什么很好的調試工具呢?

gdb調試器是一款GNU開發(fā)組織并發(fā)布的UNIX/Linux下的程序調試工具。雖然,它沒有圖形化的友好界面,但是它強大的功能也足以與微軟的VisualStudio等工具媲美。下面就請跟隨筆者一步步學習gdb調試器。

3.4.1gdb使用流程

這里給出了一個短小的程序,由此帶領讀者熟悉gdb的使用流程。建議讀者能夠動手實際操作一下。

首先,打開Linux下的編輯器vi或者emacs,編輯如下代碼(由于為了更好地熟悉gdb的操作,筆者在此使用vi編輯,希望讀者能夠參見3.3節(jié)中對vi的介紹,并熟練使用vi)。

/*test.c*/

#include<stdio.h>

intsum(intm);

intmain()

{

inti,n=0;

sum(50);

for(i=1;i<=50;i++)

{

n+=i;

}

printf("Thesumof1-50is%d\n",n);

}

intsum(intm)

{

inti,n=0;

for(i=1;i<=m;i++)

{

n+=i;

printf("Thesumof1-mis%d\n",n);

}

}

在保存退出后首先使用gcc對test.c進行編譯,注意一定要加上選項“-g”,這樣編譯出的可執(zhí)行代碼中才包含調試信息,否則之后gdb無法載入該可執(zhí)行文件。

[root@localhostgdb]#gcc-gtest.c-otest

雖然這段程序沒有錯誤,但調試完全正確的程序可以更加了解gdb的使用流程。接下來就啟動gdb進行調試。注意,gdb進行調試的是可執(zhí)行文件,而不是如“.c”的源代碼,因此,需要先通過gcc編譯生成可執(zhí)行文件才能用gdb進行調試。

[root@localhostgdb]#gdbtest

GNUgdbRedHatLinux(6.3.0.0-1.21rh)

Copyright2004FreeSoftwareFoundation,Inc.

GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouare

welcometochangeitand/ordistributecopiesofitundercertainconditions.

Type"showcopying"toseetheconditions.

ThereisabsolutelynowarrantyforGDB.Type"showwarranty"fordetails.

ThisGDBwasconfiguredas"i386-redhat-linux-gnu"...Usinghostlibthread_dblibrary"/lib/libthread_db.so.1".

(gdb)

可以看出,在gdb的啟動畫面中指出了gdb的版本號、使用的庫文件等信息,接下來就進入了由“(gdb)”開頭的命令行界面了。

(1)查看文件。

在gdb中鍵入“l”(list)就可以查看所載入的文件,如下所示。

注意

在gdb的命令中都可使用縮略形式的命令,如“l”代表“list”,“b”代表“breakpoint”,“p”代表“print”等,讀者也可使用“help”命令查看幫助信息。

(gdb)l

1#include<stdio.h>

2intsum(intm);

3intmain()

4{

5inti,n=0;

6sum(50);

7for(i=1;i<=50;i++)

8{

9 n+=i;

10}

(gdb)l

11printf("Thesumof1~50is%d\n",n);

12

13}

14intsum(intm)

15{

16inti,n=0;

17for(i=1;i<=m;i++)

18{

19n+=i;

20}

21printf("Thesumof1~mis=%d\n",n);

20}

可以看出,gdb列出的源代碼中明確地給出了對應的行號,這樣就可以大大地方便代碼的定位。

(2)設置斷點。

設置斷點是調試程序中一個非常重要的手段,它可以使程序運行到一定位置時暫停。因此,程序員在該位置處可以方便地查看變量的值、堆棧情況等,從而找出代碼的癥結所在。

在gdb中設置斷點非常簡單,只需在“b”后加入對應的行號即可(這是最常用的方式,另外還有其他方式設置斷點),如下所示:

(gdb)b6

Breakpoint1at0x804846d:filetest.c,line6.

要注意的是,在gdb中利用行號設置斷點是指代碼運行到對應行之前將其停止,如上例中,代碼運行到第6行之前暫停(并沒有運行第6行)。

(3)查看斷點情況。

在設置完斷點之后,用戶可以鍵入“infob”來查看設置斷點情況,在gdb中可以設置多個斷點。

(gdb)infob

NumTypeDispEnbAddressWhat

1breakpointkeepy0x0804846dinmainattest.c:6

用戶在斷點鍵入“backrace”(只輸入“bt”即可)可以查到調用函數(堆棧)的情況,這個功能在程序調試之中使用非常廣泛,經常用于排除錯誤或者監(jiān)視調用堆棧的情況。

(gdb)b19

(gdb)c

Breakpoin2,sum(m=50)attest.c:19

19printf(“Thesumof1-mis%d\n”,n);

(gdb)bt

#0sum(m=50)attest.c:19 /*停在test.c的sum()函數,第19行*/

#10x080483e8inmain()attest.c:6/*test.c的第6行調用sum函數*/

(4)運行代碼。

接下來就可運行代碼了,gdb默認從首行開始運行代碼,鍵入“r”(run)即可(若想從程序中指定行開始運行,可在r后面加上行號)。

(gdb)r

Startingprogram:/root/workplace/gdb/test

Readingsymbolsfromsharedobjectreadfromtargetmemory...done.

LoadedsystemsuppliedDSOat0x5fb000

Breakpoint1,main()attest.c:6

6sum(50);

可以看到,程序運行到斷點處就停止了。

(5)查看變量值。

在程序停止運行之后,程序員所要做的工作是查看斷點處的相關變量值。在gdb中鍵入“p”+變量值即可,如下所示:

(gdb)pn

$1=0

(gdb)pi

$2=134518440

在此處,為什么變量“i”的值為如此奇怪的一個數字呢?原因就在于程序是在斷點設置的對應行之前停止的,那么在此時,并沒有把“i”的數值賦為零,而只是一個隨機的數字。但變量“n”是在第4行賦值的,故在此時已經為零。

小技巧

gdb在顯示變量值時都會在對應值之前加上“$N”標記,它是當前變量值的引用標記,所以以后若想再次引用此變量就可以直接寫作“$N”,而無需寫冗長的變量名。

(6)單步運行。

單步運行可以使用命令“n”(next)或“s”(step),它們之間的區(qū)別在于:若有函數調用的時候,“s”會進入該函數而“n”不會進入該函數。因此,“s”就類似于Uisual等工具中的“stepin”,“n”類似與Uisual等工具中的“stepover”。它們的使用如下所示:

(gdb)n

Thesumof1-mis1275

7for(i=1;i<=50;i++)

(gdb)s

sum(m=50)attest.c:16

16inti,n=0;

可見,使用“n”后,程序顯示函數sum()的運行結果并向下執(zhí)行,而使用“s”后則進入sum()函數之中單步運行。

(7)恢復程序運行

在查看完所需變量及堆棧情況后,就可以使用命令“c”(continue)恢復程序的正常運行了。這時,它會把剩余還未執(zhí)行的程序執(zhí)行完,并顯示剩余程序中的執(zhí)行結果。以下是之前使用“n”命令恢復后的執(zhí)行結果:

(gdb)c

Continuing.

Thesumof1-50is:1275

Programexitedwithcode031.

可以看出,程序在運行完后退出,之后程序處于“停止狀態(tài)”。

小知識

在gdb中,程序的運行狀態(tài)有“運行”、“暫停”和“停止”3種,其中“暫停”狀態(tài)為程序遇到了斷點或觀察點之類的,程序暫時停止運行,而此時函數的地址、函數參數、函數內的局部變量都會被壓入“棧”(Stack)中。故在這種狀態(tài)下可以查看函數的變量值等各種屬性。但在函數處于“停止”狀態(tài)之后,“棧”就會自動撤消,它也就無法查看各種信息了。

3.4.2gdb基本命令

gdb的命令可以通過查看help進行查找,由于gdb的命令很多,因此gdb的help將其分成了很多種類(class),用戶可以通過進一步查看相關class找到相應命令,如下所示:

(gdb)help

Listofclassesofcommands:

aliases--Aliasesofothercommands

breakpoints--Makingprogramstopatcertainpoints

data--Examiningdata

files--Specifyingandexaminingfiles

internals--Maintenancecommands

Type"help"followedbyaclassnameforalistofcommandsinthatclass.

Type"help"followedbycommandnameforfulldocumentation.

Commandnameabbreviationsareallowedifunambiguous.

上述列出了gdb各個分類的命令,注意底部的加粗部分說明其為分類命令。接下來可以具體查找各分類的命令,如下所示:

(gdb)helpdata

Examiningdata.

Listofcommands:

call--Callafunctionintheprogram

deletedisplay--Cancelsomeexpressionstobedisplayedwhenprogramstops

deletemem--Deletememoryregion

disabledisplay--Disablesomeexpressionstobedisplayedwhenprogramstops

Type"help"followedbycommandnameforfulldocumentation.

Commandnameabbreviationsareallowedifunambiguous.

若用戶想要查找call命令,就可鍵入“helpcall”。

(gdb)helpcall

Callafunctionintheprogram.

Theargumentisthefunctionnameandarguments,inthenotationofthe

currentworkinglanguage.Theresultisprintedandsavedinthevalue

history,ifitisnotvoid.

當然,若用戶已知命令名,直接鍵入“help[command]”也是可以的。

gdb中的命令主要分為以下幾類:工作環(huán)境相關命令、設置斷點與恢復命令、源代碼查看命令、查看運行數據相關命令及修改運行參數命令。以下就分別對這幾類命令進行講解。

1.工作環(huán)境相關命令

gdb中不僅可以調試所運行的程序,而且還可以對程序相關的工作環(huán)境進行相應的設定,甚至還可以使用shell中的命令進行相關的操作,其功能極其強大。gdb常見工作環(huán)境相關命令如表3.11所示。

表3.11 gdb工作環(huán)境相關命令

命令格式

含義

setargs運行時的參數

指定運行時參數,如setargs2

showargs

查看設置好的運行參數

Pathdir

設定程序的運行路徑

showpaths

查看程序的運行路徑

setenvironmentvar[=value]

設置環(huán)境變量

showenvironment[var]

查看環(huán)境變量

cddir

進入dir目錄,相當于shell中的cd命令

Pwd

顯示當前工作目錄

shellcommand

運行shell的command命令

2.設置斷點與恢復命令

gdb中設置斷點與恢復的常見命令如表3.12所示。

表3.12 gdb設置斷點與恢復相關命令

命令格式

含義

Infob

查看所設斷點

break[文件名:]行號或函數名<條件表達式>

設置斷點

tbreak[文件名:]行號或函數名<條件表達式>

設置臨時斷點,到達后被自動刪除

delete[斷點號]

刪除指定斷點,其斷點號為“infob”中的第一欄。若缺省斷點號則刪除所有斷點

disable[斷點號]

停止指定斷點,使用“infob”仍能查看此斷點。同delete一樣,若缺省斷點號則停止所有斷點

enable[斷點號]

激活指定斷點,即激活被disable停止的斷點

condition[斷點號]<條件表達式>

修改對應斷點的條件

ignore[斷點號]<num>

在程序執(zhí)行中,忽略對應斷點num次

Step

單步恢復程序運行,且進入函數調用

Next

單步恢復程序運行,但不進入函數調用

Finish

運行程序,直到當前函數完成返回

C

繼續(xù)執(zhí)行函數,直到函數結束或遇到新的斷點

設置斷點在gdb的調試中非常重要,下面著重講解gdb中設置斷點的方法。

gdb中設置斷點有多種方式:其一是按行設置斷點;另外還可以設置函數斷點和條件斷點。下面具體介紹后兩種設置斷點的方法。

①函數斷點。

gdb中按函數設置斷點只需把函數名列在命令“b”之后,如下所示:

(gdb)btest.c:sum(可以簡化為bsum)

Breakpoint1at0x80484ba:filetest.c,line16.

(gdb)infob

NumTypeDispEnbAddressWhat

1breakpointkeepy0x080484bainsumattest.c:16

要注意的是,此時的斷點實際是在函數的定義處,也就是在16行處(注意第16行還未執(zhí)行)。

②條件斷點。

gdb中設置條件斷點的格式為:b行數或函數名if表達式。具體實例如下所示:

(gdb)b8ifi==10

Breakpoint1at0x804848c:filetest.c,line8.

(gdb)infob

NumTypeDispEnbAddressWhat

1breakpointkeepy0x0804848cinmainattest.c:8

stoponlyifi==10

(gdb)r

Startingprogram:/home/yul/test

Thesumof1-mis1275

Breakpoint1,main()attest.c:9

9n+=i;

(gdb)pi

$1=10

可以看到,該例中在第8行(也就是運行完第7行的for循環(huán))設置了一個“i==0”的條件斷點,在程序運行之后可以看出,程序確實在i為10時暫停運行。

3.gdb中源碼查看相關命令

在gdb中可以查看源碼以方便其他操作,它的常見相關命令如表3.13所示。

表3.13 gdb源碼查看相關相關命令

命令格式

含義

list<行號>|<函數名>

查看指定位置代碼

file[文件名]

加載指定文件

forward-search正則表達式

源代碼的前向搜索

reverse-search正則表達式

源代碼的后向搜索

dirDIR

將路徑DIR添加到源文件搜索的路徑的開頭

showdirectories

顯示源文件的當前搜索路徑

infoline

顯示加載到gdb內存中的代碼

4.gdb中查看運行數據相關命令

gdb中查看運行數據是指當程序處于“運行”或“暫停”狀態(tài)時,可以查看的變量及表達式的信息,其常見命令如表3.14所示。

表3.14 gdb查看運行數據相關命令

命令格式

含義

print表達式|變量

查看程序運行時對應表達式和變量的值

x<n/f/u>

查看內存變量內容。其中n為整數表示顯示內存的長度,f表示顯示的格式,u表示從當前地址往后請求顯示的字節(jié)數

display表達式

設定在單步運行或其他情況中,自動顯示的對應表達式的內容

backtrace

查看當前棧的情況,即可以查到哪些被調用的函數尚未返回

5.gdb中修改運行參數相關命令

gdb還可以修改運行時的參數,并使該變量按照用戶當前輸入的值繼續(xù)運行。它的設置方法為:在單步執(zhí)行的過程中,鍵入命令“set變量=設定值”。這樣,在此之后,程序就會按照該設定的值運行了。下面,筆者結合上一節(jié)的代碼將n的初始值設為4,其代碼如下所示:

(gdb)b7

Breakpoint5at0x804847a:filetest.c,line7.

(gdb)r

Startingprogram:/home/yul/test

Thesumof1-mis1275

Breakpoint5,main()attest.c:7

7for(i=1;i<=50;i++)

(gdb)setn=4

(gdb)c

Continuing.

Thesumof1-50is1279

Programexitedwithcode031.

可以看到,最后的運行結果確實比之前的值大了4。

注意

gdb使用時的注意點:

·在gcc編譯選項中一定要加入“-g”。

·只有在代碼處于“運行”或“暫停”狀態(tài)時才能查看變量值。

·設置斷點后程序在指定行之前停止。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統(tǒng) 散熱

根據LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉