Linux下交叉編譯gdb,gdbserver+gdb的使用以及通過gdb調試core文件
交叉編譯gdb和gdbserver
1、下載gdb:
下載地址為:
http://ftp.gnu.org/gnu/gdb/
按照一般的想法,最新版本越好,因此下載7.2這個版本。當然,凡事無絕對。
我們以gdb-7.2.tar.bz2 這個文件為例。
2、解壓縮:
$ tar jxvf gdb-7.2.tar.bz2
注:小技巧:Linux下一般壓縮文件后綴為.tar.bz2和.tar.gz,它們解壓命令有兩三個選項是一致的:
xf(v),前者再加上j選項,后者再加上z選項。
3、進入該目錄
$ cd gdb-7.2/
4、配置
$./configure --target=arm-linux --program-prefix=arm-linux- --prefix=/usr/local/arm-gdb
注:--target=arm-linux意思是說目標平臺是運行于ARM體系結構的linux內核;--program-prefix=arm-linux-是指生成的可執行文件的前綴,比如arm-linux-gdb,--prefix是指生成的可執行文件安裝在哪個目錄,這個目錄需要根據實際情況作選擇。如果該目錄不存在,會自動創建,當然,權限足夠的話。
5、編譯、安裝
$ make
$ make install
幸運的話,會在--prefix指定的目錄下生成三個子目錄:bin、lib、share,我們需要的arm-linux-gdb就在其中的bin目錄下。
如果你不小心查看它的大小的話,會發覺它有14MB那么大!天吶!怎么會占這么多空間?沒關系,我們可以為它瘦身。沒錯!就是使用strip命令!
$ strip arm-linux-gdb -o arm-linux-gdb-stripped
$ ls -lh
總計 33M
-rwxr-xr-x 1 latelee root 14M 12-14 16:16 arm-linux-gdb
-rwxr-xr-x 1 latelee root 3.1M 12-14 16:25 arm-linux-gdb-stripped
可以看到,strip后的文件大小只有3.1MB,瘦身效果明顯!如果做廣告的話,絕對有說服力。
這個文件就是我們以后遠程調試時在主機上運行的交叉調試器了:在主機上執行,調試的卻是另一種體系結構的代碼。但是,光有主機的調試器還不夠。還需要在目標板上運行一個叫gdbserver的東東。這個東東是怎么來的呢?
1、在剛才那個gdb解壓后的目錄:gdb-7.2,進入./gdb/gdbserver子目錄
gdbserver1、cd gdb/gdbserver/2、配置: ./configure --target=arm-hismall-linux --host=arm-hismall-linux --prefix=/mnt/hgfs/vmshare/gdbserver7.41/(同樣,target 和 host 為你的交叉編譯器, prefix為安裝的目錄)3、編譯: make CC=make CC=arm-hismall-linux-gcc出現錯誤:linux-arm-low.c: In function `arm_stopped_by_watchpoint':linux-arm-low.c:642: error: `PTRACE_GETSIGINFO' undeclared (first use in this function)linux-arm-low.c:642: error: (Each undeclared identifier is reported only oncelinux-arm-low.c:642: error: for each function it appears in.)解決方法:這里提示沒有PTRACE_GETSIGINFO這個東西,這里搜索PTRACE_GETSIGINFO的路徑為-I指定的頭文件以及交叉 編譯工具鏈,我們不妨到交叉編譯工具鏈里面去查找一下:cd /usr/local/arm/3.4.5/grep "PTRACE_GETSIGINFO" * -nR找到如下信息:arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202arm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202distributed/arm-linux/sys-include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202distributed/arm-linux/include/linux/ptrace.h:27:#define PTRACE_GETSIGINFO 0x4202說明PTRACE_GETSIGINFO是在交叉編譯工具鏈:linux/ptrace.h文件里定義的,那么可能是頭文件沒有包含好吧!我們到gdbserver下的linux-arm-low.c里面一看,可不是嘛,只有:#include <sys/ptrace.h>而沒有:#include<linux/ptrace.h>,于是在linux-arm-low.c文件中加上:#include <linux/ptrace.h>,再次編譯:make CC=/usr/local/arm/3.4.5/bin/arm-linux-gcc成功!
32位,ARM平臺,動態鏈接,未strip。
同樣,我們也減小它的體積:
# arm-hismall-linux-strip gdbserver
[root@localhost gdbserver]# ls gdbserver -l
-rwxrwxrwx 1 root root 498279 2012-12-30 06:21 gdbserver
[root@localhost gdbserver]# ls gdbserver -l
-rwxrwxrwx 1 root root 209048 2012-12-30 06:53 gdbserver
瘦身效果同樣那么明顯!
注意,這里必須使用strip的交叉版本,也就是你交叉編譯器帶的strip工具,我的是arm-hismall-linux-strip。
[root@localhost gdbserver]# file gdbserver
gdbserver: ELF 32-bit LSB executable, ARM, version 1, dynamically linked (uses shared libs), stripped
到此,我們生成了兩個重量級別的文件:arm-linux-gdb和gdbserver。它們的版本是一致的,這一點非常重要。我們需要將gdbserver下載到開發板中,——可以通過各種各樣的手段,包括但不限于NFS。調試時需要在開發板中運行這個程序。同時在主機中執行arm-linux-gdb調試器。
GDB+GDBServer的使用
在目標系統上啟動gdbserver,其實就是在超級終端下或者minicom下啟動gdbserver。這里將gdbserver放在宿主機的NFS設置的共享目錄下/home/zzl,該目錄掛載在目標板/work下。宿主機的ip為192.168.1.1,目標板的ip為192.168.1.33
超級終端或者minicom下
[root@localhost]cd /work
[root@localhost]./gdbserver 192.168.1.1:1234 hello
出現提示:
Process /work/hello created: pid=69
Listening on port 1234
這時切換到宿主機的控制臺,運行
[root@localhost] arm-softfloat-linux-gnu-gdb hello
(gdb) target remote 192.168.2.33:1234
出現提示:
Remote debugging using 192.168.1.33:1234
[New thread 80]
[Switching to thread 80]
0x40002a90 in ??()
同時在minicom下提示:
Remote debugging from host 192.168.2.100
(gdb)
連接成功,這時候就可以輸入各種gdb命令如list、continue、next、step、break等進行程序調試了。
使用GDB調試core文件
$ gdb --core=core.9128
GNU gdb Asianux (6.0post-0.20040223.17.1AX)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-asianux-linux-gnu".
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x08048373 in ?? ()
(gdb) bt
#0 0x08048373 in ?? ()
#1 0xbfffd8f8 in ?? ()
#2 0x0804839e in ?? ()
#3 0xb74cc6b3 in ?? ()
#4 0x00000000 in ?? ()
此時用bt看不到backtrace,也就是調用堆棧,原來GDB還不知道符號信息在哪里。我們告訴它一下:
(gdb) file ./a.out
Reading symbols from ./a.out...done.
Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) bt
#0 0x08048373 in sub () at foo.c:17
#1 0x08048359 in main () at foo.c:8
此時backtrace出來了。
(gdb) l
8 sub();
9 return 0;
10 }
11
12 static void sub(void)
13 {
14 int *p = NULL;
15
16
17 printf("%d", *p);
(gdb)
對于GDBServer出現的問題
1. GDBServer調試時出現packet error 問題。
主要是虛擬機與目標機的網絡連接要經過windows,數據包容易丟失。換到Linux系統下則恢復正常。
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成