使用gdb远程调试嵌入式主板程序

0. 准备工作

0.0 环境:

Linux:Ubuntu18 64Bit in VMWare

嵌入式目标板:随意,需要和虚拟机IP同一网段

0.1. 网络连接:

保证虚拟机和目标板之间能正常通信。

0.2. 文件确认

先确认是否存在下列两个文件:

gdbserver目标板上运行的gdb调试服务,在板子上运行。板子上运行该程序后,就可以在电脑上进行连接和调试。

aarch64-himix100-linux-gdb电脑上运行的调试软件,其中aarch64-himix100-linux-是编译器前缀。

这两个文件可以在交叉编译工具链下找到。

1. 运行准备

1.1 目标板

gdbserver复制到目标板上,或使用nfs挂载。

命令行运行gdbserver,看是否报错。

如果出现类似下面的输出则无异常。

/nfsroot/gdbserver # ./gdbserver 
Usage:	gdbserver [OPTIONS] COMM PROG [ARGS ...]
	gdbserver [OPTIONS] --attach COMM PID
	gdbserver [OPTIONS] --multi COMM
    ...

1.2 虚拟机

执行aarch64-himix100-linux-gdb

如果进入了gdb,则无异常。

已知异常:

  1. 缺少libexpat.so库。

    解决方法:(参考:https://www.cnblogs.com/reddusty/p/5232151.html)

    先用命令file确认可执行文件aarch64-himix100-linux-gdb的文件版本。

    clair@clair-virtual-machine:~/aarch64-himix100-linux/aarch64-himix100-linux/host_bin$file /opt/hisi-linux/x86-arm/aarch64-himix100-linux/host_bin/aarch64-linux-gnu-gdb
    /opt/hisi-linux/x86-arm/aarch64-himix100-linux/host_bin/aarch64-linux-gnu-gdb: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.8, with debug_info, not stripped
    

    这里看到aarch64-himix100-linux-gdb是32位的可执行文件。

    搜索整个系统,找到/lib/x86_64-linux-gnu/libexpat.so.1.6.7。但是该文件是64位的so库,无法被32位的可执行文件调用

    clair@clair-virtual-machine:~/aarch64-himix100-linux/aarch64-himix100-linux/host_bin$ file /lib/x86_64-linux-gnu/libexpat.so.1.6.7 
    /lib/x86_64-linux-gnu/libexpat.so.1.6.7: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=49976d874cc89dfcebf8c5dbf329149bfb40dab5, stripped
    

    说明需要安装32位的lib。

    执行下列命令(首先需要保证已经安装了32位系统的支持):

    安装multilib:

    sudo apt-get install gcc-multilib
    

    lld查看缺少的lib:

    lld /opt/hisi-linux/x86-arm/aarch64-himix100-linux/host_bin/aarch64-linux-gnu-gdb
    

    安装对应的lib的32bit支持库(在库名后加i386):

    sudo apt-get install libexpat1:i386
    

    结束。

  2. 运行后提示ImportError: No module named _sysconfigdata_nd

    这是ubuntu的一个bug,具体解决方法为:创建一个软链接:

    sudo ln -s /usr/lib/python2.7/plat-*/_sysconfigdata_nd.py /usr/lib/python2.7/
    

    结束。

2. gdb简单调试

2.1 测试程序编译运行

测试程序如下:

#include <stdio.h>

int main()
{
    printf("Hello World\n");
    return 0;
}

交叉编译生成可执行文件,需要带上-g参数保留符号信息:

aarch64-himix100-linux-gcc -g hello.c -o hello

2.2 目标板gdbserver加载程序

命令如下:

./gdbserver 192.168.172.199:3559 hello

其中192.168.172.199是开发板的ip地址,可省略不写。

3559是监听的端口号。

hello是待调试的程序。

运行结果如下则说明正常运行:

/nfsroot/gdbserver # ./gdbserver 192.168.172.199:3559 hello
Process hello created; pid = 1440
gdbserver: Unable to determine the number of hardware watchpoints available.
gdbserver: Unable to determine the number of hardware breakpoints available.
Listening on port 3559

2.3 虚拟机上测试远程连接和调试:

虚拟机shell直接执行aarch64-himix100-linux-gdb,输入远程连接命令:

(gdb) target remote 192.168.172.199:3559

连接成功后,输入l可看到代码:

(gdb) l
1	#include <stdio.h>
2	
3	int main()
4	{
5	    printf("Hello World\n");
6	    return 0;
7	}

在第5、6行添加断点:

(gdb) b 5
Breakpoint 1 at 0x400598: file hello.c, line 5.
(gdb) b 6
Breakpoint 2 at 0x4005a4: file hello.c, line 6.

查看断点列表:

(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400598 in main at hello.c:5
2       breakpoint     keep y   0x00000000004005a4 in main at hello.c:6

程序运行,然后会停在第一个断点处:

(gdb) c
Continuing.
Reading /lib64/libc.so.6 from remote target...

Breakpoint 1, main () at hello.c:5
5	    printf("Hello World\n");
(gdb)

输入c继续或n单步运行该命令,目标板会输出Hello World。

/nfsroot/gdbserver # ./gdbserver 192.168.172.199:3559 hello
Process hello created; pid = 1440
gdbserver: Unable to determine the number of hardware watchpoints available.
gdbserver: Unable to determine the number of hardware breakpoints available.
Listening on port 3559
Remote debugging from host 192.168.172.200
Hello World

继续执行,程序退出。

虚拟机上输入命令q退出gdb。

(gdb) q
clair@clair-virtual-machine:~/aarch64-himix100-linux/aarch64-himix100-linux/host_bin$ 

测试结束。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐