gdb 工具的简单使用

gdb工具是个颇有用的工具.常常用于咱们项目的调试使用。docker

首先咱们来启动一个镜像:sass

docker run -it --privileged=true thrift/new  /bin/bash
复制代码

1. 咱们看下今天要分析的代码:

#include "stdio.h"

int getSum(int param_one,int param_two)
{
   return param_one+param_two;
}

int main()
{
   int a = 10;
   int b = 5;
   int sum = getSum(a,b);
   printf("%d",sum);
}
复制代码

使用gcc编译:bash

gcc -g -o test test.c
复制代码

加上 -g 选项即为了程序编译后的程序中保留调试符号信息数据结构

若是发布代码的话,能够使用命令来移除调试符号信息:函数

strip test
复制代码

2. gdb 实操

函数级别断点

gdb test

#break指令 在main函数处断点
b main

#在getSum函数处断点
b getSum
复制代码

接下来咱们看下执行流程:工具

#run r命令重启程序将在断点处停下
r

Breakpoint 1, main () at test.c:10
10	   int a = 10;

复制代码
#continue 继续向下执行
c 

Breakpoint 2, getSum (param_one=10, param_two=5) at test.c:5
5	   return param_one+param_two;
复制代码

咱们看到已经执行到咱们的第二个断点上来了。ui

固然,还有更加灵活的断点方式,具体到咱们的代码某行.spa

#在咱们的例子代码中,断点第五行代码
b test.c:5

Breakpoint 1 at 0x400527: file test.c, line 5.

#运行run
r
Breakpoint 1, getSum (param_one=10, param_two=5) at test.c:5
5	   return param_one+param_two;
复制代码

断点是为了更好的调试咱们的程序, 可是咱们发现这样调试来信息仍是比较少, 若是想了解调用的堆栈信息, 咱们继续看下面的指令调试

backtrace 命令(简写为 bt)code

(gdb)b test.c:5

(gdb)r

(gdb) bt
#0 getSum (param_one=10, param_two=5) at test.c:5
#1 0x0000000000400556 in main () at test.c:12
复制代码

咱们看到了调用的堆栈信息 main()->getSum()

函数调用为栈的数据结构存储形式

咱们看到只有两层栈的调用,咱们能够使用frame切换到指定的栈.

#frame 堆栈编号
f 1

#1 0x0000000000400556 in main () at test.c:12
12	   int sum = getSum(a,b);
复制代码

咱们能够看到具体的调用方式

当咱们断点或切换到某个堆栈的时候,还想更详细的看当前断点代码

# list l 当前断点处的代码

#切换栈
(gdb) f 1

(gdb) l
8	int main()
9	{
10	   int a = 10;
11	   int b = 5;
12	   int sum = getSum(a,b);
13	   printf("%d",sum);
14	}
复制代码

查看当前运行的变量值(print)

#打印params_two的值
p params_two 
$1 = 10
复制代码

咱们还能够手动修改当前运行变量

p params_two=50
复制代码

查看咱们打了哪些断点

info b

Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400539 in main at test.c:10
2       breakpoint     keep y   0x0000000000400527 in getSum at test.c:5
复制代码

禁用/启用某个断点

disable 断点编号
enable 断点编号
复制代码

使用delete命令删除断点

(gdb) delete

Delete all breakpoints? (y or n) y
复制代码

查看断点的汇编指令

(gdb) disassemble

Dump of assembler code for function main:
   0x0000000000400531 <+0>:	push   %rbp
   0x0000000000400532 <+1>:	mov    %rsp,%rbp
   0x0000000000400535 <+4>:	sub    $0x10,%rsp
=> 0x0000000000400539 <+8>:	movl   $0xa,-0x4(%rbp)
   0x0000000000400540 <+15>:	movl   $0x5,-0x8(%rbp)
   0x0000000000400547 <+22>:	mov    -0x8(%rbp),%edx
   0x000000000040054a <+25>:	mov    -0x4(%rbp),%eax
   0x000000000040054d <+28>:	mov    %edx,%esi
   0x000000000040054f <+30>:	mov    %eax,%edi
   0x0000000000400551 <+32>:	callq  0x40051d <getSum>
   0x0000000000400556 <+37>:	mov    %eax,-0xc(%rbp)
   0x0000000000400559 <+40>:	mov    -0xc(%rbp),%eax
   0x000000000040055c <+43>:	mov    %eax,%esi
   0x000000000040055e <+45>:	mov    $0x400600,%edi
   0x0000000000400563 <+50>:	mov    $0x0,%eax
   0x0000000000400568 <+55>:	callq  0x400400 <printf@plt>
   0x000000000040056d <+60>:	leaveq 
   0x000000000040056e <+61>:	retq   
End of assembler dump.
复制代码

使用watch监控某个变量的变化

(gdb) b main 

(gdb) r

(gdb) watch sum

Old value = 32767
New value = 15
main () at test.c:13
13	   printf("%d",sum);
复制代码

先到这里吧, 等接下来咱们再研究下多进程的代码如何使用gdb调试。

相关文章
相关标签/搜索