Linux下的调试器-gdb(16)

文章目录

  • 预备知识(9-2.30.00)
  • 快速认识 gdb
  • gdb 的命令
    • 1. 更换成 cgdb
    • 2. 打和去除断点
    • 3. 逐语句与逐过程
    • 4. 使能(激活)断点
  • 调试思想
    • 1. 找到问题(找到问题所在的区域)
    • 2. 查看代码的上下文
  • 补充调试技巧
    • 1. watch
    • 2. set var
    • 3. 条件断点
    • 4. 分屏操作

将近一个星期没有更新LinuxSolidWorks的文章,主要是因为上周是期末周,实在分心不过来,这段时间争取将之前欠的内容全部补上。也会补充我期末周复习的一些相关知识,我觉得那些东西还是很有用的

预备知识(9-2.30.00)

  • 程序的发布⽅式有两种, debug 模式和 release 模式
  • debug模式是程序员开发时候所用的模式,而release模式下的程序会经过测试,上线等过程进行发布,手机上的APP和电脑上的软件都是release版本
  • Linux环境下第一次使用gdb可能没有安装:sudo yum install -y gdb
    在这里插入图片描述
  • Linux下通过gcc/g++编译好的代码是无法直接进行调试的, 因为Linux gcc/g++ 出来的⼆进制程序,默认是 release 模式
    在这里插入图片描述
  • 解决方式也很简单。程序要调试,那程序必须是debug模式,也就是编译时要加上-g选项:gcc -g code.c -o code让最后形成的可执行程序,添加调试信息
    在这里插入图片描述
  • 通过命令可查看可执行程序的调试信息:readelf -S code(可执行程序文件名)| grep -i debug
    在这里插入图片描述

快速认识 gdb

1. 测试代码。这里如果用的是C89,这个for循环的int i = 0;放到括号外。当然也可以在编译处加上选项:-std=c99

#include <stdio.h>int Sum(int s, int e)
{int result = 0;// int i = s;// for(; i <=e; i++) C89的写法for(int i = s; i <= e; i++){result += i;}return result;
}int main()
{int start = 1;int end = 100;printf("I will begin\n");int n = Sum(start, end); //[start, end]printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
}

2. 进入调试:gdb 可执行程序名quit:退出调试

  • l 1:从第一行显示,按回车键可以往下翻继续查看源代码
    在这里插入图片描述
  • b 19:在代码的第19行打上断点,再输入r,就让程序运行到第19行停下来,再输入c,再让程序直接运行完成
    在这里插入图片描述

gdb 的命令

1. 更换成 cgdb

先解决第一个gdb难用的问题:gdb它是纯命令行的方式进行调试,其调试信息和代码混在一起,非常的不方便

  • 可以安装cgdb(默认环境没有安装该软件),可以呈现出对应的代码
  • 输入命令:sudo yum install -y cgdb
    在这里插入图片描述
  • 后面不作特殊说明,统一用cgdb作为命令的说明,这里如果用鼠标去滚动界面可能会卡死,我觉得这应该是cgdbbug
    在这里插入图片描述

2. 打和去除断点

  • 打断点b后面可以跟 源文件名:行号,可以跟 源文件名:函数名,它是在函数的入口处打上断点,也可以直接跟上行号
    在这里插入图片描述
  • 查看所有断点的信息info b,只要不退出cgdb,断点编号是随着断点数量依次递增的,该断点是第几个打的,断点编号就是多少
    在这里插入图片描述
  • 删除断点d 断点编号,无法根据断点所在行号来删除断点,只能根据该断点编号去删除断点
    在这里插入图片描述
  • 输入命令:r,如果存在断点则运行到断点处,没有断点则会运行完整个程序
    在这里插入图片描述

3. 逐语句与逐过程

  • 逐语句,输入命令:s,调试会进入到函数和循环中,以一句语句算作一步,一步一步地运行
    在这里插入图片描述

  • 逐过程,输入命令:n,调试并不会进入到函数和循环中,会直接跳过
    在这里插入图片描述

  • 打断点的本质就是让程序在特定位置停下来,对写的代码进行切块,按照断点的方式对程序进行局部性追踪

  • int n = Sum(start, end);这条语句要做两个动作,第一个动作就是调这个Sum函数,另一个动作就是将Sum的返回值通过寄存器赋值给对应的用户
    在这里插入图片描述

  • 每一次函数调用的过程就是在形成栈帧的过程,在C语言调入栈中,每调一次函数就是把函数的栈中结构进行入栈。可以输入命令:bt,来查看入栈函数
    在这里插入图片描述

  • 如果要从函数中直接回到函数调用行(相当于执行完这个函数),输入命令:finish。想查看临时变量n的值,输入命令:p n
    在这里插入图片描述

  • 这里为啥n的值为32767呢?因为这只是Sum函数调用完成(第一步),还没执行到下条语句(还没进行第二步的赋值),那此时的n不就是个随机值
    在这里插入图片描述

4. 使能(激活)断点

  • 断点是可以被使能!意味断点可以打开使用,也可以关闭禁用(不是删除),这样断点的痕迹还在,下次调试的时候就很方便找到调试的历史痕迹
  • 被使能:激活断点,输入命令:enable 断点编号。没有被使能:禁用断点,输入命令:disable 断点编号,后面跟断点编号,不是断点所在的行号
    在这里插入图片描述
    在这里插入图片描述

调试思想

上面只是一些调试的基本命令,不涉及任何调试思想。调试的本质/核心工作: 首先你得知道这个代码有问题,所以调试它去找到问题所在(gdb有很多命令是找到问题所在), 查看代码的上下文,最后由你去解决问题

1. 找到问题(找到问题所在的区域)

  • 断点的本质:就是把代码进行块级别划分,以块为单位进行快速定位区域,找到问题所在的区域
  • 对代码进行切片分析。比如这块代码打上三个断点(20行有一个,25行,30行),打上断点后逐次分析每块代码片段
  • 输入命令r运行到20行,如果没有啥问题,再输入命令c跳到下一个断点处,运行第20~25行的这块代码
    在这里插入图片描述
  • 通过命令finish可以确认问题是否在函数内,就是将这个函数给跑完,没成功那问题就出现在这个函数
    在这里插入图片描述
  • 命令:until 指定行号,可以进行局部区域的快速执行。可以适用于跳出for循环
    在这里插入图片描述

2. 查看代码的上下文

  • 这里假设我的n突然就等于0,我想通过调试找到问题所在,进入函数内部,要查看其变量的值
    在这里插入图片描述
  • 这里可以输入命令:display 要常显示的值,可以用来查看上下文的数据变化。不想常显示哪个值了输入命令:undisplay 对应值的编号,不是变量的名称
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • p也支持查看表达式的值。info locals:可以查看函数或循环内的临时变量
    在这里插入图片描述
    在这里插入图片描述

补充调试技巧

1. watch

执⾏时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB 会暂停程序的执⾏,并通知使⽤者

在这里插入图片描述

删除它就跟删除断点一样,如果你有一些变量不应该修改,但是你怀疑它修改导致了问题,你就可以watch它,如果变化了就会通知你

2. set var

在这里插入图片描述

3. 条件断点

在这里插入图片描述

这样就可以直接跳到条件断点,输入命令:c

在这里插入图片描述

也可以给已经存在的断点新增条件,输入命令:condition 断点编号 条件

在这里插入图片描述

4. 分屏操作

cgdb的分屏操作:可以通过Esc键进入代码屏,i键回到cgdb屏,可以通过上下方向键进行翻阅(只有代码屏才能进行上下翻阅,cgdb屏是翻阅历史命令

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

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

相关文章

李宏毅NLP-7-计算分数和训练和测试

文章目录 分数计算训练测试 分数计算 插入式序列生成模型的概率计算逻辑&#xff0c;核心是将 “生成序列 h 的过程” 拆解为一系列插入操作&#xff0c;并通过步骤概率的乘积计算总概率 P ( h ∣ X ) P(h∣X) P(h∣X)。以下从 模型框架、步骤分解、概率计算 三个层面解析&…

Python字符与ASCII转换方法

在Python中&#xff0c;可以使用内置函数 ord() 和 chr() 来转换字符和ASCII码&#xff1a; ​获取字符的ASCII码​ - 用 ord() ascii_code ord(A) # 返回 65 ​将ASCII码转为字符​ - 用 chr() character chr(65) # 返回 A 示例&#xff1a; # 打印字母A-Z的ASCII码…

[IMX][UBoot] 10.启动流程 (6) - bootz 命令启动 Linux

文章链接 UBoot 启动流程 (1) - 基本流程 UBoot 启动流程 (2) - 平台前期初始化阶段 - board_init_f UBoot 启动流程 (3) - UBoot 程序重定位 - relocate_code UBoot 启动流程 (4) - 平台后期初始化阶段 - board_init_r UBoot 启动流程 (5) - UBoot 运行阶段 - main_loop …

TCP 三次握手协商 MSS 前,如何确定 MSS 值(结合 Linux 内核源码分析)

文章目录 一、SYN总结影响 SYN MSS 的因素 二、SYNACK总结影响 SYNACK MSS 的因素 结合 Linux 内核源码 一、SYN 总结影响 SYN MSS 的因素 套接字选项 TCP_MAXSEG路由选项 advmss出口 MTU 减去 40(TCP 和 IP 的固定首部大小)IPV4_MAX_PMTU - 40(同上) 二、SYNACK 总结影响 SY…

面试150 矩阵置0

思路 我们使用两个标记集合&#xff0c;分别记录当矩阵的元素为0的时候的横、纵坐标。然后在对矩阵元素进行遍历&#xff0c;如果所在行或者所在列的索引在集合中&#xff0c;对应的矩阵元素修改为0即可 class Solution:def setZeroes(self, matrix: List[List[int]]) -> N…

Element UI 完整使用实战示例

以下是 Element UI 的完整使用实战示例&#xff0c;涵盖从环境搭建、基础组件使用到项目实战的全流程&#xff0c;结合多个实际场景和代码示例&#xff1a; 一、环境搭建与基础配置 1. 安装 Element UI 通过 npm 或 yarn 安装&#xff1a; npm install element-ui --save # …

C# 线程同步(一)同步概念介绍

目录 1.阻塞&#xff08;Blocking&#xff09; 2.阻塞 VS 轮询 3.线程状态 到目前为止&#xff0c;我们已经阐述了如何在线程上启动任务、配置线程以及实现双向数据传递。同时&#xff0c;我们也说明了局部变量是线程私有的&#xff0c;而引用可以通过共享字段在线程间传递以…

解决leetcode第3588题.找到最大三角形面积

3588.找到最大三角形面积难度&#xff1a;中等问题描述&#xff1a;给你一个二维数组coords&#xff0c;大小为nx2&#xff0c;表示一个无限笛卡尔平面上n个点的坐标。找出一个最大三角形的两倍面积&#xff0c;其中三角形的三个顶点来自coords中的任意三个点&#xff0c;并且该…

WIFI 安全测试记录

之前为实训课特意买的无线网卡没用上&#xff0c;但是我怎么可能让他荒废。所以用了几个下午&#xff0c;浅学了WiFi&#xff0c;当然没找到什么好教材&#xff0c;自己摸索着学的很基础&#xff0c;主要是当练习了&#xff0c;特此把我此前学习…WiFi密码实践过程写上来。 省流…

android14设置--网络--Internet副标题修改

收银机订制项目 插SIM卡&#xff0c;设备使用数据流量时&#xff0c;设置–网络–Internet副标题显示对应SIM卡运营商名称&#xff0c;客户要求修改这时的名称(注意图标也要同步修改) packages\apps\Settings\src\com\android\settings\network\InternetPreferenceController.j…

Web3区块链有哪些岗位?

Web3区块链领域的岗位丰富多样&#xff0c;涵盖技术开发、产品管理、运营、商务等多个方面&#xff0c;以下是具体介绍&#xff1a; - 技术开发类&#xff1a; - 智能合约开发工程师&#xff1a;负责编写、审计和优化智能合约&#xff0c;常见于DeFi开发&#xff0c;包括抵押…

解决 Spring Boot 对 Elasticsearch 字段没有小驼峰映射的问题

场景重现在使用 MyBatis/Mybatis-Plus 框架对 MySQL 操作时习惯了字段名小驼峰映射&#xff0c;然而在操作 Elasticsearch 时发现字段名没有小驼峰映射。解决方法1. 使用 ObjectMapper 手动转换&#xff1a; 这是最直接也最常用的方法。 在 Spring Boot 应用中使用 ObjectMappe…

Error:Cannot find module ‘chokidar‘

错误复现 在vue开发中&#xff0c;出现报错&#xff1a;Error&#xff1a;Cannot find module ‘chokidar’ 原因 缺包导致 解决方案 直接安装依赖包 npm install chokidar依旧无效&#xff0c;删除node_modules重新安装 rm -rf node_modules npm i

Spring AI 向量数据库详解与 RAG 简单实战项目

一、什么是向量数据库&#xff1f; 向量数据库用于存储、检索稠密语义向量&#xff08;Embedding&#xff09;&#xff0c;是构建 RAG&#xff08;检索增强生成&#xff09;系统的核心组件。它支持近似最近邻搜索&#xff08;ANN&#xff09;&#xff0c;可根据语义相似度找出…

【RK3568+PG2L50H开发板实验例程】Linux部分/FPGA FSPI 通信案例

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 1. 简介 本案例旨在 ARM端运行 Linux系统&#xff0c;基通过 FSPI测试。 2. ARM端和 FPGA端通信流程 (1)ARM端实现SP…

github如何创建一个自己的仓库保姆级教程

文章目录 准备阶段(github官网)添加ssh公钥添加token创建仓库 本地设置本地代理创建仓库添加文件到仓库进行提交 准备阶段(github官网) 添加ssh公钥 创建SSH KEY。先看一下你C盘用户目录下有没有.ssh目录&#xff0c;有的话看下里面有没有id_rsa和id_rsa.pub这两个文件&#…

LabVIEW 网络流通信功能

LabVIEW 的网络流技术实现主机 VI&#xff08;Host VI&#xff09;与客户端 VI&#xff08;ClientVI&#xff09;间的双向数据交互&#xff0c;包含命令发送与波形数据传输&#xff0c;支持跨设备、跨进程的实时通信&#xff0c;满足分布式系统中数据交互与控制需求。 主机 VI逻…

Prompt 精通之路(一)- AI 时代的新语言:到底什么是 Prompt?为什么它如此重要?

AI 时代的新语言&#xff1a;到底什么是 Prompt&#xff1f;为什么它如此重要&#xff1f; 标签&#xff1a; #Prompt新手指南 #提示词入门 #AI指令 #人工智能 #ChatGPT &#x1f680; Prompt 精通之路&#xff1a;系列文章导航 第一篇&#xff1a;AI 时代的新语言&#xff1a…

uniapp 滚动tab

uniapp woui unibest <route lang"json5">{style: {navigationBarTitleText: 知识产权,navigationBarBackgroundColor: #C80F06,navigationBarTextStyle: white,backgroundColorTop: #C80F06,},} </route> <template><view class"bgc-b …

日事清驾驶舱模式上线:实时数据更新+项目管理+数据可视化,提升决策效率​

大家好&#xff01;我们在日事清最新更新中推出了一个令人激动的新功能——驾驶舱模式。这一全新界面将为企业管理者和团队提供一个全面、实时的数据展示平台。下面&#xff0c;让我们详细了解这个功能如何帮助您更好地把握企业动态和提升决策效率。 快速入口&#xff1a;一键激…