|
在linux環(huán)境的開(kāi)發(fā)中我們經(jīng)常遇到一些問(wèn)題,他不像在板子上裸機(jī)開(kāi)發(fā)那么方便,直接jlink連著就能debug,linux下我們總是通過(guò)printf打印來(lái)看程序跑到哪里了,或者打印一些變量的實(shí)時(shí)信息,這種方法簡(jiǎn)單沒(méi)門檻,但是每次改點(diǎn)兒東西就要重新編譯,編譯完后還需要重載程序,非常麻煩
用GNUdebug方法就方便多了,這是一個(gè)可以在linux系統(tǒng)下實(shí)現(xiàn)代碼debug功能的東西,可以打斷點(diǎn),步進(jìn)運(yùn)行程序,實(shí)時(shí)監(jiān)控變量,棧,甚至可以根據(jù)自己的想法實(shí)時(shí)控制程序往哪跑,唯一美中不足的是linux下沒(méi)有圖形操作界面。
1、想實(shí)現(xiàn)GDB,首先要保證開(kāi)發(fā)板和自己的linux虛擬機(jī)能通信,通信不上的可以看看我另一篇帖子
2、在官網(wǎng)下載GDB gnu網(wǎng)/software/gdb/download/ 下載源碼,下載完成后,上存到Ubuntu進(jìn)行解壓,解壓完以后編譯,并且install。我使用的是7.8.2版本,其實(shí)我們從網(wǎng)上下別人的源碼庫(kù)來(lái)自己編譯,經(jīng)常會(huì)編譯報(bào)錯(cuò)的,這個(gè)時(shí)候需要自己進(jìn)去里面改改代碼。我附件會(huì)帶一個(gè)我改好的,不知道咋改的同學(xué)可以直接用,當(dāng)然我更希望大神能調(diào)試好更高版本的也分享一下。
解壓后進(jìn)入build目錄下執(zhí)行../configure--target=arm-linux--prefix=/work/tools/gdb
然后執(zhí)行make,make完以后執(zhí)行make install 可執(zhí)行文件會(huì)放到/work/tools/gdb/bin下,每次使用gdb的時(shí)候需要使用絕對(duì)路徑啟動(dòng)這個(gè)可執(zhí)行程序,嫌麻煩可以自己配一下環(huán)境變量
3、在開(kāi)發(fā)板上移植gdbserver ,gdbserver 是在開(kāi)發(fā)板上運(yùn)行的,因此要交叉編譯
進(jìn)入gdb-7.8.2/gdb/gdbserver目錄
執(zhí)行../configure--target=arm-linux--host=arm-linux 配置
make CC=arm-linux-gcc交叉編譯//這一步各自看看自己的芯片用的哪個(gè)交叉編譯工具,不兼容的話編出來(lái)的東西跑不起來(lái)的
交叉編譯完后把生成的gdbserver 文件放到開(kāi)發(fā)板文件系統(tǒng)里的/usr/bin目錄下
執(zhí)行g(shù)dbserver --version看看成功沒(méi)有
4、將自己的工程編譯的時(shí)候加上-g,這樣生成的程序才能進(jìn)行調(diào)試
5、gdbserver 192.168.1.12:2001 comprot 在開(kāi)發(fā)板啟動(dòng)gdb調(diào)試,地址用自己linux虛擬機(jī)的地址,comprot是我自己的工程程序
這里的端口隨便填,當(dāng)然不能和已經(jīng)被使用的沖突,只要?jiǎng)e用常用的那幾個(gè)就OK
6、虛擬機(jī)里啟動(dòng)gdb
/work/tools/gdb/bin/arm-linux-gdb /mnt/hgfs/program/\!ocpp板程序/AAOCPP_MQTT2/Protocol-ocpp_wf3_0/bin/comprot
我用的是絕對(duì)路徑,后面要帶上本地編譯的可執(zhí)行文件
7、在虛擬機(jī)啟動(dòng)的gdb命令框里執(zhí)行target remote 192.168.1.136:2001
此處的地址是開(kāi)發(fā)板的地址,端口是上面自己設(shè)置的端口,要一致
8、如此就啟動(dòng)完成了,執(zhí)行b main,可以直接在主函數(shù)入口打斷點(diǎn),并且命令行會(huì)輸出打在哪個(gè)文件哪一行,自己看看對(duì)不對(duì)的上
下面附帶一些常用的調(diào)試指令
GDB調(diào)試命令大全
打斷點(diǎn):
b [源代碼行號(hào)][源代碼函數(shù)名][內(nèi)存地址] 任一參數(shù)b main 在主函數(shù)入口打斷點(diǎn)b /mnt/hgfs/program/!ocpp板程序/AAOCPP_MQTT2/Protocol-ocpp_wf3_0/main.c:900 在某文件的某行打斷點(diǎn)/條件。例如在循環(huán)體中可以設(shè)置break ... if i = 100 來(lái)設(shè)置循環(huán)次數(shù)
info b 查看打的斷電
clear刪除一個(gè)斷點(diǎn),這個(gè)命令需要制定代碼行或者函數(shù)名作為參數(shù)
disable禁止斷點(diǎn)功能,這個(gè)命令需要禁止的斷點(diǎn)在斷點(diǎn)列表索引值作為參數(shù) 可以通過(guò)info b 看到索引值
Ctrl-C在當(dāng)前位置停止執(zhí)行正在執(zhí)行的程序,斷點(diǎn)在當(dāng)前行
display在斷點(diǎn)的停止的地方,顯示指定的表達(dá)式的值。(顯示變量)
list顯示10行代碼。如果沒(méi)有提供參數(shù)給這個(gè)命令,則從當(dāng)前行開(kāi)始顯示10行代碼。如果提供了函數(shù)名作為參數(shù),則從函數(shù)開(kāi)頭顯示。如果提供代碼行的編號(hào)作為參數(shù),這一行作為開(kāi)頭顯示。
list顯示10行代碼。如果沒(méi)有提供參數(shù)給這個(gè)命令,則從當(dāng)前行開(kāi)始顯示10行代碼。如果提供了函數(shù)名作為參數(shù),則從函數(shù)開(kāi)頭顯示。如果提供代碼行的編號(hào)作為參數(shù),這一行作為開(kāi)頭顯示。
load動(dòng)態(tài)載入一個(gè)可執(zhí)行文件到調(diào)試器。
next執(zhí)行下一行的源代碼的所有指令。如果是函數(shù)調(diào)用,則也當(dāng)作一行源代碼,執(zhí)行到此函數(shù)返回
nexti執(zhí)行下一行的源代碼中的一條匯編指令
Print顯示變量的值
ptype顯示變量的類型
return強(qiáng)制從當(dāng)前函數(shù)返回
run從程序開(kāi)始的地方執(zhí)行
設(shè)置觀察點(diǎn):
a、watch + [變量][表達(dá)式] 當(dāng)變量或表達(dá)式值改變時(shí)即停住程序。
b、rwatch + [變量][表達(dá)式] 當(dāng)變量或表達(dá)式被讀時(shí),停住程序。
c、awatch + [變量][表達(dá)式] 當(dāng)變量或表達(dá)式被讀或被寫時(shí),停住程序。
|
評(píng)分
-
查看全部評(píng)分
|