一.调试环境
一般的GDB调试为本机环境下调试,如在一台Centos6的服务器上编写demo,那么gdb调试时只需要运行gdb工具并指定待调试文件即可开始调试;
如:
[xxx@centos6]$ gdb a.out
//……
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/a.out...done.
(gdb)
(gdb) b add3
Breakpoint 1 at 0x4004d1: file /home/exe_demo.c, line 5.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004004d1 in add3 at /home/exe_demo.c:5
然而在嵌入式开发中常见的是demo需要在嵌入式设备端运行并调试,一般情况下基本的条件是:demo使用嵌入式设备soc厂商提供的交叉编译器X编译、嵌入式设备与服务器通过串口\网络进行通信。
那么就需要gdbserver,gdbserver是调试用户空间程序的工具,允许gdb和被调试程序分别在两个机器上运行。使用方法可以参考——gdbserver使用简介、gdb+gdbserver远程调试环境搭建及调试
通常情况下gdbserver和交叉编译器都是配套的,由soc厂商提供;
以下示例:
1.nfs挂载,方便将gdbserver工具的待调试程序拷贝到嵌入式设备中;
mount -t nfs -o nolock,tcp 192.168.1.100:/home/nfs/ /home
2.设备端运行gdbserver工具 [gdbserver] [IP]:[端口号] [待调试程序]
/home/# /home/gdb/gdbserver-XSoC 192.168.1.100:6688 exe_demo
Process /home/exe_demo created; pid = 1979
Listening on port 22228
3.服务器端运行gdb工具[gdb] [待调试程序]
,通过TCP与嵌入式设备通信:target remote [IP]:[端口号]
[xxx@centos6]$ arm-XSoC-linux-gdb ./build/exe_demo
//……
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./build/exe_demo...done.
(gdb)
(gdb) target remote 192.168.1.100:6688
Remote debugging using 192.168.1.100:6688
Reading symbols from /opt/arm-XSoC-linux/arm-XSoC-linux-9.1.0/arm-XSoC-linux/sysroot/lib/ld-uClibc.so.0...(no debugging symbols found)...done.
0xb6feaea4 in _start () from /opt/arm-XSoC-linux/arm-XSoC-linux-9.1.0/arm-XSoC-linux/sysroot/lib/ld-uClibc.so.0
(gdb)
二、调试命令
- b 下断点
//1.1 通过文件名+行号 下断点:
(gdb) b 03StackAnaly.c:11
Breakpoint 1 at 0x10668: file /home/exe_demo.c, line 11.
//1.2 通过函数名下点断,注意C++的需要把函数作用域一起加上
(gdb) b add3
Breakpoint 2 at 0x1063c: file /home/exe_demo.c, line 5.
//info b查看断点信息
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00010668 in add5 at /home/exe_demo.c:11
2 breakpoint keep y 0x0001063c in add3 at /home/exe_demo.c:5
(gdb)
- c运行到断点
(gdb) c
Continuing.Breakpoint 2, add3 (a1=1, a2=2, a3=3) at /home/exe_demo.c:5
warning: Source file is more recent than executable.
5 int sum = 0;
- bt查看调用堆栈
(gdb) bt
#0 add3 (a1=1, a2=2, a3=3) at /home/exe_demo.c:5
#1 0x0001070a in main () at /home/exe_demo.c:34
(gdb)
- f x进入x层调用栈
(gdb) f 1
#1 0x0001070a in main () at /home/exe_demo.c:34
34 result = add3(a, b, c);
- p 打印变量信息
(gdb) p a
$1 = 1
(gdb) p b
$2 = 2
(gdb)
6 info r 查看所有寄存器的值,以ARMv7为例
(gdb) info r
r0 0x1 1
r1 0x2 2
r2 0x3 3
r3 0x0 0
r4 0x10519 66841
r5 0xb6fd6018 3070058520
r6 0x10571 66929
r7 0xbefffb78 3204447096
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x0 0
r12 0xbefffc38 3204447288
sp 0xbefffb60 0xbefffb60
lr 0x1070b 67339
pc 0x1070a 0x1070a <main+56>
cpsr 0x40000030 1073741872
fpscr 0x0 0
- x命令,打印内存
//x/32xw 0xbefffb60 打印内存0xbefffb60后的32个4字节,
(gdb) x/32xw 0xbefffb60
0xbefffb60: 0xbefffb78 0xb6ffef70 0xb6ff9490 0x00000000
0xbefffb70: 0x00000000 0xb6fec471 0x00000000 0x00000009
0xbefffb80: 0x00000008 0x00000007 0x00000006 0x00000005
0xbefffb90: 0x00000004 0x00000003 0x00000002 0x00000001
0xbefffba0: 0xb6ffef70 0xb6fa11ff 0xb6fd2c44 0xbefffcf4
0xbefffbb0: 0x00000001 0x000106d3 0xb6f80769 0xb6faffb1
0xbefffbc0: 0x00000000 0x00000000 0x00010519 0xb6fd6018
0xbefffbd0: 0x00010571 0xb6ffef70 0x00000000 0x00000000
//x/32xw $sp 打印sp指针指向的内存0xbefffb60后的32个4字节
(gdb) x/32xw $sp
0xbefffb60: 0xbefffb78 0xb6ffef70 0xb6ff9490 0x00000000
0xbefffb70: 0x00000000 0xb6fec471 0x00000000 0x00000009
0xbefffb80: 0x00000008 0x00000007 0x00000006 0x00000005
0xbefffb90: 0x00000004 0x00000003 0x00000002 0x00000001
0xbefffba0: 0xb6ffef70 0xb6fa11ff 0xb6fd2c44 0xbefffcf4
0xbefffbb0: 0x00000001 0x000106d3 0xb6f80769 0xb6faffb1
0xbefffbc0: 0x00000000 0x00000000 0x00010519 0xb6fd6018
0xbefffbd0: 0x00010571 0xb6ffef70 0x00000000 0x00000000
在GDB调试工具中,以下是x命令的不同选项和含义:
x/32xw
: 这个命令表示以16进制格式显示32个元素的内容,并以双字(double word)为单位进行显示。每个双字的大小通常为4个字节(32位)。这个选项对于查看内存中的数据非常有用。x/32xg
: 这个命令表示以16进制格式显示32个元素的内容,并以词(word)为单位进行显示。每个词的大小通常为4个字节(32位)。这个选项可以用于查看内存中的数据。x/32xb
: 这个命令表示以16进制格式显示32个元素的内容,并以字节(byte)为单位进行显示。每个字节的大小为1个字节(8位)。使用这个选项可以查看内存中的原始字节。x/32xc
: 这个命令表示以字符格式显示32个元素的内容,并以每个字符(character)的形式进行显示。这个选项可以在内存中查看字符串或字符数组数据。
可以根据需要调整数量和显示格式,例如 x/8xg
将显示8个词以16进制格式,x/16xb
将显示16个字节以16进制格式。可以参考GDB的文档或手册,以了解更多选项和使用方法。
- ni 1命令,单步执行汇编,n步执行则将数字1改为n
(gdb) ni 1 //n步执行则将数字1改为n
0x0001063e 5 int sum = 0;
- disassemble 查看反汇编
(gdb) disassemble
Dump of assembler code for function add3:0x00010630 <+0>: push {r7}0x00010632 <+2>: sub sp, #280x00010634 <+4>: add r7, sp, #00x00010636 <+6>: str r0, [r7, #12]0x00010638 <+8>: str r1, [r7, #8]0x0001063a <+10>: str r2, [r7, #4]0x0001063c <+12>: movs r3, #0
=> 0x0001063e <+14>: str r3, [r7, #20]0x00010640 <+16>: ldr r2, [r7, #12]0x00010642 <+18>: ldr r3, [r7, #8]0x00010644 <+20>: add r3, r20x00010646 <+22>: ldr r2, [r7, #4]0x00010648 <+24>: add r3, r20x0001064a <+26>: str r3, [r7, #20]0x0001064c <+28>: ldr r3, [r7, #20]0x0001064e <+30>: mov r0, r30x00010650 <+32>: adds r7, #280x00010652 <+34>: mov sp, r70x00010654 <+36>: ldr.w r7, [sp], #40x00010658 <+40>: bx lr
End of assembler dump.
- info sharedlibrary 查看动态库的加载情况
(gdb) info sharedlibrary
From To Syms Read Shared Object Library
0xb6feae60 0xb6fee348 Yes (*) /opt/arm-XSoC-linux/arm-XSoC-linux-9.1.0/arm-XSoC-linux/sysroot/lib/ld-uClibc.so.0// 带(*)的表示这个动态库没有调试符号
0xb6f785f0 0xb6fb51e4 Yes /opt/arm-XSoC-linux/arm-XSoC-linux-9.1.0/arm-XSoC-linux/sysroot/lib/libc.so.0
(*): Shared library is missing debugging information.// 未加载上的动态库可能的原因:1)gdbLib目录中没有该动态库。2)有该动态库但是名字不一样,这时候需要修改下本地动态库的名字。
- thread apply all bt 查看所有线程的堆栈
(gdb) thread apply all btThread 1 (Thread 1979.1979):
#0 0x0001063e in add3 (a1=1, a2=2, a3=3) at /home/exe_demo.c:5
#1 0x0001070a in main () at /home/exe_demo.c:34
- info symbol 查看地址对应的符号信息,只有代码段、全局数据段、bss段才能返回符号信息
(gdb) disassemble
Dump of assembler code for function add3:0x00010630 <+0>: push {r7}0x00010632 <+2>: sub sp, #280x00010634 <+4>: add r7, sp, #00x00010636 <+6>: str r0, [r7, #12]0x00010638 <+8>: str r1, [r7, #8]0x0001063a <+10>: str r2, [r7, #4]0x0001063c <+12>: movs r3, #0
=> 0x0001063e <+14>: str r3, [r7, #20]0x00010640 <+16>: ldr r2, [r7, #12]0x00010642 <+18>: ldr r3, [r7, #8]0x00010644 <+20>: add r3, r20x00010646 <+22>: ldr r2, [r7, #4]0x00010648 <+24>: add r3, r20x0001064a <+26>: str r3, [r7, #20]0x0001064c <+28>: ldr r3, [r7, #20]0x0001064e <+30>: mov r0, r30x00010650 <+32>: adds r7, #280x00010652 <+34>: mov sp, r70x00010654 <+36>: ldr.w r7, [sp], #40x00010658 <+40>: bx lr
End of assembler dump.
(gdb) info symbol 0x00010648
add3 + 24 in section .text of /home/355308/test/blueOceanProject/03/build/03StackAnaly
(gdb)