交叉編譯gdb和gdbserverlinux
一、下載gdb:
下載地址爲:
http://ftp.gnu.org/gnu/gdb/
按照通常的想法,最新版本越好,所以下載7.2這個版本。固然,凡事無絕對。
咱們以gdb-7.2.tar.bz2 這個文件爲例。
二、解壓縮:windows
$ tar jxvf gdb-7.2.tar.bz2
注:小技巧:Linux下通常壓縮文件後綴爲.tar.bz2和.tar.gz,它們解壓命令有兩三個選項是一致的:網絡
xf(v),前者再加上j選項,後者再加上z選項。app
三、進入該目錄ide
$ cd gdb-7.2/
四、配置工具
$./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是指生成的可執行文件安裝在哪一個目錄,這個目錄須要根據實際狀況做選擇。若是該目錄不存在,會自動建立,固然,權限足夠的話。post
五、編譯、安裝this
$ makespa
$ make installdebug
幸運的話,會在--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的東東。這個東東是怎麼來的呢?
一、在剛纔那個gdb解壓後的目錄:gdb-7.2,進入./gdb/gdbserver子目錄
gdbserver一、cd gdb/gdbserver/二、配置: ./configure --target=arm-hismall-linux --host=arm-hismall-linux --prefix=/mnt/hgfs/vmshare/gdbserver7.41/(一樣,target 和 host 爲你的交叉編譯器, prefix爲安裝的目錄)三、編譯: 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系統下則恢復正常。