Linux應(yīng)用調(diào)試使用gdb和gdbserver命令詳解
1.gdb和gdbserver調(diào)試原理
通過linux虛擬機(jī)里的gdb,來向開發(fā)板里的gdbserver發(fā)送命令,比如設(shè)置斷點(diǎn),運(yùn)行setp等,然后開發(fā)板上的gdbserver收到命令后,便會(huì)執(zhí)行應(yīng)用程序做相應(yīng)的動(dòng)作,來實(shí)現(xiàn)調(diào)試的功能
和之前學(xué)的裸板GDB調(diào)試 一樣,只不過之前學(xué)的是在win下的,本次是在linux里的gdb
1.1同樣,它們都會(huì)需要一個(gè)帶調(diào)試信息的編譯文件.
通過Makefile里的arm-linux-gcc -g 來的, -g:表示編譯文件里包含gdb調(diào)試信息
1.2為什么需要調(diào)試信息的編譯文件?
比如讀開發(fā)板的應(yīng)用程序里的變量a:
首先gdb通過應(yīng)用程序的帶調(diào)試信息的編譯文件,來找出變量a存的地址位置
然后將地址發(fā)送給開發(fā)板里的gdbserver,來讀出a地址的值
2.安裝gdb和gdbserver
首先進(jìn)入官網(wǎng)下載gdb-7.4: http://ftp.gnu.org/gnu/gdb/
2.1在虛擬機(jī)上安裝GDB:
# tar xjf gdb-7.4.tar.bz2 //解壓 # cd gdb-7.4/ //進(jìn)入gdb-7.4目錄 #./configure --target=arm-linux //GDB需要在pc本機(jī)里運(yùn)行,并調(diào)試開發(fā)板里的應(yīng)用程序,所以--target設(shè)為arm-linux #make //編譯 #mkdir tmp #make install prefix=$PWD/tmp //安裝到./tmp目錄下 sudo cp tmp/bin/arm-linux-gdb /bin/ //復(fù)制到/bin目錄下 /bin/arm-linux-gdb -v //-v: 確定一下gdb的版本VID,是否是7.4
2.2 在開發(fā)板上安裝GDBServer:
cd gdb/gdbserver/ //在gdb-7.4目錄下輸入 ./configure --target=arm-linux --host=arm-linux //設(shè)GDBServer的工作環(huán)境 make //編譯
出現(xiàn)以下錯(cuò)誤:
指在linux-arm-low.c里,沒有找到PTRACE_GETSIGINFO 定義
2.3 解決:
1)
#echo $PATH //來查看PATH環(huán)境變量
找到編譯器gcc位于/work/tools/gcc-3.4.5-glibc-2.3.6/bin
2)
#cd /work/tools/gcc-3.4.5-glibc-2.3.6/ # grep "PTRACE_GETSIGINFO" * -nR
在gcc根目錄下,搜索到在linux/ptrace.h中定義:
3)
#vi linux-arm-low.c
添加: #define PTRACE_GETSIGINFO 0x4202
4)最后重新make,生成gdbserver命令文件
然后將gdbserver命令文件,放入我們開發(fā)板的根目錄/bin中,便能使用了
cp gdbserver /nfs_root/bin/ //nfs_root:開發(fā)板的nfs系統(tǒng)根目錄
3.測試程序如下(test_debug.c)
#include <stdio.h> void C(int *p) { *p = 0x12; } void B(int *p) { C(p); } void A(int *p) { B(p); } void A2(int *p) { C(p); } int main(int argc, char **argv) { int a; int *p = NULL; A2(&a); // A2 > C printf("a = 0x%x\n", a); A(p); // A > B > C return 0; }
其中A2(&a)會(huì)調(diào)用A2()->C(),然后將a賦值為0x12.
A(p)會(huì)調(diào)用A()->B()->C(),由于p是個(gè)空指針,這里將會(huì)出錯(cuò).
接下來,我們便以這個(gè)應(yīng)用程序?yàn)槔?
4.編譯
#arm-linux-gcc -g -o test_debug test_debug.c //-g:附帶調(diào)試信息
5.調(diào)試test_debug.c
在開發(fā)板上:
首先,需要讓gdbserver建立本地服務(wù)器,以及要測試的哪個(gè)文件:
#gdbserver 192.168.2.107:2345 ./test_debug //192.168.2.107:本地IP地址 //2345:端口號,用來讓gdb來連接用的 //./test_debug:要測試的哪個(gè)文件
在虛擬機(jī)上:
#/bin/arm-linux-gdb ./test_debug // 啟動(dòng)gdb,指定調(diào)試文件為test_debug #target remote 192.168.2.107:2345 //與gdbserver建立連接
5.1連接成功,便使用gdb命令來調(diào)試
常用命令如下所示(參考http://blog.sciencenet.cn/blog-619295-813770.html):
列出所有源代碼
break [file]:[row]
打斷點(diǎn),比如:
break test_debug.c:21 //在test_debug.c文件的第21行處打斷點(diǎn)
info br
查看斷點(diǎn)
info file
列出當(dāng)前的文件,共享庫。
delete <num>
刪除第幾個(gè)斷點(diǎn),如下圖所示:
c
啟動(dòng)程序運(yùn)行
step
單步執(zhí)行
next
單步執(zhí)行,和step不同的是,比如:當(dāng)前行里有函數(shù)調(diào)用時(shí),next直接執(zhí)行下一句,step會(huì)進(jìn)入函數(shù)
print a
打印a變量的值
quit
退出gdb
6.也可以通過gdb+coredump來調(diào)試test_debug.c
當(dāng)程序運(yùn)行出錯(cuò)時(shí),便會(huì)生成core文件,并將程序里的運(yùn)行狀況存到core中,也就是coredump,供給gdb來調(diào)試
6.1首先,通過ulimit來查看coredump的資源大小
ulimit命令(user limit),主要用來限制用戶的各個(gè)進(jìn)程資源.
在開發(fā)板里,輸入
如上圖所示,可以看到coredump的資源大小為0,也就是說,當(dāng)程序運(yùn)行出錯(cuò)時(shí),不會(huì)生成core文件
6.2設(shè)置core文件
設(shè)置core文件的資源大小為無限制,輸入:
ulimit -c unlimited //-c:對應(yīng)coredump
6.3生成core文件
執(zhí)行:
#./test_debug
出現(xiàn)段錯(cuò)誤,并生成core文件,如下圖所示:
6.4 進(jìn)入虛擬機(jī)
將core拷貝過來,然后執(zhí)行:
#/bin/arm-linux-gdb ./test_debug ./core
然后輸入bt,便可查看調(diào)用關(guān)系:
總結(jié)
以上所述是小編給大家介紹的Linux應(yīng)用調(diào)試使用gdb和gdbserver命令詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
國產(chǎn)中文操作系統(tǒng)OpenDesktop
國產(chǎn)中文操作系統(tǒng)OpenDesktop...2006-10-10Linux下搭建Spark 的 Python 編程環(huán)境的方法
這篇文章主要介紹了Linux下搭建Spark 的 Python 編程環(huán)境的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06詳解shell中source、sh、bash、./執(zhí)行腳本的區(qū)別
這篇文章主要介紹了shell中source、sh、bash、./執(zhí)行腳本的區(qū)別,需要的朋友可以參考下2017-11-11Linux操作系統(tǒng)12則經(jīng)典應(yīng)用技巧
Linux操作系統(tǒng)12則經(jīng)典應(yīng)用技巧...2006-10-10設(shè)置一個(gè)高容量的Linux POP3服務(wù)器
設(shè)置一個(gè)高容量的Linux POP3服務(wù)器...2006-10-10