gdb工具是个颇有用的工具.常常用于咱们项目的调试使用。docker
首先咱们来启动一个镜像:sass
docker run -it --privileged=true thrift/new /bin/bash
复制代码
#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
复制代码
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 }
复制代码
#打印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 断点编号
复制代码
(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.
复制代码
(gdb) b main
(gdb) r
(gdb) watch sum
Old value = 32767
New value = 15
main () at test.c:13
13 printf("%d",sum);
复制代码
先到这里吧, 等接下来咱们再研究下多进程的代码如何使用gdb调试。