使用gdb调试c语言代码

mac2022-06-30  19

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)