[GDB] GDB调试

目录

一 简介

二 功能:

三 命令:

四 调试准备:

五 开始调试:

5.1 添加断点:

5.2 条件编译

5.3 断点查看

5.4 断点删除:

5.5 查看源码

5.6 单步调试(逐过程):

5.7 断点调试:

5.8 单步跟踪(逐语句):

5.9 调试过程:

5.9.1 开始调试

5.9.2 查看变量 

5.9.3 显示变量:

5.9.4 监控变量:

5.9.5 设置变量:

六 段错误追踪

6.1 设置核心文件大小:

6.2 设置核心文件路径:

6.3 追踪核心文件:


一 简介

  • UNIX及UNIX-like下的调试工具。虽然它是命令行模式的调试工具,但是它的功能强大到你无法想象,能够让用户在程序运行时观察程序的内部结构和内存的使用情况。

二 功能:

GDB的功能很是强大,主要列出了几点常用且重要的。要值得注意的是只有debug程序可以进行GBD调试,如果是releas程序是不可以进行调试的。

  • 条件调试:  可以自定义断点的调试方式,以及触发条件等。
  • 变量监视:  可以动态的监视某个值的变化
  • 动态改变程序执行环境:可以在断点处修改程序目前变量的值,从而在不重新运行程序的情况下,用预期的值来进行调试。
  • 分析上下文: 可以分析出程序目前的上下文堆栈调用情况
  • 段错误分析: 这个是个很重要的点,可以帮助我们找到程序崩溃的源码。

三 命令:

命令作用使用方式
gdb进入调试环境gdb 可执行文件名 
r(run)重新开始运行可执行文件r或者run
b(break)设置断点,可以针对不同文件,函数名设置b或者break
info b查看断点信息info b 或者info break
d删除断点d 断点编号
d break删除所有断点d break不能使用d b
disable/enable 使断点无效/有效

指定断点无效:disable 断点编号 

使所有断点无效: disable b

n(next)逐过程,相当于F10,不会进入函数体.单步执行n或者n 【数字】 可以一步也可以指定多步
s(step)逐语句【相当于F11,所有语句都会进入s或者s 【数字】 可以一步也可以指定多步
c(continue)从一个断点处,直接运行至下一个断点处【F5】c
p打印变量名

p 【变量名】

四 调试准备:

  • 首先我们准备一段测试demo。
#include <stdio.h>// 一个简单的函数,用于演示函数调用
void print_message(const char* message) {int i = 0;for(i = 0; i < 10; ++i){printf("%d+%s\n", i, message);}
}int main() {// 未初始化的指针char* ptr = (char*)malloc(50);// 尝试打印通过未初始化指针指向的数据,这将导致段错误printf("The secret message is: %s\n", ptr);// 正常情况下会调用此函数,但由于前面的段错误,可能无法执行到print_message("This message should never appear");return 0;
}
  • 首先我们不带编译信息来编译这段程序,也就是release模式
  • 然后我们使用gdb main命令来进行调试这个可执行程序
  • 这时候我么会发现,No debugging symbols found in main),表示这个可执行程序并不能够进行调试。

gcc main.c -o main

  • 所以在编译时我们应该加上-g选项,如果是其他编译工具,对应的生成debug下的可执行文件即可。
  • 这时候Reading symbols from main... 就表示可以进行调试了。

  • 还有两种方式也能够查看:使用readelf和objdump命令

五 开始调试:

  • 使用gdb main(对应自己可执行程序文件)
  • 设置断点: 如果未设置调试信息(断点)直接输入r(运行程序),那么就会和正常运行程序一样,直到程序结束。

5.1 添加断点:

有两种方式一种是指定行号,一种是指定函数名。

  • break 文件名:行号      如果不写文件名那么会在主函数的对应行号设置断点
  • break 文件名:函数名  如果不写文件名GBD会找到项目整个目录中所有包含这个函数名的地方并打上断点

这里我们分别使用两种方式打上两个断点,对于vi编辑器如果不知道行号我们可以在命令模式下输入

set number命令这样就可以看到行号了。

5.2 条件编译

  • 对于断点调试是可以进行设置条件断点的。
  • break 文件名: 行号 条件
  • 下面这个条件编译也就是当这个指针等于0时才会触发这个断点。

5.3 断点查看

  • info b: 可以看到断点编号 位置等信息
Num断点唯一标识号
Type断点的类型,比如全程序断点、条件断点、指令断点等。
Disp表示断点的处理方式。例如,keep表示即使断点被命中,它也不会被自动删除;del则会在首次命中后删除断点。
Enb表明断点是否启用。y表示启用,n表示禁用。
Address断点所在代码的地址。
What断点关联的具体位置,可以是源代码文件名和行号,或者是函数名,甚至是内存地址。
Cond如果设置了条件断点,这里会显示该条件表达式
Times断点被触发的次数

5.4 断点删除:

  • d 断点编号: d 后面跟上断点编号
  • d break : 删除所有断点,这里会提示是否全部删除

5.5 查看源码

  • l:  list 默认查看从第一行到20行前20行代码,后续可以直接按下回车查看后面代码,GDB会默认记住上一次的命令
  • l 10,20: 查看第10行到第20行的代码,也就是指定行号
  • l main.c:print_message: 查看main.c文件中的print_message函数的代码
  • l main.c:20: 查看main.c 中第20行的代码(默认从此处后20行)
  • l main.c:10,20: 同理查看main.c文件中第10到20行代码

5.6 单步调试(逐过程):

  • n: next 从这个断点执行一行源程序代码,遇到函数也会直接调用并执行,不会进入函数.
  • n 数字: 单步执行多少行,比如你确认下面的几行是没有问题的,你就可以直接跳过。

这里要注意的是在设置函数的断点时,如果是使用的是 break 函数名设置的断点,使用n是仍然会进入函数的,如果是使用break + 数字(这个函数所在的行号) 这样是可以跳过的。如果这样设置了我们可以利用s 函数名 或者 n 数字 这种方式也可以直接跳出函数。

5.7 断点调试:

  • c:continue 会直接跳转到下一个断点处进行调试。

5.8 单步跟踪(逐语句):

  • s:skip 执行一行源代码程序,但是如果遇到函数调用,会进入该函数
  • s 函数名: 跳出该函数

5.9 调试过程:

5.9.1 开始调试

  • 输入r开始运行程序,此时会在程序遇到的第一个断点处停下

5.9.2 查看变量 

  • print 变量名: 此时我们可以使用print来查看变量值
  • print 函数名:变量名: 如果多个函数有同一个变量名我们需要前面加上函数名来区分
  • print *ptr: 如果这个值是指针那么我们看到的将是地址,想要查看它的值我们需要解引用: 
  • 这里我们看到ptr的值是等于0的,这样恰好验证了我们当时的条件编译,如果我们不做初始化ptr那么此时ptr不等于0那么断点也就不会触发。

5.9.3 显示变量:

  • display 变量: 跟踪查看一个变量,每次停下来都会显示它的值。

5.9.4 监控变量:

  • watch 变量名: 这样在这个变量名改变时程序就会停下来,其实这也是一个断点,我们可以此时查看断点信息,就会发现它也生成了一个断点。

5.9.5 设置变量:

  • set 变量 = 值:  这是很有用的,因为它可以让我们改变当前程序变量的值,按照我们想预期的值来执行后面的程序,而不需要重新运行程序。
  • 这里我们在for循环中运行第一次的时候,此时的i = 0,我们可以直接设置i = 6 那么下一次就会直接从6开始执行for循环了。
  • 当然要值得注意的是,如果报错,我们可以使用set variable 变量 = 值,因为直接使用命令这有可能会导致命令不清晰,GDB不知道是变量还是GBD内部的一些设置。

六 段错误追踪

我们有时候会遇到程序异常崩溃,然后会提示 Core Dump(段错误),这一般是程序调用了非法的内存地址,比如空指针,野指针等造成的,GDB也可以帮助我们找到这个地方。

6.1 设置核心文件大小:

  • ulimit -c: 如果后面不跟具体大小,则是显示当前核心文件的大小,如果加上数字表示当前核心文件当前系统最大可以生成核心文件的大小(单位:字节(B))
  • ulimit -c unlimited: 取消核心文件大小的限制

6.2 设置核心文件路径:

  • 我们最好是将核心文件生成的路径指定,这样方便查找。
  • %e表示程序名, %p表示进程id:这样生成的核心文件就会带上当前可执行文件的程序名和进程id了。

echo /home/data/coredump/core.%e.%p> /proc/sys/kernel/core_pattern

6.3 追踪核心文件:

  • 这里我们首先把测试程序中指针初始化时给一个非法的地址,这样程序再读取这个地址的值时,就会异常崩溃,触发段错误。

  • 然后我们直接运行这个可执行文件,就会发送段错误

  • 此时我们查看之前设置的核心文件的生成路径/home/data/coredump就能看到生成的核心文件。

  • 接下来我们进入gdb环境: 切记要使用gdb 可执行文件名  不要直接使用GDB进入GDB环境。
  • 再进入之后我们使用core-file 核心文件名
  • 最后我们使用bt命令查看堆栈信息,就能准确看到崩溃的位置和信息了。
  • 我们可以看到确实是再main.c中的第18行导致的崩溃。

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

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

相关文章

在CentOS 8上卸载与安装MySQL 8的详细步骤

关键词&#xff1a;MySQL 8安装、CentOS 8、YUM源配置、卸载MySQL、MySQL残留文件删除、首次登录MySQL临时密码、服务状态检查、MySQL社区服务器 阅读建议&#xff1a;本文适合需要在CentOS 8操作系统上部署最新MySQL 8数据库的系统管理员或开发者阅读。文中步骤简洁清晰&#…

ssm145基于java的电脑硬件库存管理系统+jsp

电脑硬件库存管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对电脑硬件库存信息管理混乱&…

【设计模式】创建型-抽象工厂模式

前言 在软件开发领域&#xff0c;设计模式是一种被广泛接受的解决方案&#xff0c;用于解决特定问题并提供可维护和可扩展的代码结构。抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是其中之一&#xff0c;它提供了一种方法来创建一系列相关或相互依赖的对象…

Linux 使用 yum安装 ELK服务,yum 安装elasticsearch和Kibana(未写完)

文章目录 环境准备ELK组件介绍安装Elasticsearch安装Kibana 丢弃下载ELK 服务安装包Elasticsearch安装 Tips:关闭elasticsearch https 环境准备 ELK组件介绍 ElasticSearch &#xff1a; 是一个近实时&#xff08;NRT&#xff09;的分布式搜索和分析引擎&#xff0c;它可以用…

PyQt6实战 | 绘图画板程序 自由绘制 直线 矩形 椭圆 画笔颜色和大小选择

引言 本文将介绍如何使用 PyQt6 创建一个简单的绘图应用程序。这个应用程序实现了常用的绘图功能&#xff0c;如自由绘制、画直线、矩形和椭圆。此外&#xff0c;还提供了选择画笔颜色、调整画笔宽度、清空画布和导出图像的功能。 环境设置 首先&#xff0c;需要安装 PyQt6&a…

OrangePi AIpro评测 - AI服务篇

0. 环境 ●OrangePi AIpro ●windows电脑 ●路由器 之前我已经对OrangePi AIpro进行了些嵌入式基本操作的评测。接下来进行AI部分。来看看华为昇腾的特别之处。 1.普通CPU和AI CPU 这里请提前用调试串口或者ssh到板子上&#xff0c;记得用户名和密码&#xff0c;分别是HwHiAiUs…

【Mybatis】映射文件获取新增记录的id

我们在讲JDBC的时候讲过在插入新数据值的时候需要获得到自动生成的那个主键id的值 ①获取PreparedStatement的对象的时候 PreparedStatement st conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS ); ②在执行SQL语句后 st.executeUpdate();ResultSet rs st.ge…

马斯克:AI时代人人高收入,不需要工作,商品服务不再短缺,可能性80%

当前人工智能现状和未来如何&#xff1f;AI时代下&#xff0c;人类未来会发生哪些变化&#xff1f; 埃隆马斯克&#xff08;Elon Musk&#xff09;在2024 VivaTech大会上分享了关于地球未来的诸多愿景。 投资作业本课代表摘录了其中的要点&#xff0c;分享给大家&#xff1a…

Golang的基本使用

目录 变量的声明 Golang常用容器 defer 有趣的多态 结构体标签和reflect 反射 Golang最强的协程 channel go可能造成的内存泄露 变量的声明 方法 1:有类型,有var,不赋值 在Golang中默认值为0 方法 2:无类型,有var,赋值 方法 3:无类型,无var,赋值 多变量声明 多变…

强大友好的Nginx扩展:VeryNginx

VeryNginx&#xff1a; 简化Web管理&#xff0c;增强网站防御- 精选真开源&#xff0c;释放新价值。 概览 VeryNginx是一个基于lua-nginx-module&#xff08;openresty&#xff09;的高效、友好的Nginx版本&#xff0c;专为满足现代Web应用的需求而设计。它不仅提供了强大的We…

spring-boot 3.2 + spring-boot-starter-quartz + HikariCP配置

第一步&#xff0c;添加 spring-boot-starter-quartz 的 maven 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> 第二步&#xff0c;在 ap…

Adobe Animate AN v24.0.2 安装教程 (动画特效设计及合成工具)

Adobe系列软件安装目录 一、Adobe Photoshop PS 25.6.0 安装教程 (最流行的图像设计软件) 二、Adobe Media Encoder ME v24.3.0 安装教程 (视频和音频编码渲染工具) 三、Adobe Premiere Pro v24.3.0 安装教程 (领先的视频编辑软件) 四、Adobe After Effects AE v24.3.0 安装…

SSE(Server Sent Event) 踩坑留念

整条链路是 客户端A --> 服务端 A —> 服务端 B 我负责服务端 A 此时要注意 Client 中的 processes 的写法 Post(value “/v2/xx”, processes MediaType.TEXT_EVENT_STREAM) 这样写是一直报错的 改成下面的写法才可以 Post(value “/v2/xx”, processes MediaT…

【荐闻】空中目标检测综述

https://t.zsxq.com/tgUjbhttps://t.zsxq.com/tgUjb 这篇综述论文全面回顾了空中目标检测的最新进展&#xff0c;包括五个不平衡问题、相关方法、实际应用和性能评估。以下是对论文内容的详细描述&#xff1a; 1&#xff09;引言&#xff1a;介绍了空中目标检测的概念&#x…

Ubuntu22.04之扩展并挂载4T硬盘(二百三十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

工控屏(触摸屏)怎么连接电脑

一、使用USB接口连接 连接方法&#xff1a;使用USB线连接触摸屏和电脑&#xff0c;触摸屏会自动识别并连接到电脑上。 二、使用HDMI接口连接 连接方法&#xff1a;1.首先要确认您的触摸屏是否有HDMI接口&#xff1b;2.将一端连接到触摸屏&#xff0c;另一端连接到电脑&#…

选择排序与堆排序

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 关注博主带你了解更多数据结构知识 1.选择排序 第一种方法:直接定义一个 i下标 和 j下标(ji1) ,再定义minIdex下标 让 minIdex i, 开始遍历数组,过程中 如果j下标的值大于minIdex下标的值就交换,然…

JVM 常见配置参数

JVM 配置常见参数 Java虚拟机的参数&#xff0c;在启动jar包的时候通过java 命令指定JVM参数 -options表示Java虚拟机的启动参数&#xff0c;class为带有main()函数的Java类&#xff0c;args表示传递给主函数main()的参数。 一、系统查看参数: -XX:PrintVMOptions可以在程序…

超越连接:ZL-450边缘网关全面评测与应用案例

前言 在现代工业自动化和智能设备管理的背景下&#xff0c;对实时数据通信与设备监控的需求日益增加。ZL450边缘网关作为一款先进的串口通信解决方案&#xff0c;不仅满足了这些要求&#xff0c;还通过其多样的连接性和高效的数据处理能力&#xff0c;为企业带来了显著的效率提…

R可视化:另类的箱线图

介绍 方格状态的箱线图 加载R包 knitr::opts_chunk$set(echo TRUE, message FALSE, warning FALSE) library(patternplot) library(png) library(ggplot2) library(gridExtra)rm(list ls()) options(stringsAsFactors F)导入数据 data <- read.csv(system.file(&qu…