深入了解Linux —— 调试程序

前言

我们已经学习了linux下许多的工具,vimgccmake/makefile等;

已经能够在linux写代码,并且进行编译运行,让程序在linux下跑起来。

但是,如果我们在写代码的时候遇见了错误;但是我们并不知道错误在哪,在windows下,我们可以进行调试来查找代码错误的位置进行修改;我们在linux就只能查看源代码,直接查找错误,这样很麻烦;

现在就来学习linux如何调试程序。

调试程序 ——gdb/cgdb

Debug/Release模式

在之前学习C语言时,听说过DebugRelease,只知道Debug时用来调试的,程序员写代码的版本;而Release是发布版本。

现在我们来看一下这两个模式有什么区别

  • 首先的区别就是Debug会生成程序的调试信息,而Release不会生成程序的调试信息。

因为Debug模式会生成调试信息,所以Debug模式的程序就要比Release模式的程序大小要大。

我们如何验证呢?

linuxgcc编译默认生成的是Release版本,我们要生成Debug模式就要带-g选项。

现在有这样一段代码test.c文件

#include<stdio.h>
int func(int n)
{int ret = 0;for (int i = 1; i <= n; i++){ret += i;}return n;
}
int main()
{int n = 100;int sum = func(n);printf("sum = %d\n", sum);return 0;
}

我们在linux下进行编译

在这里插入图片描述

这里有这样的提示,那是因为C98不支持在for循环中定义变量,要使用C99,上面也有提示。

所以我们就要这样来编译

gcc test.c -o test -st=c99

这里写成makefile方便操作。

这样生成的是Release模式的程序,我们查看它文件属性

在这里插入图片描述

现在,我们使用-g选项生成Debug模式的程序

在这里插入图片描述

可以看到Debug模式的要比Release模式的程序要大一些。

gdb/cgdb的使用

这里,只有Debug模式的程序才能被调试;Release模式下不能被调试,因为缺少调试信息。

在使用之前可能需要进行安装

yum -install -y gdb
yum -install -y cgdb

1. 进入调试

gdb 可执行程序

这里无论是gdb还是cgdb,都是可执行程序,对可执行程序进行调试。

在这里插入图片描述

可以看到这样就进入gdb调试了,但是gdb调试现在看不到我们的源代码。

2. 退出调试

quit

在这里插入图片描述

现在来看一下cgdb调试的界面

cgdb test

在这里插入图片描述

这样的界面看起来要比gdb好用一些,所以这里就以cgdb为例,来学习调试

cgdb中,屏幕上半部分可以看到一部分代码;其中绿色箭头指向的地方就是当前程序运行的位置。

退出调试仍然是quit

3. 查看代码

查看代码,l;后可以什么的不跟,也可以跟行号或者函数名

  • l :查看源代码,从上次位置开始,依次显示10行代码
  • l 文件名:行号 :列出指定文件的源代码
  • l 函数名 :列出指定函数的源代码

在这里插入图片描述

l 文件名:行号
在这里插入图片描述

l:函数名

在这里插入图片描述

这里列出的可能有一些差别。

4. 运行代码

我们进入调试,但是代码并没有运行起来;在windows下我们之间F5就让代码运行起来了;而cgdbr命令可以让代码运行起来

r/run,执行代码:

在这里插入图片描述

逐步执行

有了断点,我们在r时程序就会停止在断点处,那我们该如何一行一行执行代码呢?

windows下,我们是按F10F11来依次执行代码;

linuxcgdb,我们使用n/nexts/step来依次执行代码

n/next,相当于F10,一行一行执行代码, 在遇到函数时,不进入函数内部;

s/step,就相当于F11,一行一行执行代码, 在遇到函数时,进入函数内部;

这里就不演示了。

执行到某处

在我们调试程序时,程序现在停止在一个断点处,我们不想一行一行执行代码,而是想要让程序直接运行到下一个代码;

只需要指向c/contine即可

c/continue

在这里插入图片描述

r 重新执行

如果现在程序正在执行,我们想要让程序重新执行,只需要r即可;

这是会询问我们是否重新执行,y即可

在这里插入图片描述

finish

执行到当前函数结束,然后停止

在这里插入图片描述

until 执行到某一行

until 行号 程序执行到某一行然后停止。

在这里插入图片描述

现在执行until 11,让程序执行到11行。

在这里插入图片描述

5. 断点

增加/删除断点

我们指向run/r后,发现代码直接就执行结束了;但是在我们调试的时候,我们并不希望代码执行运行结束,我们需要通过断点让代码在指定位置停下来;

windows下,我们通过快捷键F9或者鼠标点击来打断点和去掉断点;

cgdb中,我们通过命令**b/break**来打断点,通过delete/d来取消断点。

b打断点

  • b 行号:在指定行打断点
  • b 函数名:在函数开头打断点

在这里插入图片描述

可以看到,我们打断点之后并看不到任何断点信息,那如果我们想要看到已经存在的断点,可以使用命令info b来查看

info b查看所有断点信息

在这里插入图片描述

d删除断点

我们打断点可以通过行号,但是删除断点我们就不能使用行号了,而是使用Num 断点编号。

在这里插入图片描述

这里还要注意一个点,断点编号时不断递增的,不会随着我们删除断点而减小

什么意思呢,就是现在存在两个断点我们删除了其中一个断点,然后再次创建了一个断点,它的编号就是3而不是2

在这里插入图片描述

这样有了断点,我们在执行r时就程序就会停止在断点处。

在这里插入图片描述

这里看一下上半代码部分,可以看到程序停在了15行,并且断点位置的行号颜色为红色。

启用/禁用断点

当我们在调试程序时,我们增加的断点并不一定所有的都能用的到,有一些断点我们不想让它在这次调试中起作用,这时就可以禁用这个断点

看到这里可能有疑惑,为什么不直接删除呢?

如果代码非常的多,删除了之后,接下来调试要用到,又要重新去找,非常浪费时间。

启用断点

enable 断点编号

禁用断点

disable 断点编号

这里断点默认是启用状态的。

在这里插入图片描述

那现在执行一下看是否真的禁用了呢?

在这里插入图片描述

可以看到第一个断点并未触发,而是直接触发第二个断点。

6. 监视

windows下我们通过监视窗口来查看一个变量的值;

而在linuxcgdb中,我们也可以通过指令来查看变量的值。

监视变量

p

p 用来查看一个变量当前的值

在这里插入图片描述

但是这样,我们在此执行代码会发现,执行过后就不在显示了;

这样我们每次查看就要去输入指令p 变量名,这样好麻烦,我们想要每一次执行过后,它都会显示出来变量的值

display用来跟踪显示变量的值。

display
在这里插入图片描述

如上图所示,我们每一次执行代码,变量的值都会显示出来。

监视函数栈帧内局部变量

如果我们不是想要查看某一个变量,而是查看当前函数内所有的局部变量?

我们就要用到info/i locals

在这里插入图片描述

可以看到func中所有的局部变量都显示出来了。

查看当前函数调用栈帧

如果我们想要查看当前的函数调用栈帧,直接使用bt/backtrace即可。

在这里插入图片描述

cgdb常用小技巧

1. watch

watch:用来监视一个变量的值是否发生变化,发生变化时会提示。
在这里插入图片描述

我们使用info b查看断点中也可以看到watch监视的变量。

2. set war

set war:在调试过程中,修改变量的值。

在这里插入图片描述

可以看到,我们在调试过程中,使用set var就可以修改一个变量的值。

3. 条件断点

添加条件断点

b 行号 if 条件

在这里插入图片描述

如上图所示,新添加的条件断点(当i==10时触发)。

在这里插入图片描述

可以看到程序在i==0时,断点触发,停止在第九行。

给已存在断点增加条件

当我们需要给已经存在的断点增加条件时,我们需要指令

condition 断点编号 条件

在这里插入图片描述

到这里本篇内容就结束了,希望对你有所帮助。

制作不易,感谢大佬的支持。

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws

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

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

相关文章

Python接口自动化之断言封装!

该框架支持两种断言方式&#xff0c;相等和包含。 先看一下断言的yaml文件编写规范&#xff1a; validate: - equals: {status_code: 200} - contains: $ddt{assert_str} 其中assert_str和之前用例一样&#xff0c;作为变量&#xff0c;放在对应的data yaml文件中 # D…

基于Rye的Django项目通过Pyinstaller用Github工作流简单打包

前言 Rye的介绍和安装 Ryehttps://rye.astral.sh/Rye 完整使用教程_安装rye-CSDN博客https://blog.csdn.net/zhenndbc/article/details/144544692 正文 项目建立 配置好环境后 新建文件夹 新建文件夹&#xff0c;进入项目 初始化 rye init下载依赖 rye syncpycharm 打…

Pycharm 取消拼写错误检查(Typo:in word xxx)

现象 Pycharm显示单词存在错误&#xff0c;下面看着有下划波浪线&#xff0c;看着很不舒服。 快捷键AltEnter&#xff0c;查看提示错误。 Typo是啥? "Typo" 这个词通常用于描述打字或排印过程中的小错误&#xff0c;尤其是拼写错误。它指的是在文本中由于打字或印刷…

K8S学习之基础十七:k8s的蓝绿部署

蓝绿部署概述 ​ 蓝绿部署中&#xff0c;一共有两套系统&#xff0c;一套是正在提供服务的系统&#xff0c;一套是准备发布的系统。两套系统都是功能完善、正在运行的系统&#xff0c;只是版本和对外服务情况不同。 ​ 开发新版本&#xff0c;要用新版本替换线上的旧版本&…

三、0-1搭建springboot+vue3前后端分离-idea新建springboot项目

一、ideal新建项目1 ideal新建项目2 至此父项目就创建好了&#xff0c;下面创建多模块&#xff1a; 填好之后点击create 不删了&#xff0c;直接改包名&#xff0c;看自己喜欢 修改包名和启动类名&#xff1a; 打开ServiceApplication启动类&#xff0c;修改如下&#xff1a; …

任天堂Switch拉美游戏价涨,传Switch 2全球或提价

易采游戏网3月9日独家消息&#xff1a;近日据相关资讯显示&#xff0c;在拉丁美洲地区&#xff0c;任天堂Switch的游戏价格出现了上扬态势。这一变化引发了玩家与市场的关注&#xff0c;不过就目前而言&#xff0c;其并未波及全球游戏市场的整体定价格局。但值得注意的是&#…

10.2 继承与多态

文章目录 继承多态 继承 继承的作用是代码复用。派生类自动获得基类的除私有成员外的一切。基类描述一般特性&#xff0c;派生类提供更丰富的属性和行为。在构造派生类时&#xff0c;其基类构造函数先被调用&#xff0c;然后是派生类构造函数。在析构时顺序刚好相反。 // 基类…

如何在需求分析阶段考虑未来扩展性

在需求分析阶段考虑未来扩展性的关键在于 前瞻规划、灵活架构、标准设计。其中&#xff0c;前瞻规划尤为重要&#xff0c;因为通过全面分析业务发展趋势与技术演进&#xff0c;能够在初期设计阶段预留足够扩展空间&#xff0c;降低后期改造成本&#xff0c;为企业长期发展奠定坚…

PawSQL for MSSQL:PawSQL 支持 SQL Server 的SQL优化、SQL审核、性能巡检

0. 概述 在PawSQL的最新版本中&#xff0c;PawSQL 为 SQL Server 数据库提供了全方位的SQL优化、SQL审核、性能巡检支持&#xff0c;覆盖SQL开发、测试、运维的整个生命周期&#xff0c;助力用户充分发挥 SQL Server 数据库的性能潜力。 1. 纳管SQL Server 实例 工作空间是SQ…

【Java代码审计 | 第六篇】XSS防范

文章目录 XSS防范使用HTML转义使用Content Security Policy (CSP)输入验证使用安全的库和框架避免直接使用用户输入构建JavaScript代码 XSS防范 使用HTML转义 在输出用户输入时&#xff0c;对特殊字符进行转义&#xff0c;防止它们被解释为HTML或JavaScript代码。 例如&…

NO.26十六届蓝桥杯备战|字符数组七道练习|islower|isupper|tolower|toupper|strstr(C++)

P5733 【深基6.例1】自动修正 - 洛谷 小写字母 - 32 大写字母 大写字母 32 小写字母 #include <bits/stdc.h> using namespace std;const int N 110; char a[N] { 0 };int main() {ios::sync_with_stdio(false);cin.tie(nullptr);cin >> a;int i 0;while (a…

langChainv0.3学习笔记(初级篇)

LangChain自0.1版本发布以来&#xff0c;已经历了显著的进化&#xff0c;特别是向AI时代的适应性提升。在0.1版本中&#xff0c;LangChain主要聚焦于提供基本的链式操作和工具集成&#xff0c;帮助开发者构建简单的语言模型应用。该版本适用于处理简单任务&#xff0c;但在应对…

qt 播放pcm音频

一、获取PCM音频 ffmpeg -i input.mp3 -acodec pcm_s16le -ar 44100 -ac 2 -f s16le output.pcm -acodec pcm_s16le&#xff1a;指定16位小端PCM编码格式&#xff08;兼容性最佳&#xff09;-ar 44100&#xff1a;设置采样率为CD标准44.1kHz&#xff08;可替换为16000/8000等&a…

Windsuf 连接失败问题:[unavailable] unavailable: dial tcp...

问题描述 3月6日&#xff0c;在使用Windsuf 时&#xff0c;遇到以下网络连接错误&#xff1a; [unavailable] unavailable: dial tcp 35.223.238.178:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of…

Leetcode 刷题记录 05 —— 普通数组

本系列为笔者的 Leetcode 刷题记录&#xff0c;顺序为 Hot 100 题官方顺序&#xff0c;根据标签命名&#xff0c;记录笔者总结的做题思路&#xff0c;附部分代码解释和疑问解答。 目录 01 最大子数组和 方法一&#xff1a;动态规划&#xff08;卡达尼算法&#xff09; 方法…

QTS单元测试框架

1.QTS单元测试框架介绍 目前QTS项目采用C/C语言,而CppUnit就是xUnit家族中的一员,它是一个专门面向C的单元测试框架。因此,QTS采用CppUnit测试框架是比较理想的选择。 CppUnit按照层次来管理测试,最底层的就是TestCase,当有了几个TestCase以后&#xff0c;可以将它们组织成Te…

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12📚页面效…

探索Java多线程的核心概念与实践技巧,带你从入门到精通!

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 今天我们来学习多线程编程-"掌握线程创建、管理与安全"&#xff1a; 上一节课程我们铺垫了一系列的东西&#xff0c;引出来了我们的多…

前端数据模拟 Mock.js 学习笔记(附带详细)

前端数据模拟 Mock.js 学习笔记 在前端开发过程中&#xff0c;数据模拟是一项至关重要的环节。当后端接口尚未完成或者需要独立进行前端开发与测试时&#xff0c;Mock.js 能发挥巨大作用&#xff0c;它可以模拟各种数据场景&#xff0c;助力前端开发高效进行。 一、Mock.js 的…

NoteGen是一款开源跨平台的 AI 笔记应用,专注于 recording 和 writing ,基于 Tauri 开发

一、软件介绍 文末提供程序和源码下载 NoteGen 是一款专注于记录和写作的跨平台 AI 笔记应用&#xff0c;基于 Tauri 开发。NoteGen 的核心理念是将记录、写作和 AI 结合使用&#xff0c;三者相辅相成。记录功能可以帮助用户快速捕捉和整理碎片化知识。整理功能是连接记录和写…