Linux 调试器 --- g d b 使用

2023-12-13 05:14:14

目录


一:gdb简介

二:示例代码

三:使用

1.启动gdb

2.各种指令

<1>: 查看源代码?

<2>:设置断点

<3>:查看断点信息

<4>:删除断点

<5>: run?

<6>:逐过程调试

<7>:逐语句调试

<8>:查看变量值

<9>:跳转行号

四:总结


一:gdb简介

? ? ? ? GDB 全称“GNUsymbolic?debugger”,是?Linux?下常用的程序调试器。发展至今,GDB?已经迭代了诸多个版本,当下的?GDB?支持调试多种编程语言编写的程序,包括?C、C++、Go?等等。实际场景中,GDB?更常用来调试?C?和?C++?程序。一般来说,GDB主要帮助我们完成以下四个方面的功能:?启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。?在某个指定的地方或条件下暂停程序。?当程序被停住时,可以检查此时你的程序中所发生的事。?在程序执行过程中修改程序中的变量或条件,将一个bug产生的影响修正从而测试其他bug。

二:示例代码

code.c 文件内容为:

#include<stdio.h>
int ADDToTop(int num)
{
    int result = 0;
    int i = 0;
    for(i = 1; i <= num; i++)
    {
        result += i;
    }
    return result;
}
int main()
{
    int num = 10;
    int sum = 0;

    sum = ADDToTop(num);

    printf("sum: %d\n",sum);
    return 0;
}

makefile 文件内容为:

mycode:code.c
		gcc -o $@ $^ -g
.PHONY:clean
clean:
		rm -f mycode

我们知道程序的发布形式,有两种,一种为 debug 模式,另一种为 release 模式。一般情况下,编译指令为: gcc code.c -o test ,要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项。不加就是默认为 release 版本。

编译为 debug 版本的指令为:

gcc code.c -o code.debug -g -std=c99

debug版本需要一些调试信息,占用的内存更大,所以我们可以通过占用内存的大小,判断Linux gcc/g++出来的二进制程序,默认是哪一种模式?

89a4768a9a4b47ffad37919f0b666b51.png

通过上述示例,我们可以看出,Linux gcc/g++出来的二进制程序,默认是release模式。

5dc4d7cde85a4bbdafdc105b16f114d6.png

-std = c99 ,c99 是C语言的一个标准,该标准规定了可以在循环控制条件里面定义变量,(eg:for(int i = 0; i < 10; i++)。如果没有使用,则可能会导致:

683e2b8658164be5ae41d1ae7f1242d9.png

三:使用

1.启动gdb

启动 gdb 的指令为 [gdb + 文件的名称] 示例:

gdb mycode

运行效果为:

b1f0998dc3da4841ba2554db0be1eccf.png

此时,需要我们切换为 root 用户,安装 gdb ,如下图所示:

b752e8df1b0f4b75bd46a7fca6edc3bd.png

此时,我们再切回普通用户,进行启动 gdb 的工作:

63122376969344bb9d0e6f02c52d6194.png

73a03a26f95e4390a61991da8581bb74.png

如果出现上述界面,则说明已经进入 gdb 调试,接下来可以开始使用各种指令进行调试。

2.各种指令

在进行各种调试指令之前,我们需要首先知道退出调试的指令:

ctrl + d 或 quit 调试命令

<1>: 查看源代码?

list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。

ddfeb7f86d034c048b3c90898a8e0dea.png

<2>:设置断点

break(b)?行号:在某一行设置断点

我们此处在以 #include<stdio.h> 为第一行的第16行打上断点:?

058377009557425281a31ab0e4d8954a.png

break?函数名:在某个函数开头设置断点

在 main 函数,和 ADDToTop函数开头打断点?

5438d82629ff4b1290b456ff5278515b.png

<3>:查看断点信息

info break :查看断点信息

我们查看在 <2> 第16行所打的断点:

a43a8251d0be4d5082c8bd25e28f07ec.png

Num --- 编号? ?Type --- 种类? ?Address --- 断点在内存中的位置? What --- 断点在程序中的位置

查看 <2> 中指定函数名打断点:

6fac154aa6fc4ad7a9c7418986c305c1.png

<4>:删除断点

delete?breakpoints?n:删除序号为n的断点
disable?breakpoints:禁用断点
enable?breakpoints:启用断点

n --- 表示该断点不可用,y --- 表示该断点可用

3bccfa7e94a54e888c8581542bb36e04.png?如果想把已经变为 n 的改变为 y ,则需要执行:enable b 3 命令,示例:

dffc3c929339428b9c9cdd57fedb4522.png

<5>: run?

run(或r):从开始连续而非单步执行程序
如果有断点,则执行到断点处停止,如果没有断点,则执行到结束。

c8ae98f5eef74505aa12a14c0b2a210d.png

d69fa615ed6d4b1a8bd6eb3c7e28beb3.png

<6>:逐过程调试

n 或 next:单条执行。一步步执行,但不会进入函数内部

清空原来的所有断点,在第16行打上断点,按下 r? 运行键,程序会在断点处停下,此时输入 n,观察现象:

?程序直接执行完了 ADDToTop 函数内部的全部内容。

<7>:逐语句调试

s或step:进入函数调用,遇到函数时,会进入函数内调试

?保持第16行的断点,按下 r 执行到断点处停止,此时在按下 s ,观察现象:

我们发现逐语句调试过程中,进入了?ADDToTop 函数内部,并且一步一步往下执行。

<8>:查看变量值

p 变量:打印变量值。

?可以用于查看循环执行到某一步的时候,查看某个/某些变量的值,如下图所示:

<9>:跳转行号

until X行号:跳至X行

当我们进入一个函数后,可能会存在需要循环很多次的场景,此时,我们可以通过 until 行号 跳转到指定行数,示例如下:

?

四:总结


  • list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
  • list/l 函数名:列出某个函数的源代码。
  • r或run:运行程序。
  • n 或 next:单条执行。
  • s或step:进入函数调用
  • break(b)?行号:在某一行设置断点
  • break?函数名:在某个函数开头设置断点
  • info break :查看断点信息。
  • finish:执行到当前函数返回,然后挺下来等待命令
  • print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
  • p 变量:打印变量值。
  • set?var:修改变量的值
  • continue(或c):从当前位置开始连续而非单步执行程序
  • run(或r):从开始连续而非单步执行程序
  • delete?breakpoints:删除所有断点
  • delete?breakpoints?n:删除序号为n的断点
  • disable?breakpoints:禁用断点
  • enable?breakpoints:启用断点
  • info(或i)?breakpoints:参看当前设置了哪些断点
  • display?变量名:跟踪查看一个变量,每次停下来都显示它的值
  • undisplay:取消对先前设置的那些变量的跟踪
  • until X行号:跳至X行
  • breaktrace(或bt):查看各级函数调用及参数
  • info(i)?locals:查看当前栈帧局部变量的值
  • quit:退出gdb

文章来源:https://blog.csdn.net/weixin_74828161/article/details/134768269
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。