调试工具之GDB的基本使用

news2024/10/2 16:14:33

GDB基本使用

GDB是Linux下一款非常强大的调试软件,其实就是GNU Debugger的缩写。接下来我们学习一下他的基本使用。
例子函数,其中只有一个ds18b20的采集温度函数和一个主函数:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int measure_temp(float *temp);

int main(int argc,char *argv[])
{
	float 				   temp = 0;

	measure_temp(&temp);

	printf("the temp:%f\n",temp);

	return 0;
}

int measure_temp(float *temp)
{
	int					   fd = -1;//打开ds18b20时候的文件描述符
	int					   found = -1;//是否找到chip的参数。
	char            	   *w1_path = "/sys/bus/w1/devices/"; //文件名的前半段,28-后面不能确定,因为设备号会变化,我们一会获取。
	char				   chip[32];//文件名的后半段,-28
	char				   ds_path[128];//拼凑出全部的路径名
    DIR					   *dirp = NULL;//打开w1时返回的DIR类型文件指针
    struct dirent          *direntp = NULL;//是readdir后返回的文件夹信息结构体指针
    char				   buf[1024];
    char 				   *ptr;//用来指向温度值

	if (NULL == temp)
	{
		printf("mesure_temp arguments error:[%s]\n",strerror(errno));
		return -1;
	}
	printf("measure_temp arguments right!\n");
    
	//打开devices文件夹
	if ( NULL == (dirp = opendir(w1_path)) )
	{
		printf("open w1_path error:[%s]\n",strerror(errno));
		return -2;
	}
	printf("open w1_path DIR[%p] success!\n",dirp);

	//readdir查找这个文件夹下有什么
	while(NULL != (direntp=readdir(dirp)))
	{
		if (strstr(direntp->d_name,"28-"))
		{
			strncpy(chip,direntp->d_name,sizeof(chip));//duancuowu
			found = 1;
		}
	}
	closedir(dirp);

	if (found < 0)
	{
		printf("nofind \"-28\" \n");
		return -3;
	}
	printf("find chip success[%s]\n",chip);
    
	snprintf(ds_path,sizeof(ds_path),"%s%s/w1_slave",w1_path,chip);
    printf("ds_path:%s\n",ds_path);

	if ((fd = open(ds_path,O_RDONLY)) < 0)
	{
		printf("open error[%s]\n",strerror(errno));
		return -4;
	}

	int i;
	int *p = NULL;
	p = &i;
	//read fd 
	memset(buf,0,sizeof(buf));
	if ( read(fd,buf,sizeof(buf)) <=0 )
	{
		printf("error:[%s]\n",strerror(errno));
		return -5;
	}
	//printf("temperature:[%s]\n",buf);

	if ( NULL == (ptr = strstr(buf,"t=") ))
	{
		printf("nofound error[%s]\n",strerror(errno));
		return -6;
	}

	//printf("%s\n",ptr);
	ptr += 2;

	*temp = atof(ptr)/1000;

	return 0;
}


(1)首先我们使用 gcc 直接生成的程序是没有调试信息的,所以我们要使用 gcc -g 命令来生成一个带有调试信息版本的目标文件。

在这里插入图片描述

(2)然后我们用 gdb 来打开这个目标文件,其实就是让带有调试信息的二进制文件在我们 gdb 的这个 “盒子” 里面进行运行。 用 gdb + 目标文件 命令来运行它。

在这里插入图片描述

(3)之后我们就可以开始调试啦!如何让 test_gdb.o 这个文件在gdb中跑起来呢?在 gdb 中输入 run 就可以了。

在这里插入图片描述

(4)不过我们发现,这和不使用 gdb 跑程序没有什么区别,所以我们学习如何增加断点。

增加断点是通过 break 命令来实现的,他有三种基本的使用形式,如下:

(gdb) break main               	# 在 main 函数处设置断点
(gdb) break my_program.c:10    	# 在 my_program.c 文件的第 10 行设置断点
(gdb) break my_function        	# 在 my_function 函数处设置断点

(5)这里假设我们程序异常退出了,但我们不清楚导致退出的错误是发生在 measure 测温函数内还是函数之前,我们就可以在进入这个函数之前,设置一个断点,然后运行它。
在这里插入图片描述我们可以看到,程序成功运行到了这个函数前,没有抛出异常,那么我们就可以确定,异常是在 measure 测温函数内的了。

(6)使用 next 单步执行,但是不进入到函数内部。

在这里插入图片描述

(7)也可以使用step单步执行,但是会进入到函数内部。

在这里插入图片描述

(8)使用bt命令或者backtrace命令显示调用的栈信息:

在这里插入图片描述

(9)显示所有的断点:

在这里插入图片描述

(10)删除特定的某一个断点:

在这里插入图片描述

运行到某一个断点后,要直接运行到下一个断点,使用continue 或者 c 就可以了。若后面没有断点了,那么就会一直运行到结束或者某个循环里面。

命令汇总:

(gdb) break main               	# 在 main 函数处设置断点
(gdb) break my_program.c:10    	# 在 my_program.c 文件的第 10 行设置断点
(gdb) break my_function        	# 在 my_function 函数处设置断点

(gdb) next                     # 或 (gdb) n 单步执行,不进入函数内部
(gdb) step                     # 或 (gdb) s 单步执行,进入函数内部
(gdb) finish                   # 运行到当前函数返回的位置
(gdb) until                    # 运行到循环结束的位置

(gdb) run                      # 启动程序
(gdb) continue                 # 或 (gdb) c 继续运行直到下一个断点

(gdb) backtrace                # 或 (gdb) bt 显示调用栈
(gdb) frame n                  # 切换到调用栈中的第 n 帧
(gdb) info frame               # 显示当前帧的信息
(gdb) info locals              # 显示当前帧的局部变量

(gdb) info breakpoints         # 或 (gdb) info b 显示所有断点
(gdb) delete breakpoint_number # 或 (gdb) d breakpoint_number 删除特定断点
(gdb) clear                    # 删除当前行的断点
(gdb) disable breakpoint_number# 禁用特定断点
(gdb) enable breakpoint_number # 启用特定断点

当然,我们也可以在运行过程中对某些变量进行查看和修改:
在这里插入图片描述

这里用到的命令是:

print 变量名  			#打印变量的值,注意,没有print,没有f。
set var 变量 =# 改变某个变量的值

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

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

相关文章

一些硬件知识(十九)

立创的这个功能&#xff0c;绕等长线时候真的好用到o(╥﹏╥)o&#xff1a; 设计完成后一定要有一个最小工艺安全间距的DRC检查&#xff0c;不然的话又会出现嘉立创反馈短路&#xff0c;或者工艺生产不了&#xff1a; PMOS防反接电路&#xff1a; 理分析&#xff1a;当输入端加…

【两数之和 II - 输入有序数组】python刷题记录

R3-二分查找 双指针简单题 class Solution:def twoSum(self, numbers: List[int], target: int) -> List[int]:#双指针法i0jlen(numbers)-1while i<j:snumbers[i]numbers[j]if s>target:j-1elif s<target:i1else:return i1,j1return []

react-native从入门到实战系列教程一InputText组件之登录表单

登录使我们业务中不可缺少的功能&#xff0c;所以这篇我们学习写在react-native中实现表单登录 实现效果 代码实现 import {View,Text,StyleSheet,Dimensions,TextInput,Button,Alert, } from react-native; import {useEffect, useState} from react; import Logo from ../.…

通过systemd-resloved实现不同域名通过不同的`nameserver`进行解析

通过systemd-resloved实现不同域名通过不同的nameserver进行解析 一般来说只要DNS不发生网络故障就只会在一个nameserver 获取地址&#xff0c;但我们可能需要从不同nameserver 获取不同域名的地址&#xff0c;比如内网环境和外网环境分别使用不同的nameserver &#xff0c;但…

中间证书缺失如何发现和修复

一、背景 微信小程序等功能在发送后台请求时一般都会要求证书齐全&#xff0c;否则就会导致请求发送失败。 一般来说&#xff0c;如果中间证书不齐全&#xff0c;在不同设备上表现不一样&#xff0c;一般PC端可能不会有太大问题&#xff0c;仍然认为你的证书可信&#xff0c;但…

shell实用笔记

目录 一、基本语法 1. 基础知识 2. if判断 3. 循环遍历 介绍一个{ n1..n2 }, seq -s分隔符 n1 n2. 4. 函数脚本传参 结果会是如何&#xff1f; 5. 字符串常规操作 6. 字符串处理&#xff1a;awk、sed、tr。留着下次&#xff0c;太多了 一、基本语法 1. 基础知识 shel…

SSM网上考试系统—计算机毕业设计源码12795

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作…

后端学习笔记(3)--Maven

1.Maven ​ *专门用于管理和构建Java项目的工具&#xff0c;主要功能有&#xff1a; ​ 1.提供了一套标准化的项目结构 ​ 2.提供了一套标准化的构建流程(编译&#xff0c;测试&#xff0c;打包&#xff0c;发布) ​ 3.提供了一套依赖管理机制 1.简介 ​ *Apache Maven是一…

三分钟了解自动驾驶中视觉Transform应用:视觉Transoform自动驾驶综述

引言 Transformer技术在自然语言处理领域取得突破&#xff0c;催生了BERT、GPT和T5等模型。它在计算机视觉中也显示出潜力&#xff0c;尤其在自动驾驶领域&#xff0c;Transformer在物体检测、车道检测和分割等关键任务中替代了传统CNN和RNN&#xff0c;与强化学习结合用于路径…

秒懂Linux之gdb调试

目录 ​ 一. 前情提要 二. 相关命令 2.1 l 行号/函数名 2.2 r 2.3 b 2.4 info break 2.5 d 2.6 disable/enable 2.7 n 2.8 s 2.9 p 2.10 display/undisplay 2.11 c 2.12 bt 2.13 finish 2.14 untill 2.15 set var 三. 总结 一. 前情提要 Linux gcc/g出来的二…

100379.新增道路查询后的最短距离I

今天看到很有意思的一个题目&#xff0c;记录下来&#xff0c;供大家参考 题目描述 解题思路 为了解决这个问题&#xff0c;我们需要处理一系列的单向道路添加操作&#xff0c;并在每次添加后计算从城市 0 到城市 n-1 的最短路径长度。由于初始时每个城市 i 都有一条到 i1 的…

【C++高阶】:C++11的深度解析下

✨ 彼方尚有荣光在&#xff0c;何须悲叹少年轻 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;C学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&…

浅谈 Spring AOP框架 (1)

文章目录 一、什么是 Spring AOP二、为什么要使用 Spring AOP三、AOP 的一些应用场景四、AOP 的组成五、如何使用 Spring AOP六、Spring AOP 的实现原理6.1、JDK 和 CGLIB 的区别 一、什么是 Spring AOP AOP (Aspect Oriented Programming) &#xff1a;面向切面编程&#xff…

[CTF]-PWN:格式化字符串漏洞题综合解析

printf型格式化字符串漏洞&#xff1a; 任意地址写&#xff1a; 32位&#xff1a; 例题&#xff08;inndy_echo&#xff09;&#xff1a; 有格式化字符串漏洞&#xff0c;可以修改printf的got表内地址为system&#xff0c;传参getshell 解法一&#xff1a; 在32位中可以使…

C语言 操作符

操作符分多种&#xff1a;算术操作符&#xff0c;移位操作符&#xff0c;位操作符&#xff0c;赋值操作符&#xff0c;单目操作符&#xff0c;关系操作符&#xff0c;逻辑操作符&#xff0c;条件操作符&#xff0c;逗号表达式&#xff0c;下标引用&#xff0c;函数调用和结构成…

【Web开发手礼】探索Web开发的秘密(十四)-Vue2(1)Node.js的安装、Vue入门

主要介绍了Node.js的安装教程、Vue2常用的一些指令、声明周期&#xff01;&#xff01;&#xff01; 文章目录 前言 Node.js安装 选择安装目录 验证NodeJS环境变量 配置npm的全局安装路径 切换npm的淘宝镜像 安装Vue-cli ​编辑 Vue2入门 引入vue.js文件 入门代码 常用指令 生…

眼在手外-机器人坐标系与相机坐标系标定方法

1 眼在手外坐标系概述 实现机械臂和相机的手眼标定&#xff0c;就是要通过双目相机坐标系、机械臂坐标系和机械臂 末端执行器三者的坐标系转换&#xff0c;求出手眼转换矩阵。设双目相机坐标系为 Oc&#xff0c;标定板坐标 系为 Ow&#xff0c;末端执行器坐标系为 Oe&#xff0…

【学习笔记】Day 3

一、进度概述 1、作业1 2、组会会议纪要——没太听懂&#xff0c;得再看 二、详情 1、作业1 &#xff08;1&#xff09;在python中&#xff0c;想要使output为图片&#xff0c;需要用的matplotlib库&#xff0c;这里做简单的整理&#xff0c;以便更好的理解代码。 …

ADC的介绍和工作原理

一&#xff0c;什么是ADC&#xff1f; Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 什么是ADC&#xff1a; ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 SUCH AS: 12 位 ADC 是一种逐次逼近…

免费【2024】springboot 导师选择管理系统的管理设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…