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