gdbserver工具
先确定默认crosstool交叉编译器是否有自带gdbserver,如果有就不需要自行编译。一般都会带有对应的gdbserver工具,可以通过find命令查找确定:
hong@ubuntu:~/work/system$ which arm-none-linux-gnueabi-gcc
/opt/arm-2009q3/bin/arm-none-linux-gnueabi-gcc
hong@ubuntu:~/work/emrock/emrock/system$ find /opt/arm-2009q3 -name gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/thumb2/usr/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/thumb2/usr/lib/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/armv4t/usr/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/armv4t/usr/lib/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/usr/bin/gdbserver
/opt/arm-2009q3/arm-none-linux-gnueabi/libc/usr/lib/bin/gdbserver
hong@ubuntu:~/work/system$
如果找到了就直接跳到步骤4,没有的话就需要自行编译了。
编译gdbserver
到GNU官方FTP下载, 下载地址:
http://ftp.gnu.org/gnu/gdb/
1
2
3
4
|
# cd gdb-6.7.1/gdb/gdbserver/
#./configure --host=arm-none-linux-gnueabi --prefix=/work/install/gdbserver
#make
#make install
|
1
2
|
#cd /work/install/gdbserver
#cp bin/gdbserver /work/nfs/rootfs/bin
|
这里需要特别注意的是交叉编译的gdbserver和host调试用的gdb版本必须保证版本一致,否则会出现如下的问题:
1
2
3
4
5
|
hong@ubuntu:~
/work/
$ arm-none-linux-gnueabi-
gdb
.
/ipcr002_debug
(
gdb
) target remote 192.168.0.178:1234
Remote debugging using 192.168.0.178:1234
Malformed packet(b) (missing colon): ore:0;
Packet:
'T050b:00000000;0d:80bdc3be;0f:b0070040;thread:5c21;core:0;'
|
1
2
|
hong@ubuntu:~
/work/system
$ arm-none-linux-gnueabi-
gdb
--version
GNU
gdb
(Sourcery G++ Lite 2009q3-67) 6.8.50.20090630-cvs
|
而我使用交叉编译工具链自带的gdbserver就不会有这个问题。除了使用自带的gdbserver外,另一种解决办法就是重新从gdb源码编译arm-none-linux-gnueabi-gdb,这样也可以保证两者的版本一致。
库问题
这里需要注意的是运行gdbserver还需要libthread_db库,若你自己做的文件系统内没有这个库的话需要从交叉编译器内拷一个过去。
1
2
3
4
5
|
# gdbserver -h (target)
gdbserver: error
while
loading shared libraries: libthread_db.so.1: cannot
open
shared object
file
: No such
file
or directory
# cp -avf lib/libthread_db* /work/nfs/rootfs_bluetooth_omap/lib/
`
/lib/libthread_db-1
.0.so
' -> `/work/nfs/rootfs/lib/libthread_db-1.0.so'
`
/lib/libthread_db
.so.1
' -> `/work/nfs/rootfs/lib/libthread_db.so.1'
|
#strace -f -F -o strace.log gdbserver -h
#vi strace.log
发现如下字段:
872 writev(2, [{"gdbserver", 9}, {": ", 2}, {"error while loading shared libra"..., 36}, {": ", 2}, {"libthread_db.so.1", 17}, {": ", 2}, {"cannot open shared object file", 30}, {": ", 2}, {"No such file or directory", 25}, {"\n", 1}], 10) = 126
872 exit_group(127) = ?
得知缺少libthread_db.so.1库(红色部分标出)。
调试过程
1)Target端建立远程调试服务# gdbserver 192.168.0.29:1234 obexftp (target)
Process obexftp created; pid = 858
Listening on port 1234
其中IP地址为用来远程调试的上位机地址(现在直接被gdbserver忽略掉,所以可以不写),端口为target TCP 监听端口。目标程序不需要符号表,即可以是strip后的,这样可以节省存储空间,所有的符号信息处理都是在Host端的gdb处完成的。
2)Host端GDB加载要调试的程序这里要调试的程序得是交叉编译过的,并且加了-g参数。不过大部分编译程序默认就是加了-g参数的,这点可以从编译时的log看出。
1
2
3
4
5
6
7
8
|
# arm-linux-gdb obexftp
GNU
gdb
6.6.50.20070301 (MontaVista 6.6.50-2.0.1.0702865 2007-03-26)
Copyright (C) 2007 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
"--host=i686-pc-linux-gnu --target=armv5tl-montavista-linux-gnueabi"
...
|
1
2
3
4
5
|
(
gdb
) target remote 192.168.0.178:1234
Remote debugging using 192.168.0.178:1234
Error
while
reading shared library symbols:
Dwarf Error: Can
't read DWARF data from '
/opt/montavista/pro/devkit/arm/v5t_le/target/usr/lib/debug/lib/ld-2
.5.90.so.debug'
0x400007a0
in
_start () from
/opt/montavista/pro/devkit/arm/v5t_le/target/lib/ld-linux
.so.3
|
连接成功后ARM板上的信息应该是这样的:
1
2
3
|
# ./gdbserver 192.168.0.29:1234 obexftp
Process obexftp created; pid = 858
Remote debugging from host 192.168.0.29
# 这个ip地址是上位机的IP地址
|
调试过程如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
(
gdb
) b main
Breakpoint 1 at 0x9870:
file
obexftp.c, line 376.
(
gdb
) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00009870
in
main at obexftp.c:376
(
gdb
) c
Continuing.
Error
while
mapping shared library sections:
/work/install/bluetooth//lib/libobexftp
.so.0: No such
file
or directory.
Error
while
mapping shared library sections:
/work/install/bluetooth//lib/libc
.so.6: No such
file
or directory.
Breakpoint 1, main (argc=1, argv=0xbed0dec4) at obexftp.c:384
384
if
(strstr(argv[0],
"ls"
) != NULL) most_recent_cmd =
'l'
;
(
gdb
)
|
(相对与远程调试,gdb默认搜索的路径即为交叉编译器的库路径,下面我会介绍到)
因此,这里我们需要修改一下gdb默认的共享库搜索路径。
修改的办法是设置GDB的环境变量:
1
2
3
4
5
6
7
8
9
10
11
|
hong@ubuntu:~
/work/system
$ arm-none-linux-gnueabi-
gdb
-q ipcr002_debug_gdb
(
gdb
) show solib-absolute-prefix
The current system root is
""
.
(
gdb
) show solib-search-path
The search path
for
loading non-absolute shared library symbol files is .
(
gdb
)
set
solib-absolute-prefix
/opt/arm-2009q3/arm-none-linux-gnueabi/libc
(
gdb
)
set
solib-search-path
/tftpboot/ak_ipc
(
gdb
) show solib-absolute-prefix
The current system root is
"/opt/arm-2009q3/arm-none-linux-gnueabi/libc"
.
(
gdb
) show solib-search-path
The search path
for
loading non-absolute shared library symbol files is
/tftpboot/ak_ipc
.
|
solib-absolute-prefix设置的是被搜索文件路径的前缀,一般设置为交叉编译工具链的库路径前缀,即不包括lib目录,lib目录的父目录,solib-search-path设置的是被搜索库文件的路径。solib-search-path可以有多个路径,中间按用:隔开, solib-absolute-prefix的值只能有一个。若在solib-absolute-prefix指定的路径内没有搜索到库,则再继续尝试从solib-search-path指定的路径进行搜索。
1
2
3
4
5
6
7
8
|
hong@ubuntu:~$
ls
-l
/opt/arm-2009q3/arm-none-linux-gnueabi/libc
total 24
drwxr-xr-x 6 wenju wenju 4096 Oct 17 2009 armv4t
drwxr-xr-x 2 wenju wenju 4096 Oct 17 2009 etc
drwxr-xr-x 2 wenju wenju 4096 Oct 17 2009 lib
# 前缀为父目录,/lib/ld-linux.so .etc.
drwxr-xr-x 2 wenju wenju 4096 Oct 17 2009 sbin
drwxr-xr-x 6 wenju wenju 4096 Oct 17 2009 thumb2
drwxr-xr-x 10 wenju wenju 4096 Oct 17 2009 usr
|
详细参考GDB手册中相关部分:
http://wiki.chinaunix.net/index.php/GDB_Manual_15_1
设置好solib-search-path后再运行程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
(
gdb
)
set
solib-search-path
/work/install/bluetooth/lib/
(
gdb
) c
Continuing.
Error
while
reading shared library symbols:
Dwarf Error: Can
't read DWARF data from '
/opt/montavista/pro/devkit/arm/v5t_le/target/usr/lib/debug/lib/ld-2
.5.90.so.debug'
Breakpoint 1, main (argc=1, argv=0xbe896eb4) at obexftp.c:384
384
if
(strstr(argv[0],
"ls"
) != NULL) most_recent_cmd =
'l'
;
(
gdb
) l
379 char *output_file = NULL;
380 char *move_src = NULL;
381 /* char *inbox; */
382
383 /* preset mode of operation depending on our name */
384
if
(strstr(argv[0],
"ls"
) != NULL) most_recent_cmd =
'l'
;
385
if
(strstr(argv[0],
"get"
) != NULL) most_recent_cmd =
'g'
;
386
if
(strstr(argv[0],
"put"
) != NULL) most_recent_cmd =
'p'
;
387
if
(strstr(argv[0],
"rm"
) != NULL) most_recent_cmd =
'k'
;
388
(
gdb
)
|
注:使用GDB调试时查看代码不是很方便。CLWEN使用VIM作为GDB前端界面,结合gdb的远程调试功能,动态的将程序当前运行的代码显示在VIM上,查看起来十分方便。其远程调试方法和GDB+GDB Server一样,但是多了一个GUI界面(VIM)。