使用gdb调试c语言代码
1. 前言编写代码过程中少不了调试。在windows下面,我们有visual studio工具。在linux下面呢,实际上除了gdb工具之外,你没有别的选择。那么,怎么用gdb进行调试呢?我们可以一步一步来试试看。先写一个代码, 文件名01_1_gdb.c/** @Author: sanjayzhong* @Github: https://github.com/sanjayzzz...
1. 前言
编写代码过程中少不了调试。在windows下面,我们有visual studio工具。在linux下面呢,实际上除了gdb工具之外,你没有别的选择。那么,怎么用gdb进行调试呢?我们可以一步一步来试试看。
先写一个代码, 文件名01_1_gdb.c
/*
* @Author: sanjayzhong
* @Github: https://github.com/sanjayzzzhong
* @Date: 2019-10-02 19:30:57
*/
#include <stdio.h>
int func(int a, int b){
int t_a = a;
int t_b = b;
return t_a + t_b;
}
int main(){
int ret = 0;
ret = func(10, 20);
int a = 20;
return 0;
}
既然需要调试,那么生成的可执行文件就需要包含调试的信息,这里应该怎么做呢?
很简单,输入gcc 01_1_gdb.c -g
输入命令之后,如果没有编译和链接方面的错误,你就可以看到可执行文件a.out
了。
2. 调试步骤
-
首先, 在可执行文件
a.out
所在的目录打开终端,输入gdb a.out
-
进入到gdb调试界面, 输入
list
,就可以看到01_1_gdb.c
原文件,也就是代码 -
设置断点, 输入
b main
-
启动程序, 输入
run
程序在main开始的地方设置了断点,所以程序在
int ret = 0
处断住注意:这里显示的语句是表示下一句要执行的
-
这时候,可以单步跟踪。s单步可以进入到函数,而n单步则越过函数
-
如果希望从断点处继续运行程序,输入c
-
希望程序运行到函数结束,输入finish
-
查看断点信息, 输入
info break
-
如果希望查看堆栈信息,输入
bt
ps:这里的意思是只有
main
函数在栈中 -
如果希望看到更详细的堆栈信息,比如说现在的堆栈是:
(gdb) bt #0 func (a=10, b=20) at 01_1_gdb.c:9 #1 0x0000555555554638 in main () at 01_1_gdb.c:17
可以输入
info frame
查看栈的信息:(gdb) info frame Stack level 0, frame at 0x7fffffffd780: rip = 0x555555554604 in func (01_1_gdb.c:9); saved rip = 0x555555554638 called by frame at 0x7fffffffd7a0 source language c. Arglist at 0x7fffffffd770, args: a=10, b=20 Locals at 0x7fffffffd770, Previous frame's sp is 0x7fffffffd780 Saved registers: rbp at 0x7fffffffd770, rip at 0x7fffffffd778
然后可以指定某一层的栈:
f 0
(gdb) f 0 #0 func (a=10, b=20) at 01_1_gdb.c:9 9 int t_a = a; (gdb) s 10 int t_b = b; (gdb) 11 return t_a + t_b; (gdb) f 0 #0 func (a=10, b=20) at 01_1_gdb.c:11 11 return t_a + t_b;
但是这样只能看到栈的信息和下一行要执行的代码,如果想要看到函数里面所有的局部变量和值,应该输入:
info locals
:(gdb) info locals t_a = 10 t_b = 20 (gdb) s 12 } (gdb) info locals t_a = 10 t_b = 20 (gdb) n main () at 01_1_gdb.c:18 18 int a = 20; (gdb) info locals ret = 30 a = 0
总结:
info frame 会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句
info args 打印出当前函数的参数名及其值。
info locals 打印出当前函数中所有局部变量及其值。
info catch 打印出当前的函数中的异常处理信息 -
希望查看内存,输入
x/64xh + 内存地址
-
删除断点,则输入
delete break + 断点序号
-
希望查看函数局部变量的数值,可以输入
print + 变量名
-
希望修改内存值,直接输入
print + *地址 = 数值
-
希望实时打印变量的数值,可以输入
display + 变量名
-
查看函数的汇编代码,输入
disassemble + 函数名
-
退出调试输入
quit
即可
3. 函数调用流程
顺便用一张图来说明一下以上代码在执行时的调用流程,主要是在栈上:
更多推荐
所有评论(0)