建立環境
cd ~/arm-linux
mkdir -p gdb/src
mkdir -p gdb/build
export SRCDIR=~/arm-linux/gdb/src
export BUILDDIR=~/arm-linux/gdb/build
export TARGET=arm-linux-gnueabi
export PREFIX=/usr/local/arm/4.8.2
export TARGET_PREFIX=$PREFIX/$TARGET
export PATH=$PATH:$PREFIX/bin
下載下傳gdb源碼
cd $SRCDIR
下載下傳版本:7.6.1
wget -c http://ftp.gnu.org/gnu/gdb/gdb-7.6.1.tar.bz2
解壓:
tar -jxvf gdb-7.6.1.tar.bz2
編譯 gdb
cd $BUILDDIR
$SRCDIR/gdb-7.6.1/configure --prefix=$PREFIX --target=$TARGET
make
常見錯誤:
...
/bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I../../../src/gdb-7.6.1/bfd -I. -I../../../src/gdb-7.6.1/bfd -I../../../src/gdb-7.6.1/bfd/../include -DHAVE_bfd_elf32_littlearm_vec -DHAVE_bfd_elf32_bigarm_vec -DHAVE_bfd_elf32_little_generic_vec -DHAVE_bfd_elf32_big_generic_vec -DBINDIR='"/usr/local/arm/4.8.2/bin"' -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Werror -g -O2 -MT opncls.lo -MD -MP -MF .deps/opncls.Tpo -c -o opncls.lo ../../../src/gdb-7.6.1/bfd/opncls.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I../../../src/gdb-7.6.1/bfd -I. -I../../../src/gdb-7.6.1/bfd -I../../../src/gdb-7.6.1/bfd/../include -DHAVE_bfd_elf32_littlearm_vec -DHAVE_bfd_elf32_bigarm_vec -DHAVE_bfd_elf32_little_generic_vec -DHAVE_bfd_elf32_big_generic_vec -DBINDIR=\"/usr/local/arm/4.8.2/bin\" -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Werror -g -O2 -MT opncls.lo -MD -MP -MF .deps/opncls.Tpo -c ../../../src/gdb-7.6.1/bfd/opncls.c -o opncls.o
In file included from ../../../src/gdb-7.6.1/bfd/opncls.c:26:0:
../../../src/gdb-7.6.1/bfd/opncls.c: In function ‘bfd_fopen’:
./bfd.h:529:65: error: right-hand operand of comma expression has no effect [-Werror=unused-value]
#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
^
../../../src/gdb-7.6.1/bfd/opncls.c:263:5: note: in expansion of macro ‘bfd_set_cacheable’
bfd_set_cacheable (nbfd, TRUE);
^
cc1: all warnings being treated as errors
Makefile:1607: recipe for target 'opncls.lo' failed
make[4]: *** [opncls.lo] Error 1
make[4]: Leaving directory '/home/weisf/arm-linux/build/gdb/bfd'
Makefile:1649: recipe for target 'all-recursive' failed
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory '/home/weisf/arm-linux/build/gdb/bfd'
Makefile:1135: recipe for target 'all' failed
make[2]: *** [all] Error 2
make[2]: Leaving directory '/home/weisf/arm-linux/build/gdb/bfd'
Makefile:2579: recipe for target 'all-bfd' failed
make[1]: *** [all-bfd] Error 2
make[1]: Leaving directory '/home/weisf/arm-linux/build/gdb'
Makefile:828: recipe for target 'all' failed
make: *** [all] Error 2
原因是比較新的編譯器如gcc4.5 以上的編譯器,對 #define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) 這樣的文法不支援,解決方法是加上忽略告警的選項 --disable-werror:
make clean
$SRCDIR/gdb-7.6.1/configure --prefix=$PREFIX --target=$TARGET --disable-werror
make
編譯完成後,安裝:
有錯誤提示:Makefile:370: recipe for target ‘gdb.info’ failed
但是已經安裝成功了。在/usr/local/arm/4.8.2/bin 下面能夠看到 arm-linux-gnueabi-gdb 這個檔案
$ ls /usr/local/arm/4.8.2/bin/
arm-linux-addr2line arm-linux-gdb arm-linux-gnueabi-gcc-4.8.2 arm-linux-gnueabi-objdump arm-linux-objcopy
arm-linux-ar arm-linux-gdbtui arm-linux-gnueabi-gcc-ar arm-linux-gnueabi-ranlib arm-linux-objdump
arm-linux-as arm-linux-gnueabi-addr2line arm-linux-gnueabi-gcc-nm arm-linux-gnueabi-readelf arm-linux-ranlib
arm-linux-c++ arm-linux-gnueabi-ar arm-linux-gnueabi-gcc-ranlib arm-linux-gnueabi-run arm-linux-readelf
arm-linux-c++filt arm-linux-gnueabi-as arm-linux-gnueabi-gcov arm-linux-gnueabi-size arm-linux-run
arm-linux-cpp arm-linux-gnueabi-c++ arm-linux-gnueabi-gdb arm-linux-gnueabi-strings arm-linux-size
arm-linux-elfedit arm-linux-gnueabi-c++filt arm-linux-gnueabi-gprof arm-linux-gnueabi-strip arm-linux-strings
arm-linux-g++ arm-linux-gnueabi-cpp arm-linux-gnueabi-ld arm-linux-gprof arm-linux-strip
arm-linux-gcc arm-linux-gnueabi-elfedit arm-linux-gnueabi-ld.bfd arm-linux-ld rename.sh
arm-linux-gcc-4.6.3 arm-linux-gnueabi-g++ arm-linux-gnueabi-nm arm-linux-ld.bfd
arm-linux-gcov arm-linux-gnueabi-gcc arm-linux-gnueabi-objcopy arm-linux-nm
編譯gdbserver
cd $BUILDDIR
mkdir gdbserver
cd gdbserver
$SRCDIR/gdb/gdbserver/configure --host=arm-linux-gnueabi --target=arm-linux-gnueabi --prefix=/usr/local/arm/4.8.2 --disable-werror
如果不加 --disable-werror,會報出一個錯誤:
In file included from /usr/local/arm/4.8.2/arm-linux-gnueabi/include/sys/sysinfo.h:24:0,
from ../../src/gdb-7.6.1/gdb/gdbserver/../common/linux-osdata.c:29:
/usr/local/arm/4.8.2/arm-linux-gnueabi/include/linux/kernel.h:720:2: error: #warning Attempt to use kernel headers from user space, see http: [-Werror=cpp]
#warning Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders
^
cc1: all warnings being treated as errors
Makefile:534: recipe for target 'linux-osdata.o' failed
make: *** [linux-osdata.o] Error 1
用 --disable-werror 忽略這個錯誤
另外,還會報如下的錯誤:
arm-linux-gnueabi-gcc -g -O2 -I. -I../../src/gdb-7.6.1/gdb/gdbserver -I../../src/gdb-7.6.1/gdb/gdbserver/../common -I../../src/gdb-7.6.1/gdb/gdbserver/../regformats -I../../src/gdb-7.6.1/gdb/gdbserver/../../include -I../../src/gdb-7.6.1/gdb/gdbserver/../gnulib/import -Ibuild-gnulib-gdbserver/import -Wall -Wdeclaration-after-statement -Wpointer-arith -Wformat-nonliteral -Wno-char-subscripts -Wempty-body -Werror -DGDBSERVER -c -o hostio.o -MT hostio.o -MMD -MP -MF .deps/hostio.Tpo ../../src/gdb-7.6.1/gdb/gdbserver/hostio.c
../../src/gdb-7.6.1/gdb/gdbserver/hostio.c: In function ‘require_filename’:
../../src/gdb-7.6.1/gdb/gdbserver/hostio.c:67:20: error: ‘PATH_MAX’ undeclared (first use in this function)
if (count >= PATH_MAX - 1)
^
這是因為交叉編譯器的頭檔案中,PATH_MAX 是在 linux/limits.h 中定義的而不是 limits.h,是以,打開報錯的檔案,在 #include <limits.h> 這樣後面,新加一行 #include <linux/limits.h>
vim …/…/src/gdb-7.6.1/gdb/gdbserver/hostio.c
21 #include "server.h"
22 #include "gdb/fileio.h"
23
24 #include <fcntl.h>
25 #include <limits.h>
26
27 #include <unistd.h>
28 /* HAOJC ADD */
29 #include <linux/limits.h>
30
31 extern int remote_debug;
32
這個同樣的錯誤,還會出現在另外一個檔案 …/…/src/gdb-7.6.1/gdb/gdbserver/thread-db.c,用同樣的方法處理它。
然後,編譯就通過了。
然後,可以安裝一下:
sudo make install
這會生成 /usr/local/arm/4.8.2/bin/arm-linux-gnueabi-gdbserver
部署到 arm linux
在主機上安裝 nfs server
sudo apt install nfs-kernel-server
設定服務通路配置:
sudo vim /etc/exports
添加一行:
/home/weisf/nfs *(rw,sync,no_root_squash,no_subtree_check)
/home/weisf/nfs 是用于共享檔案的目錄,
“*” 表示所有主機可以通路
rw - 表示可以讀和寫;
no_root_squash - 不降低root使用者的權限(不會将root使用者及所屬組都映射為匿名使用者或使用者組)
no_subtree_check - 即使輸出目錄是一個子目錄,nfs伺服器也不檢查其父目錄的權限,這樣可以提高效率。
啟動 nfs 服務:
sudo service nfs-kernel-server start
然後,就可以從 arm 闆上加載 nfs 實作共享了。
在arm linux 上加載 nfs 目錄
192.168.1.20 是主機IP位址
mkdir /mnt/nfs
mount -t nfs -o nolock 192.168.1.20:/home/weisf/nfs /mnt/nfs
如果想開機就加載,則建立初始化檔案 rc.local
vi /etc/rc.local
輸入:
mount -t nfs -o nolock 192.168.1.20:/home/weisf/nfs /mnt/nfs
儲存
chmod a+x /etc/rc.local
然後在 /etc/init.d/rc 腳本裡面調用它,在文檔的最後,加上:
#Uncomment to cause psplash to exit manually, otherwise it exits when it sees a
#if [ "x$runlevel" != "xS" ] && [ ! -x /etc/init.d/xserver-nodm ]; then
# if type psplash-write >/dev/null 2>&1; then
# TMPDIR=/mnt/.psplash psplash-write "QUIT" || true
# umount /mnt/.psplash
# fi
#fi
/etc/rc.local
将 gdbserver 通過 nfs 發送給arm闆
加載nfs目錄後,從主機上将gdbserver程式複制到 nfs目錄:
cp /usr/local/arm/4.8.2/bin/arm-linux-gnueabi-gdbserver /home/weisf/nfs/
從arm闆上,就可以看到:
/mnt/nfs/arm-linux-gnueabi-gdbserver
arm linux 目标闆遠端調試
主機:192.168.1.20
目标機:192.168.1.232
在主機上,編寫程式:
vim test.c
#include <stdio.h>
int func(int n)
{
int sum=0, i;
for (i=0; i<n; i++)
{
sum += i;
}
return sum;
}
int main(int argc, char* argv[])
{
int i;
long result = 0;
for (i=0; i<=100; i++)
{
result += i;
}
printf("result[1-100] = %d \n",result);
printf("resutl[1-225] = %d \n",func(255));
return 0;
}
在主機上編譯:
arm-linux-gcc -g test.c -o test
一定要用 -g,才可以在目标檔案中帶上調試資訊,否則不可調試。
然後,将 test 複制到 nfs:
cp test /home/weisf/nfs/
在arm闆上:
ls /mnt/nfs
可以看到 test。
執行:
[email protected]:/mnt/nfs# ./arm-linux-gnueabi-gdbserver 192.168.1.20:1234 test
Process test created; pid = 1107
Listening on port 1234
向 192.168.1.20 打開監聽端口 1234 來調試 test 程式。
在主機上進行調試:
[email protected]:~/work/test$ arm-linux-gnueabi-gdb test
Python Exception <type 'exceptions.ImportError'> No module named gdb:
warning:
Could not load the Python gdb module from `/usr/local/arm/4.8.2/share/gdb/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/weisf/work/test/test...done.
(gdb) l
Cannot access memory at address 0x0
6 {
7 sum += i;
8 }
9 return sum;
10 }
11
12 int main(int argc, char* argv[])
13 {
14 int i;
15 long result = 0;
(gdb) b 15
Breakpoint 1 at 0x8478: file test.c, line 15.
(gdb) b func
Breakpoint 2 at 0x8410: file test.c, line 4.
(gdb) c
Continuing.
warning: Could not load shared library symbols for 2 libraries, e.g. /lib/libc.so.6.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Breakpoint 1, main (argc=1, argv=0xbefffbc4) at test.c:15
15 long result = 0;
(gdb) n
16 for (i=0; i<=100; i++)
(gdb) n
18 result += i;
(gdb) n
16 for (i=0; i<=100; i++)
(gdb) p result
$1 = 0
(gdb) n
18 result += i;
(gdb) n
16 for (i=0; i<=100; i++)
(gdb) p result
$2 = 1
(gdb)
注意到有個警告:
Could not load the Python gdb module from `/usr/local/arm/4.8.2/share/gdb/python’.
Limited Python support is available from the _gdb module.
這是缺少 python 子產品,将源碼中的python 庫檔案複制過來:
cd /usr/local/arm/4.8.2/share/gdb/python/gdb
sudo cp -R ~/arm-linux/gdb/src/gdb-7.6.1/gdb/python/lib/gdb/* ./
QT遠端調試
在主機上,設定QT的生成檔案目錄到 nfs 目錄下,這樣可以即時與目标闆共享編譯生成的目标程式。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9EUT3FkaNtmSzI2MONDW65kMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1gjNwUDMzgTMzEDOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
然後,執行編譯,會在 /home/weisf/nfs 目錄下生成目标程式。
在目标闆上,執行:
cd /mnt/nfs/dae/debug
/mnt/nfs/arm-linux-gnueabi-gdbserver 192.168.1.20:1234 ./DAE-gui -qws
然後,在主機上qtcreator界面中,選擇 Debug -> Start Debugging -> Attach to Running Debug Server…
設定遠端arm闆上的位址和端口,點選OK。可以選擇 break at “main”,這樣可以執行的時候,在main入口處設定斷點暫停。
然後,就可以随意在主機上,執行各種調試操作了,設定斷點、監視變量、調用堆棧等。