arm-linux下的多线程调试

来源:互联网 发布:mac safari 清除缓存 编辑:程序博客网 时间:2024/05/30 04:46

gdb是UNIX及UNIX-like下的调试工具。在linux下开发的人一定不会陌生,在arm-linux下也有对应的调试版本。下面记录一下在工作中用到的一些在arm-linux下用gdb调试多线程的一些知识。

一、下载调试工具
工程中使用了arm-none-linux-gnueabi-gcc编译器,提供一个下载网站arm-none-linux-gnueabi-gcc。
安转以后执行 arm-arago-linux-gnueabi-gdb -v即可查看版本信息和安转成功与否。

xxx@xxx-desktop:~/workdir/$ arm-arago-linux-gnueabi-gdb -vGNU gdb (GDB) 7.2Copyright (C) 2010 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=i686-linux --target=arm-arago-linux-gnueabi".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.

二、调试环境的建立
1、在下位机中输入:gdbserver 10.11.13.19:215 test.app

/mnt/test/ # gdbserver 10.11.13.19:215 test.app Process test.app created; pid = 817Listening on port 215

其中10.11.13.19为主机的ip地址,215为连接的端口号,test.app为要调试的应用程序。成功以后下位机将会监听215端口。
2、在主机输入:arm-arago-linux-gnueabi-gdb test.app

xxx@xxx-desktop:~/workdir/$arm-arago-linux-gnueabi-gdb test.appGNU gdb (GDB) 7.2Copyright (C) 2010 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=i686-linux --target=arm-arago-linux-gnueabi".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/xxx/workdir/test.app...done.(gdb) 

3、下位机与主机建立起连接,在(gdb)的后面输入: target remote 10.11.13.215:215

(gdb) target remote 10.11.13.215:215Remote debugging using 10.11.13.215:215Reading symbols from /lib/ld-linux.so.3...(no debugging symbols found)...done.Loaded symbols for /lib/ld-linux.so.30x400b3790 in ?? () from /lib/ld-linux.so.3(gdb) 

10.11.13.215为下位机的ip地址,215为端口号。成功以后再下位机会答应一条Remote debugging from host 10.11.13.19 的信息。

三、调试过程
上述的一切步骤成功以后就可以执行相应的调试命令来调试程序了,下面介绍一些常用的调试命令。
1、打断点
可以用:b <函数名>

(gdb) b cfg_bswv_main_t::set_pulse_dutyBreakpoint 1 at 0x48828: file cfg_bswv_main.cpp, line 1402.(gdb) 

或者用 b 文件名:行号。

(gdb) b cfg_bswv_valid_check.cpp :301Breakpoint 2 at 0x565a4: file cfg_bswv_valid_check.cpp, line 301.(gdb) 

此外,disable n可以让n断点无效,如disable 2让断点2无效,有效为enable 2,删除断点用disable 2,清除断点用clear
2、让程序执行敲入c就可以了

(gdb)c

3、查看调试过程中的信息可以用info关键字。
例如查看断点信息可以用i(info b):

(gdb) i bNum     Type           Disp Enb Address    What1       breakpoint     keep y   0x00048828 in cfg_bswv_main_t::set_pulse_duty(cfg_data_t) at cfg_bswv_main.cpp:1402        breakpoint already hit 1 time2       breakpoint     keep y   0x000565a4 in cfg_bswv_valid_check_t::check_pulse_duty(fp64&, fp64, fp64, fp64, cfg_bswv_wave_t&) at cfg_bswv_valid_check.cpp:301

info还可以查看很多信息,如查看线程信息:info threads,可以输入info回车自行查找,再次不一一列举。
4、执行下一步用n,步进(可以进入函数内部)用s.
5、查看变量的值用p

(gdb) p data$1 = {data = 20, unit = CFG_IU}

6、查看当前堆栈信息用bt

(gdb) bt#0  cfg_bswv_main_t::set_pulse_duty (this=0x7bed50, data=...) at cfg_bswv_main.cpp:1405#1  0x000487bc in cfg_bswv_main_t::set_pulse_width_duty_mode (this=0x7bed50, pulse_mode=CFG_PULSE_DUTY_MODE)    at cfg_bswv_main.cpp:1369#2  0x0007356c in bswv_pulse_duty_width_mode_msg_t::deal_set_message (this=0x7c1144, msg_data=...)    at cfg_bswv_msg.cpp:1480#3  0x000217b4 in cfg_msg_t::deal_message (this=0x7c1144, in_buffer=0x426da570) at cfg_lib_msg.cpp:49#4  0x0015a168 in deal_message_t::deal (this=0x7c1144, message_buffer=0x426da570) at message.cpp:567#5  0x00159d44 in message_receive_t::deal_message (this=0x426da568) at message.cpp:399#6  0x00159820 in message_receive_t::wait_message (this=0x426da568, msgflg=4096, msg_id=0) at message.cpp:290#7  0x0003c94c in cfg_main (arg=0x0) at cfg_main.cpp:80#8  0x0003c820 in cfg_if_config_thread (arg=0x0) at cfg_if_main.cpp:40#9  0x400ddcf8 in ?? () from /home/ding/ti-sdk-am335x/filesystem/lib/libpthread.so.0#10 0x400ddcf8 in ?? () from /home/ding/ti-sdk-am335x/filesystem/lib/libpthread.so.0Backtrace stopped: previous frame identical to this frame (corrupt stack?)

可以看到程序在当前线程的调用堆栈。此外执行;thread apply all bt 可以查看所有线程的堆栈情况。从中我们也可以发现,每个线程都有各自的调用堆栈。
7、kill 终止调试。
8、break filename:line number 多文件设置断点
9、p/x 十六进制显示变量值

(gdb) p/x frq.data$4 = 0x3e8

10、finish 继续执行知道当前函数结束
11、jump 跳到制定行
12、tbreak 设置临时断点(设置断点只执行一次)
13、p a=5 给变量赋值
14、show scheduler-locking

(gdb) show scheduler-lockingMode for locking scheduler during execution is "off".

off时所有线程都可以得到调度,on时只有当前。
15、set scheduler-locking off|on|step
调试解锁|加锁|步进当前线程,其他线程停止。
16、thread num 查看指定的线程号的线程信息

(gdb) thread 2  [Switching to thread 2 (Thread 815)]#0  cfg_bswv_main_t::set_pulse_duty (this=0x7bed50, data=...)    at cfg_bswv_main.cpp:14071407            get_prd(prd);

17、x/4096xh 内存打印
18、b 477 if point_count=1000 条件断点
19、until 运行到指定行
20、thread apply id1 id2 command
22、 p addpadd + size
dump binary memory ./file 12

除此之外还有很多调试命令,在此不一一列举。可以查阅相关文档找到。不过以上的那些基本够用了~
四、总结
总而言之,在使用的过程中可以感觉到gdb的调试功能还是很强大的,程序有BUG时,先查看代码有没有错误,在适当的地方加上打印信息是一种有效的方法,但是当这些都解决不了时,不防试一试使用gdb。调试的命令还可以写在脚本里执行,执行脚本的命令是:source。

(gdb) source gdbmake.sh 
0 0
原创粉丝点击