嵌入式开发 - GDB串口远程调试

1. 准备调试串口

目标板一般只有一个串口用于控制台输入输出,串口远程调试需要第二个串口。下面假设这个串口设备是/dev/ttyS2。同时假设宿主机上的串口设备是/dev/ttyS1。

  • 检查串口连通性。在宿主机上执行:
$ cat /dev/ttyS1

在板上执行:

$ echo hello > /dev/ttyS2

这时宿主机上应收到hello。如果收到证明宿主机RX方向没有问题。

类似地,反过来检查确认宿主机TX方向没有问题。

  • 如果宿主机上的Linux不是直接装在本机上,而是Windows上的虚拟机(如VMware),则虚拟机需要添加串口。VWware的设置方法如下图:

一般串口1的设备号是/dev/ttyS0,串口2的设备号是/dev/ttyS1 ... 可以用前面的方法验证连通性。

2. 检查 gdb + gdbserver

  • 软件布局

这里的设置影响动态库符号的加载。假设你的软件包mypkg.tar.gz的布局如下:

mypkg/lib
mypkg/bin

在板上安装在/opt目录下:

/opt/mypkg

在宿主机上解压在/home/ronzheng下

/home/ronzheng/opt/mypkg
  • 连接gdbserver

在板上运行如下命令,gdbserver应当显示进程启动信息。为了显示后来的连接信息,这里打开了选项
--remote-debug。

$ cd /opt/mypkg/bin
$ gdbserver --remote-debug /dev/ttyS2 myapp
Process myapp created; pid = 23466
Remote debugging using /dev/ttyS2

在宿主机上运行如下命令,gdb应当从本地加载符号信息。其中9600是/dev/ttyS1的波特率。

$ cd /home/ronzheng
$ arm-linux-gnueabi-gdb -b 9600 opt/pos/bin/myapp
...
Reading symbols from extp/pos/bin/msghub...done.

继续设置sysroot,以便找到动态库的符号信息:

(gdb) set sysroot /home/aronzheng

在main()设置断点:

(gdb) b main

连接串口target,这时板上的gdbserver应该打印一系列连接信息。

(gdb) target remote /dev/ttyS1
Remote debugging using /dev/ttyS1
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
0xb6fd7a00 in ?? ()

运行continue,这时gdb应该停在main()函数上。

(gdb) continue
warning: Could not load shared library symbols for 10 libraries, e.g. /lib/librt.so.1.
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=0xbefffd74) at /home/ronzheng/dev/mypkg/apps/myapp/src/MyApp.cpp:10

这时就可以开始调试了。

也可以用info sharedlib检查动态库的符号加载情况。

(gdb) info sharedlib
From        To          Syms Read   Shared Object Library
0xb6fc5b1c  0xb6fc6180  Yes         /home/ronzheng/opt/pos/lib/libappfrm.so
0xb6fb06c0  0xb6fb340c  Yes         /home/ronzheng/opt/pos/lib/libmsgend.so
                        No          /lib/librt.so.1
                        No          /lib/libdl.so.2
0xb6f7300c  0xb6f73ad0  Yes         /home/ronzheng/opt/pos/lib/libtlog.so
0xb6f1ba50  0xb6f5957c  Yes         /home/ronzheng/opt/pos/lib/libnanomsg.so.5.1.0
                        No          /lib/libstdc++.so.6
                        No          /lib/libm.so.6
                        No          /lib/libgcc_s.so.1
                        No          /lib/libpthread.so.0
                        No          /lib/libc.so.6
                        No          /lib/ld-linux.so.3
                        No          /usr/lib/extra/libanl.so.1
                        No          /lib/libnsl.so.1
  • 切换root用户

连接串口target时,可能出现权限不够的情况:

(gdb) target remote /dev/ttyS1
/dev/ttyS1: Permission denied.

这时需要先切换到root用户:

$ sudo passwd root
$ su

3. 正式调试

去掉gdbserver的--remote-debug选项,重新开始调试。

$ gdbserver /dev/ttyS2 myapp

相关链接

GDB 常用法
GDB 调试Coredump问题
嵌入式开发中GDB调试Coredump问题
嵌入式开发中GDB串口远程调试
用backtrace()调试coredump问题
Valgrind memcheck 用法
Address Sanitizer 用法

参考资料

arm-linux-gdb + gdbserver双串口目标机调试心得
http://blog.sina.com.cn/s/blog_48ca560d0100ej6t.html

ubuntu怎么切换到root用户,切换到root账号方法
https://jingyan.baidu.com/article/fd8044fa1e74035031137ae0.html

你可能感兴趣的:(嵌入式开发 - GDB串口远程调试)