Linux 调试工具:gdb

调试复习

调试可谓是 “贯穿” 了程序员的一生,调试的重要性,就不再赘述啦!如果你还不知道什么是调试,可以看看 Windows 系统的 Visual Studio 是如何调试的:➡️ visual stuudio 使用调试技巧

下载调试软件 gdb

yum install gdb -y

gdb 的使用

gdb 的使用非常简单:

gdb 可执行文件

这是一段简单的代码:

#include<stdio.h>int main()
{printf("hello gdb\n");return 0;
}

这是 makefile 文件:

test:test.cgcc -o $@ $^ -std=c99
.PHONY:clean
clean:rm -f test

make 生成可执行文件之后,我们来看看是否能够启动 gdb 调试:
在这里插入图片描述
我们看到出现了报错:可执行文件中没有调试信息。这是因为 linux 环境下 gcc 形成的可执行程序默认是以 release 的形式发布的,release 版本的可执行程序当然不包含调试信息啦!
于是,我们需要以 debug 的方式发布可执行程序,只需要加一个 -g 的选项就可以啦!

# 这是 makefile 文件
test:test.cgcc -o $@ $^ -g -std=c99
.PHONY:clean
clean:rm -f test

那么如何看到可执行程序中是否有调试信息呢?我们都知道 linux 环境下的可执行程序是一种 elf 格式的文件,我们只要打开这个 elf 格式的文件,就能看到啦!

readelf -S 可执行程序

我们可以看到 debug 方式发布的可执行程序确实多了调式信息。(文件比较长,下图中只截取了一部分)
在这里插入图片描述

调试前的准备

我们来写一个简单的程序,作为调试之前的准备工作吧!
test.c

#include<stdio.h>
#include "function.h"int multiple(int x, int y)
{int ret = x * y;return ret;
}
int main()
{int a = 2, b = 3;int sum = 0;sum = Add(a, b);printf("a + b: %d\n", sum);int times = multiple(a, b);for(int i = 0; i < times; i++){printf("hello gdb %d\n", i);}return 0;
}

function.h

#pragma onceint Add(int x, int y);

function.c

#include "function.h"int Add(int x, int y)
{return x + y;
}

调试命令一览

gdb 可执行程序   #开始调试
quit/q          #退出调试
l 数字          #显示代码,默认是 10 行
r               #运行程序
b 行号          #在main函数所在文件的指定行打断点
b 文件名:行号    #在指定文件的指定行号打断点
b 函数名         #在指定函数的第一行代码处打断点
info b          #查看所有断点信息
d 断点编号       #删除断点# r 开始调试之后n               #逐过程运行
s               #逐语句执行
p 变量           #查看变量的值
display 变量     #变量值常显示,类似于 visual studio 的监视窗口
undisplay 变量   #取消变量的长显示
untill 行号      #在函数内跳转到指定行
finish          #执行完当前行所在的函数
c               #运行到下一个断点处
disable 断点编号 #禁用指定断点
enable 断点编号  #恢复禁用的断点
set var 变量=#类比 visual studio 中的条件断点
bt              #查看调用堆栈
info locals     #查看本地变量(局部变量)

下面我会选择几个比较不好理解的讲讲

l 数字

l 默认显示 10 行,gdb 会记住上一条命令,回车就可以继续执行上一条命令。
在这里插入图片描述

b 文件名:行号

这个命令在多文件的调试中可能会用到:
在这里插入图片描述

d 断点编号


断点编号是什么呢?查看断点编号需要使用 info b 命令:
在这里插入图片描述
其中这个 Num 就是断点编号啦!


在这里插入图片描述
可以看到删除断点之后就查看不到断点的信息啦!


删除刚刚的断点之后我们再打一个断点,发现断点编号并不是 1,说明断点编号是递增的!
在这里插入图片描述

display 变量

可以动态显示一个变量的内容,类似于监视窗口。
我们使用 r 运行程序,开始调试。display num 看到:sum = 0 没问题,然后 n 逐过程运行。发现 sum 变成了 5。这就相当于监视窗口不是嘛!
在这里插入图片描述

finish

执行完当前行所在的函数,这是什么意思呢?我们在第六 6 行打一个断点,看看效果就知道了!
在这里插入图片描述
效果就是直接完成了当前行所在函数的运行

disable 断点编号

这个命令可以禁用断点,visual studio 也是可以的!
在这里插入图片描述
禁用 1 号断点之后,我们查看断点信息,发现 Enb 属性变成了 n。这就表示这个断点被禁用了!

set var 变量=值

我们在 19 行打一个断点,然后运行程序,开始调试,再然后 set var i=3 运行之后,我们发现打印的就是 hello gdb 3 这是不是和 visual studio 中的条件断点一个味儿!
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/228978.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AntDB数据库:从海量数据处理,到5G计费商用核心

AntDB数据库自2008年研发面世以来&#xff0c;首先被应用于运营商的核心系统&#xff0c;满足运营商海量数据处理的需求。随着数字科技的不断发展&#xff0c;AntDB也在不断地更新迭代&#xff0c;逐渐地为更多行业与客户提供更全面的服务。5G时代来临&#xff0c;AntDB抓住发展…

W2311283-可燃气体监测仪怎么监测燃气管道

可燃气体监测仪怎么有效监测燃气管道 燃气管道遍布于城市地下各处&#xff0c;作为城市生命线的一部分&#xff0c;一旦燃气管网出现泄露问题便是牵一发而动全身&#xff0c;城市的整体安全也会受到威胁。但是如何才能科学管理和监测燃气管网呢&#xff1f; 燃气管网监测系统便…

Maven 介绍

文章目录 什么是 maven为什么要选择mavenmaven 仓库什么是maven中央仓库什么是maven本地仓库 idea如何创建出maven项目如何引入第三方库依赖配置国内源 下载 Maven Helper 插件查看各个项目之间的依赖关系 什么是 maven Maven是 Apache 下的一个纯 Java 开发的开源项目&#x…

【精选】Spring整合MyBatis,Junit 及Spring 事务Spring AOP面向切面详解

Spring整合MyBatis 搭建环境 我们知道使用MyBatis时需要写大量创建SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession等对象的代码&#xff0c;而Spring的作用是帮助我们创建和管理对象&#xff0c;所以我们可以使用Spring整合MyBatis&#xff0c;简化MyBatis开发。 …

let const 与var的区别

1、let可以形成块级作用域&#xff0c;在es6之前javascript只有函数作用域&#xff0c;没有块级作用域。在es6之前实现块级作用域: 2、可以看到通过一个立即执行函数表达式&#xff0c;我们实现了一个局部作用域或者块级作用域&#xff0c;但是有了let之后就不需要写这样的代…

关于网站的favicon.ico图标的设置需要注意的几点

01-必须在网页的head标签中放上对icon图标的说明语句&#xff1a; 比如下面这样的语句&#xff1a; <link rel"shortcut icon" href"/favicon.ico">否则&#xff0c;浏览器虽然能读到图标&#xff0c;但是不会把图标显示在标签上。 02-为了和本地开…

jenkins pipeline 运行超时后强制停止

在Jenkins中&#xff0c;Pipeline是一种用于定义持续集成/持续交付&#xff08;CI/CD&#xff09;流程的工具。有时候&#xff0c;Pipeline的执行可能会超时&#xff0c;需要强制停止。 要在Jenkins Pipeline中设置超时&#xff0c;并在超时后强制停止运行&#xff0c;可以使用…

Maven——坐标和依赖

Maven的一大功能是管理项目依赖。为了能自动化地解析任何一个Java构件&#xff0c;Maven就必须将它们唯一标识&#xff0c;这就依赖管理的底层基础——坐标。将详细分析Maven坐标的作用&#xff0c;解释其每一个元素&#xff1b;在此基础上&#xff0c;再介绍如何配置Maven&…

GO 集成Prometheus

一、Prometheus介绍 Prometheus&#xff08;普罗米修斯&#xff09;是一套开源的监控&报警&时间序列数据库的组合&#xff0c;起始是由SoundCloud公司开发的。随着发展&#xff0c;越来越多公司和组织接受采用Prometheus&#xff0c;社会也十分活跃&#xff0c;他们便…

浅谈数据资产价值评估

加gzh"大数据食铁兽“&#xff0c;了解更多大数据信息 数据是资产&#xff0c;是当前时代大背景下毋庸置疑的。随着科技的发展&#xff0c;数据的重要性越来越受到人们的关注。对于企业来说&#xff0c;数据是非常重要的资产&#xff0c;它可以为企业提供决策依据、增加市…

运维笔记111

运维笔记 Navicat中查询指定字段名所在的表名tomcat设置JVM的初始堆内存修改catalina.sh文件修改完保存并关闭tomcat启动tomcat 查询数据库连接数查询是否存在死锁 Navicat中查询指定字段名所在的表名 SELECT * FROM information_schema.COLUMNS WHERE COLUMN_NAME‘替换成你要…

Linux系统---环境变量+内核进程调度队列(选学)

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、环境变量 1.基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数&#xff0c;如: 我们在编写CI/…