uClinux下應(yīng)用程序開發(fā)課件_第1頁
uClinux下應(yīng)用程序開發(fā)課件_第2頁
uClinux下應(yīng)用程序開發(fā)課件_第3頁
uClinux下應(yīng)用程序開發(fā)課件_第4頁
uClinux下應(yīng)用程序開發(fā)課件_第5頁
已閱讀5頁,還剩48頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

開發(fā)工具GNU的使用

GNU軟件包括C編譯器GCC,C++編譯器G++,匯編器AS,鏈接器LD,二進(jìn)制轉(zhuǎn)換工具(OBJCOPY,OBJDUMP),調(diào)試工具(GDB,GDBSERVER,KGDB)和基于不同硬件平臺的開發(fā)庫。在GNUGCC支持下用戶可以使用流行的C/C++語言開發(fā)應(yīng)用程序,滿足生成高效率運(yùn)行代碼、易掌握的編程語言的用戶需求。

GNU開發(fā)工具都是采用命令行的方式,用戶掌握起來相對比較困難,不如基于Windows系統(tǒng)的開發(fā)工具好用,但是GNU工具的復(fù)雜性是由于它更貼近編譯器和操作系統(tǒng)的底層,并提供了更大的靈活性。一旦學(xué)習(xí)和掌握了相關(guān)工具后,就了解了系統(tǒng)設(shè)計的基礎(chǔ)知識。 運(yùn)行于Linux操作系統(tǒng)下的自由軟件GNUgcc編譯器,不僅可以編譯Linux操作系統(tǒng)下運(yùn)行的應(yīng)用程序,還可以編譯Linux內(nèi)核本身,甚至可以作交叉編譯,編譯運(yùn)行于其它CPU上的程序。所以,在進(jìn)行嵌入式系統(tǒng)應(yīng)用程序開發(fā)時,這些工具得到了日益廣泛的應(yīng)用。GCC編譯器

GCC是GNU組織的免費(fèi)C編譯器,Linux的很多發(fā)布缺省安裝的就是這種。很多流行的自由軟件源代碼基本都能在GCC編譯器下編譯運(yùn)行。所以掌握GCC編譯器的使用無論是對于編譯系統(tǒng)內(nèi)核還是自己的應(yīng)用程序都是大有好處的。 下面通過一個具體的例子,學(xué)習(xí)如何使用GCC編譯器。 在Linux操作系統(tǒng)中,對一個用標(biāo)準(zhǔn)C語言寫的源程序進(jìn)行編譯,要使用GNU的gcc編譯器。

要編譯這個程序,我們只要在Linux的bash提示符下輸入命令:

$gcc-ohellohello.c gcc編譯器就會生成一個hello的可執(zhí)行文件。在hello.c的當(dāng)前目錄下執(zhí)行./hello就可以看到程序的輸出結(jié)果,在屏幕上打印出“Hellotheworld”的字符串來。

命令行中

gcc表示是用gcc來編譯源程序;-ooutput選項表示要求編譯器生成文件名為output的可執(zhí)行文件,如果不指定-o選項,則缺省文件名是

a.out。在這里生成指定文件名為hello的可執(zhí)行文件,而hello.c是我們的源程序文件。gcc是一個多目標(biāo)的工具。gcc最基本的用法是: gcc[options]file... 其中的option是以-開始的各種選項,file是相關(guān)的文件名。在使用gcc的時候,必須要給出必要的選項和文件名。gcc的整個編譯過程,實(shí)質(zhì)上是分四步進(jìn)行的,每一步完成一個特定的工作,這四步分別是:預(yù)處理,編譯,匯編和鏈接。它具體完成哪一步,是由gcc后面的開關(guān)選項和文件類型決定的gcc編譯器有許多選項,但對于普通用戶來說只要知道其中常用的幾個就夠了。在這里為讀者列出幾個最常用的選項:-o選項表示要求編譯器生成指定文件名的可執(zhí)行文件;-c選項表示只要求編譯器進(jìn)行編譯,而不要進(jìn)行鏈接,生成以源文件的文件名命名但把其后綴由.c或.cc變成.o的目標(biāo)文件;-g選項要求編譯器在編譯的時候提供以后對程序進(jìn)行調(diào)試的信息;-E選項表示編譯器對源文件只進(jìn)行預(yù)處理就停止,而不做編譯,匯編和鏈接;-S選項表示編譯器只進(jìn)行編譯,而不做匯編和鏈接;-O選項是編譯器對程序提供的編譯優(yōu)化選項,在編譯的時候使用該選項,可以使生成的執(zhí)行文件的執(zhí)行效率提高;-Wall選項指定產(chǎn)生全部的警告信息。 GNU編譯器生成的目標(biāo)文件缺省格式為elf(executivelinkedfile)格式,這是Linux系統(tǒng)所采用的可執(zhí)行鏈接文件的通用文件格式。elf格式由若干段(section)組成,如果沒有特別指明,由標(biāo)準(zhǔn)c源代碼生成的目標(biāo)文件中包含以下段:.text(正文段)包含程序的指令代碼,.data(數(shù)據(jù)段)包含固定的數(shù)據(jù),如常量,字符串等,.bss(未初始化數(shù)據(jù)段)包含未初始化的變量和數(shù)組等。

當(dāng)改變了源文件hello.c后,需要重新編譯它:$gcc-chello.c然后重新鏈接生成:$gcc–ohello.o 對于本例,因?yàn)橹缓幸粋€源文件,所以當(dāng)改動了源碼后,進(jìn)行重新的編譯鏈接的過程顯得并不是太繁瑣,但是,如果在一個工程中包含了若干的源碼文件,而這些源碼文件中的某個或某幾個又被其他源碼文件包含,那么,如果一個文件被改動,則包含它的那些源文件都要進(jìn)行重新編譯鏈接,工作量是可想而知的。GNU提供了使這個步驟變得簡單的工具,就是下面要介紹給大家的GNUMake工具

GNUMake

make是負(fù)責(zé)從項目的源代碼中生成最終可執(zhí)行文件和其他非源代碼文件的工具。make命令本身可帶有四種參數(shù):標(biāo)志、宏定義、描述文件名和目標(biāo)文件名。其標(biāo)準(zhǔn)形式為:make[flags][macrodefinitions][targets] 通過命令行參數(shù)中的target,可指定make要編譯的目標(biāo),并且允許同時定義編譯多個目標(biāo),操作時按照從左向右的順序依次編譯target選項中指定的目標(biāo)文件。如果命令行中沒有指定目標(biāo),則系統(tǒng)默認(rèn)target指向描述文件中第一個目標(biāo)文件。

make如何實(shí)現(xiàn)對源代碼的操作是通過一個被稱之為makefile的文件來完成的,在下面的小節(jié)里,主要向讀者介紹一下makefile的相關(guān)知識

makefile基本結(jié)構(gòu)

GNUMake的主要工作是讀一個文本文件

makefile。makefile

是用bash語言寫的,bash語言是很像BASIC語言的一種命令解釋語言。這個文件里主要描述了有關(guān)哪些目標(biāo)文件是從哪些依賴文件中產(chǎn)生的,是用何種命令來進(jìn)行這個產(chǎn)生過程的。有了這些信息,

make會檢查磁盤的文件,如果目標(biāo)文件的日期(即該文件生成或最后修改的日期)至少比它的一個依賴文件日期早的話,make就會執(zhí)行相應(yīng)的命令,以更新目標(biāo)文件。

makefile一般被稱為“makefile”或“Makefile”。還可以在

make的命令行中指定別的文件名。如果沒有特別指定的話,make就會尋找“makefile”或“Makefile”,所以為了簡單起見,建議讀者使用這兩名字。如果要使用其他文件作為

makefile,則可利用類似下面的

make命令選項指定

makefile文件:

$make-fmake一個

makefile主要含有一系列的規(guī)則,如下:

目標(biāo)文件名:依賴文件名(tab鍵)命令

第一行稱之為規(guī)則,第二行是執(zhí)行規(guī)則的命令,必須要以tab鍵開始。

下面舉一個簡單的makefile的例子。

executable:main.oio.o

gccmain.oio.o-oexecutable

main.o:main.c

gcc-Wall-O-g-cmain.c-omain.o

io.o:io.c

gcc-Wall-O-g-cio.c-oio.o

現(xiàn)在,

再回到第一個規(guī)則處,如果剛才兩個規(guī)則中的任何一個被執(zhí)行,最終的目標(biāo)文件executable都需要重建(因?yàn)閑xecutable所依賴的其中一個.o文件就會比它新),因此鏈接命令就會被執(zhí)行。

有了makefile,對任何一個源文件進(jìn)行修改后,所有依賴于該文件的目標(biāo)文件都會被重新編譯(因?yàn)?o文件依賴于.c文件),進(jìn)而最終可執(zhí)行文件會被重新鏈接(因?yàn)樗蕾嚨?o文件被改變了),再也不用手工去一個個修改了。

編寫Makefile1、Makefile宏定義 makefile里的宏是大小寫敏感的,一般都使用大寫字母。它們幾乎可以從任何地方被引用,可以代表很多類型,例如可以存儲文件名列表,存儲可執(zhí)行文件名和編譯器標(biāo)志等。 要定義一個宏,在makefile中,任意一行的開始寫下該宏名,后面跟一個等號,等號后面是要設(shè)定的這個宏的值。如果以后要引用到該宏時,使用$(宏名),或者是${宏名},注意宏名一定要寫在圓或花括號之內(nèi)。把上一小節(jié)所舉的例子,用引入宏名的方法,可以寫成下面的形式:OBJS=main.oio.oCC=gccCFLAGS=-Wall-O-gexecutable:$(OBJS) $(CC)$(OBJS)-oexecutablemain.o:main.c $(CC)$(CFLAGS)-cmain.c-omain.oio.o:io.c $(CC)$(CFLAGS)-cio.c-oio.o利用這些變量,可以把上面的

makefile寫成:OBJS=main.oio.oCC=gccCFLAGS=-Wall-O-gexecutable:$(OBJS) $(CC)$^-o$@main.o:main.c $(CC)$(CFLAGS)–c$<-o$@io.o:io.c $(CC)$(CFLAGS)-c$<-o$@ 可以將宏變量應(yīng)用到其他許多地方,尤其是當(dāng)把它們和函數(shù)混合使用的時候,正確使用宏,會給開發(fā)者帶來極大的便利

2、隱含規(guī)則

請注意,在上面的例子里,幾個產(chǎn)生.o文件的命令都是以.c文件作為依賴文件產(chǎn)生.o目標(biāo)(obj)文件,這是一個標(biāo)準(zhǔn)的生成目標(biāo)文件的步驟。如果把生成main.o和io.o的規(guī)則從makefile中刪除,make會查找它的隱含規(guī)則,然后會找到一個適當(dāng)?shù)拿钊?zhí)行。實(shí)際上make已經(jīng)知道該如何生成這些目標(biāo)文件,它使用變量

CC做為編譯器,并且傳遞宏

CFLAGS給

C編譯器(CXXFLAGS用于

C++編譯器),CPPFLAGS(C預(yù)處理選項),

TARGET_ARCH(就目前例子而言,還不用考慮這個宏),然后它加入開關(guān)選項-c,后面跟預(yù)定義宏$<(第一個依賴文件名),最后是開關(guān)項-o,后跟預(yù)定義宏$@(目標(biāo)文件名)。一個C編譯的具體命令將

會是:$(CC)$(CFLAGS)$(CPPFLAGS)$(TARGET_ARCH)-c$<-o$@

在make工具中所包含的這些內(nèi)置的或隱含的規(guī)則,定義了如何從不同的依賴文件建立特定類型的目標(biāo)。Unix系統(tǒng)通常支持一種基于文件擴(kuò)展名即文件名后綴的隱含規(guī)則。這種后綴規(guī)則定義了如何將一個具有特定文件名后綴的文件(例如.c文件),轉(zhuǎn)換成為具有另一種文件名后綴的文件(例如.o文件):系統(tǒng)中默認(rèn)的常用文件擴(kuò)展名及其含義為: .o

目標(biāo)文件

.c

C源文件

.f

FORTRAN源文件

.s

匯編源文件

.y

Yacc-C源語法

.l

Lex源語法

而GNUmake除了支持后綴規(guī)則外還支持另一種類型的隱含規(guī)則即模式規(guī)則。這種規(guī)則更加通用,因?yàn)榭梢岳媚J揭?guī)則定義更加復(fù)雜的依賴性規(guī)則。同時可用來定義目標(biāo)和依賴文件之間的關(guān)系,例如下面的模式規(guī)則定義了如何將任意一個.c文件轉(zhuǎn)換為文件名相同的.o文件:

%.o:%.c

$(CC)$(CFLAGS)$(CPPFLAGS)-c-o$@$<

這里

executable1和executable2是最終希望生成的兩個可執(zhí)行文件。

make把這個'all'做為它的主要目標(biāo),每次執(zhí)行時都會嘗試把'all'更新。但是,由于這行規(guī)則里并沒有命令來作用在一個叫'all'的實(shí)際文件上(事實(shí)上,

all也不會實(shí)際生成),所以這個規(guī)則并不真的改變'all'的狀態(tài)。可既然這個文件并不存在,所以

make會嘗試更新

all規(guī)則,因此就檢查它的依賴文件

executable1,exectable2是否需要更新,如果需要,就把它們更新,從而達(dá)到生成兩個目標(biāo)文件的目的。

偽目標(biāo)在makefile中廣泛使用

4、函數(shù)

makefile里的函數(shù)跟它的宏很相似,在使用的時候,用一個$符號開始后跟圓括號,在圓括號內(nèi)包含函數(shù)名,空格后跟一系列由逗號分隔的參數(shù)。例如,在

GNUMake里有一個名為'wildcard'的函

數(shù),它只有一個參數(shù),功能是展開成一列所有符合由其參數(shù)描述的文件名,文件間以空格間隔??梢韵裣旅嫠臼褂眠@個命令:

SOURCES=$(wildcard*.c)

這樣會產(chǎn)生一個所有以'.c'結(jié)尾的文件的列表,然后存入變量

SOURCES里。當(dāng)然你不需要一定要把結(jié)果存入一個變量。

CFLAGS+=$(EXT_CC_OPTS)CFLAGS+=$(RTM_CC_OPTS)SRCS=tune1.crt_sim.crt_nonfinite.c\grt_main.crt_logging.c\ext_svr.cupdown.cext_svr_transport.c\ext_work.cOBJS=$(SRCS:.c=.o)RM=rm–fCC=gccLD=gccall:tune1%.o:%.c $(CC)-c-o$@$(CFLAGS)$(INCLUDES)$<tune1:$(OBJS) $(LD)-o$@$(OBJS)-lmclean: $(RM)$(OBJS在這個makefile中首先定義了十個宏:'INCLUDES=-I…'(省略號代表-I后面的內(nèi)容),'-Idirname'表示將dirname所指的目錄加入到程序頭文件目錄列表中去,是在進(jìn)行預(yù)處理過程中使用的參數(shù);'EXT_CC_OPTS=-DEXT_MODE'表示在程序中定義了宏EXT_MODE,等價于在源代碼寫入語句'#defineEXT_MODE';接下來的兩個宏定義CPP_REQ_DEFINES和RTM_CC_OPTS起到和EXT_CC_OPTS類似的作用;'CFLAGS=-O-g'是編譯器的編譯選項,表示在編譯的過程中對代碼進(jìn)行基本優(yōu)化,并產(chǎn)生能被GNU調(diào)試器(如gdb)使用的調(diào)試信息;'CFLAGS+='表示對這個宏定義在原來的基礎(chǔ)上增加新的內(nèi)容;'SRCS=…'代表了所有要編譯的源代碼文件列表;'OBJS=$(SRCS:.c=.o)'表示把宏SRC所代表的所有以.c結(jié)尾的文件名用.o結(jié)尾的文件名替換,即表示各個源文件所對應(yīng)的目標(biāo)文件名;'RM=rm–f'表示刪除命令,-f是強(qiáng)制刪除選項,使用該符號,在對文件進(jìn)行刪除時,沒有提示;'CC=gcc'表示編譯器是用gcc;'LD=gcc'表示鏈接命令是用gcc;

all和clean是兩個偽目標(biāo),在使用make命令的時候,如果不指明目標(biāo)文件名,則是以在makefile中出現(xiàn)的第一個目標(biāo)作為最終目標(biāo),所以如果鍵入命令make,則偽目標(biāo)all被作為最終的目標(biāo)而執(zhí)行,由于這個文件并不存在,所以

make會嘗試更新

all規(guī)則,因此就檢查它的依賴文件

tune1是否需要更新,如果需要,就把它更新,這樣偽目標(biāo)下面的兩條規(guī)則就會被執(zhí)行,從而生成可執(zhí)行文件tune1。如果要執(zhí)行刪除命令,只需要鍵入命令makeclean,就會把所有以.o結(jié)尾的中間文件刪除。

另外,請注意在本makefile的例子中多次用到'\',該符號用于在makefile中,如果一條語句過長時,可以用'\'放在這條語句的右邊界,通過回車換行,使下面新一行的語句成為該語句的續(xù)行。在makefile文件中,用符號'#'作為注釋行語句的開始,以增強(qiáng)makefile文件的可讀性。 本例假設(shè)makefile文件名為makefile,當(dāng)然也可按照個人的喜好取其他文件名,如果文件名不是makefile,Makefile的話,在用make命令是,請使用make–fmake。

使用GDB調(diào)試程序

無論是多么資深的程序員在編寫的程序時,都不大可能一次性就會成功,在程序運(yùn)行時,會出現(xiàn)許許多多意想不到的錯誤,一味地只是查看程序用處不大,最有效的方法通過一些手段進(jìn)入到程序內(nèi)部進(jìn)行調(diào)試。通常在調(diào)試程序的時候如果能夠得到以下一些信息,對于開發(fā)者找到錯誤所在是很有幫助的。1 1

程序是運(yùn)行到哪個語句或者表達(dá)式就發(fā)生了錯誤?2 2

如果錯誤是在執(zhí)行一個函數(shù)的時候出現(xiàn)的,那么是程序的哪一行包含了這個函數(shù)的調(diào)用語句,在調(diào)用該函數(shù)的時候傳遞的實(shí)參是什么?

3 3

在程序執(zhí)行到某處時,所關(guān)心的某一個變量值為多少? 4某個表達(dá)式最終運(yùn)行的結(jié)果為何值?

調(diào)試器(更準(zhǔn)確地說應(yīng)該稱為符號調(diào)試器)能夠完成上述目標(biāo)。它是一個能夠運(yùn)行其他程序的應(yīng)用程序,它和普通意義上的程序的唯一不同之處在于,調(diào)試器能夠進(jìn)入到程序源碼中,允許開發(fā)者進(jìn)行逐行單步運(yùn)行,了解程序代碼執(zhí)行順序,和每條語句執(zhí)行的結(jié)果,可以在程序運(yùn)行的同時,查看甚至是改變?nèi)我蛔兞恐?。在程序運(yùn)行出錯時,它為程序開發(fā)者提供程序運(yùn)行時的詳細(xì)細(xì)節(jié),從而找到出錯的原因。在Linux系統(tǒng)中,最常用到的就是GDB(GNUDegugger)。GDB是GNU自帶的調(diào)試工具。

1GDB常用命令

要想使用gdb,必須在對源碼進(jìn)行編譯的時候,使用-g編譯選項開關(guān),來通知編譯器,開發(fā)者希望進(jìn)行程序調(diào)試。用了-g選項后,程序在編譯的時候就會包含調(diào)試信息,這些調(diào)試信息存在目標(biāo)文件中,它描述了每個函數(shù)或變量的數(shù)據(jù)類型以及源碼行號和可執(zhí)行代碼地址間對應(yīng)關(guān)系,gdb正是通過這些信息使源碼和機(jī)器碼相關(guān)聯(lián)的,它實(shí)現(xiàn)了源碼級的調(diào)試。 為了使用gdb調(diào)試,只需要在命令行中輸入gdb(是用gcc編譯生成的最終可執(zhí)行文件名),該語句啟動與調(diào)試器的文本接口。就在上一小節(jié)中所舉makefile例子來說,就是鍵入gdbtune1,則在屏幕上會出現(xiàn):[nie@uClinuxmysrc]$gdbtune1GNUgdbRedHatLinux7.x(5.0rh-15)(MI_OUT)Copyright2001FreeSoftwareFoundation,Inc.GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouarewelcometochangeitand/ordistributecopiesofitundercertainconditions.Type"showcopying"toseetheconditions.ThereisabsolutelynowarrantyforGDB.Type"showwarranty"fordetails.ThisGDBwasconfiguredas"i386-redhat-linux"...(gdb)

gdb雖然運(yùn)行起來,但是可執(zhí)行程序tune1并沒有運(yùn)行,此時在gdb提示符下直接鍵入run命令即可,如果可執(zhí)行程序在運(yùn)行的時候需要輸入命令行參數(shù),則在gdb提示符下可以這樣鍵入命令:runcommand-line-arguments,就如同是輸入命令:tune1command-line-arguments一樣,啟動了可執(zhí)行程序的運(yùn)行。

有時候,我們希望能夠斷點(diǎn)調(diào)試程序,讓程序執(zhí)行到代碼某處時停止繼續(xù)執(zhí)行下去,此時可以使用命令break,該命令的格式為breakplace,這里place可以是程序代碼的行號,某函數(shù)名,甚至可以是用breakmain,讓程序斷點(diǎn)設(shè)置在代碼一開始執(zhí)行的地方,比如對于上面舉的可執(zhí)行文件名為tune1的例子,它調(diào)用了一個函數(shù)名為rtExtModeCheckInit的子函數(shù),如果想讓程序執(zhí)行到該函數(shù)處停止,可以在gdb提示符下輸入:breakrtExtModeCheckInit,此時屏幕上出現(xiàn)下列信息:Breakpoint1at0x8049a28:,line604.。當(dāng)然,也可以使用行號設(shè)置中斷位置,上面設(shè)置中斷的語句可以等價為break604,可以在屏幕上看到相同的效果。

當(dāng)設(shè)置了斷點(diǎn)后,程序會運(yùn)行到斷點(diǎn)處停下來,此時從屏幕上可以得到類似下面的信息:Breakpoint1,main(argc=4,argv=0xbffffb84)atgrt_main.c:604604

rtExtModeCheckInit();(gdb) 當(dāng)想將某個斷點(diǎn)除去,可以在gdb提示符下輸入命令:deleteN,這里N表示第幾個中斷,第一個設(shè)置的中斷序號為1,第二個設(shè)置的序號為2,依次類推。如果delete后不跟任何序號,在表示把設(shè)置的所有斷點(diǎn)都刪除。如果想查看目前設(shè)置斷點(diǎn)的情況,可以使用命令infobreak,屏幕會顯示出每一個設(shè)置的斷點(diǎn)信息

在gdb提示符下使用help命令,會給出有關(guān)gdb命令的一個簡短描述和命令分類。 如果開發(fā)者想進(jìn)入到程序內(nèi)部進(jìn)行單步調(diào)試,gdb提供兩種命令供選擇,step和next命令,兩者的區(qū)別在于step執(zhí)行每一條語句,如果遇到函數(shù)調(diào)用,會跳轉(zhuǎn)到到該函數(shù)定義的開始行去執(zhí)行,而next則不進(jìn)入到函數(shù)內(nèi)部,它把函數(shù)調(diào)用語句當(dāng)作普通一條語句執(zhí)行完成。continue命令是繼續(xù)運(yùn)行程序,直到遇到下一個斷點(diǎn)或程序結(jié)束。 有時候使用者僅僅是在linux的bash提示符下輸入命令gdb后,啟動了gdb而已,此時,如果要加載可執(zhí)行文件,需要在gdb提示符下鍵入命令:(為可執(zhí)行文件名),注意是可執(zhí)行文件的名字而不是源文件名。當(dāng)在調(diào)試過程中,想查看一個變量值的時候,可以在gdb環(huán)境下輸入命令:watchvariablename,這里的variablename是你想觀察的變量名。 還有一個可以顯示表達(dá)式值的命令print,其使用規(guī)則為printexpressionname,其中expressionname為要顯示的表達(dá)式名

2GDB具體調(diào)試實(shí)例

下面通過使用一個簡單的程序使讀者進(jìn)一步熟悉用gdb的調(diào)試方法。源程序名為example1.c,代碼如下:/********************************************************InstituteofAutomation,ChineseAcademyofSciences*: example.c*Description:introducehowtousegdb*Author: XueyuanNie*Date:

*******************************************************/#include<stdio.h>staticvoiddisplay(inti,int*ptr);intmain(void){intx=5;int*xptr=&x; printf("Inmain():\n");printf("xis%dandisstoredat%p.\n",x,&x);printf("xptrholds%pandpointsto%d.\n",xptr,*xptr);display(x,xptr);return0;}voiddisplay(intz,int*zptr){ printf("Indisplay():\n");printf("zis%dandisstoredat%p.\n",z,&z);printf("zptrholds%pandpointsto%d.\n",zptr,*zptr);}

要使用gdb調(diào)試程序,一定要在編譯程序時,使用-g編譯選項,以生成參數(shù)符號表(augmentedsymboltable),提供調(diào)試信息。 首先使用gcc–g–oexample1example.c對源代碼進(jìn)行編譯,這樣就可以使用gdb監(jiān)視example1的執(zhí)行細(xì)節(jié)。在bash提示符下,鍵入命令:gdbexample1,啟動了對可執(zhí)行文件example1的調(diào)試,在屏幕上會出現(xiàn)下面的信息:

[nie@uClinuxnie]$gdbexample1GNUgdbRedHatLinux7.x(5.0rh-15)(MI_OUT)Copyright2001FreeSoftwareFoundation,Inc.GDBisfreesoftware,coveredbytheGNUGeneralPublicLicense,andyouarewelcometochangeitand/ordistributecopiesofitundercertainconditions.Type"showcopying"toseetheconditions.ThereisabsolutelynowarrantyforGDB.Type"showwarranty"fordetails.ThisGDBwasconfiguredas"i386-redhat-linux"...(gdb) 最后一行(gdb)就是進(jìn)入到gdb調(diào)試中的提示符,此時可以在提示符下輸入任何想鍵入的命令。

現(xiàn)在如果要進(jìn)行斷點(diǎn)調(diào)試的話,就需要顯示一下要調(diào)試的源碼,以便知道在哪個地方進(jìn)行斷點(diǎn)設(shè)置。在gdb下,Linux最常用文本編輯命令vi不能使用,可以使用list命令列出可執(zhí)行文件的源代碼的一部分,為了列出源代碼的全部,只要多鍵入幾次list命令即可。具體操作如下: (gdb)list 屏幕上清楚顯示出了每一個語句所在的具體行號,比如現(xiàn)在我們想在第五行設(shè)置斷點(diǎn),可以在gdb提示符下輸入命令:break5,可以看到下面的顯示信息:(gdb)break5Breakpoint1at0x8048466:,line5. 斷點(diǎn)已經(jīng)設(shè)置好,現(xiàn)在開始讓程序運(yùn)行起來,鍵入命令run,也可以鍵入其縮寫形式r,屏幕上出現(xiàn)的信息如下:(gdb)rStartingprogram:/home/nie/example1Breakpoint1,main()atexample1.c:55intx=5;

上述信息表明,gdb已經(jīng)開始執(zhí)行可執(zhí)行程序,目前程序運(yùn)行到example1.c程序中main()函數(shù)的第五行處停止,并且顯示出即將要執(zhí)行的第五行語句?,F(xiàn)在我們進(jìn)行單步調(diào)試的工作,輸入命令:next,它表明單步執(zhí)行程序的每一條語句,當(dāng)用next命令執(zhí)行到函數(shù)display處時,即當(dāng)屏幕出現(xiàn)如下所示信息時:(gdb)next6int*xptr=&x;(gdb)next7printf("Inmain():\n");(gdb)nextInmain():8printf("xis%dandisstoredat%p.\n",x,&x);(gdb)nextxis5andisstoredat0xbffffb44.9printf("xptrholds%pandpointsto%d.\n",xptr,*xptr);(gdb)nextxptrholds0xbffffb44andpointsto5.10display(x,xptr);

為了進(jìn)入到函數(shù)display內(nèi)部進(jìn)行調(diào)試,輸入命令step,即:(gdb)stepdisplay(z=5,zptr=0xbffffb44)atexample1.c:1515printf("Indisplay():\n");step命令使執(zhí)行進(jìn)入到函數(shù)內(nèi)部,此時在該函數(shù)內(nèi)部,可以繼續(xù)使用step命令或者是next命令進(jìn)行單步執(zhí)行,如果不想單步執(zhí)行,而是直接將程序一次執(zhí)行完畢,可以輸入命令continue即可。

要退出gdb,請鍵入命令quit,如果程序此時仍在進(jìn)行,gdb會讓你確認(rèn)是否真的要退出,屏幕會出現(xiàn)類似下面的提示信息:(gdb)quitTheprogramisrunning.Exitanyway?(yorn) 按下‘y’即退出調(diào)試程序,如果程序本身已經(jīng)運(yùn)行完畢,則

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論