记录关于智能家居的路程的一个bug___Segmentation fault(段错误)
前言
其实发生段错误的情况有很多:
其实在项目的开发中最有可能的错误就是①和②,考虑到本项目数组用的比较少,所以主要是考虑错误①指针的误用。
有时候错误就是那么离谱,声音也算是一种设备?????
出错原因:对语音模块发出开机的指令就会出现段错误,然后各种错误
有时候又没有段错误
找bug的过程:
第一次找:
怀疑是多线程的问题,把线程一个一个注释掉,发现第四个线程注释掉就不会出现“Segmentation fault”
解决思路:
对比其他三个线程的结构,有没有什么不一样。
对比下来发现,功能其实差的比较大,receive线程的主要目的是接收处理数据,而其他3个都是直接添加设备,果断转战下一个解决思路。
ps:这里补充VsCode的一个对比工具“Partial Diff”插件
差异对比犀利手册:使用 Partial Diff 插件在 VSCode 中比较代码差异_vscode提交代码对比插件-CSDN博客
还补充了 gdb调试 的基本步骤
---------------------------------------------------------------------------------------------------------------------------------
第二次找:
在receive线程里面一句一句的排查注释,最终锁定一段代码、一句话
解决思路:
其实仔细一想,也不是这里的问题,这里只是初始化,情况内存,不是核心问题(因为此时的核心问题没有找,所以根本发现不了,只能挨着继续往下寻找)
---------------------------------------------------------------------------------------------------------------------------------
第三次找:
进一步排查,发现是该函数的memset的下面一句发生了错误,同样也发生了错误
解决思路:
排查到这句话,现在想起来其实是可以说明 cur_gdev->gpio_status 的状态是有问题的,只是当时不清楚,排查不到这里去。当时的解决思路完全是去纠结这里的语法去了
第一次改 :strcpy(change_status, cur_gdev->gpio_status == LOW ? "Open" : "Close");
修改的原因是:考虑字符串不能直接赋值。
但是不幸的是仍然是报错
所以又试了试不用三目运算符来写一下试试???
发现还是不行还是段错误。
继续考虑,会不会是指针没有分配到地址??
还是报错!
此时又回过头来考虑语法的问题
想了想 change_status 是一个指针,而 cur_gdev->gpio_status 是一个int类型,这两个能直接比较吗?
而且能够把字符串赋值给int类型的变量吗?现在想想都觉得当时写的很好笑
这个时候就应该考虑让 gpio_status 与一个数字作比较来判断高低电平
if (gpio_status == 0)
以及用 strcpy() 来对字符串赋值
但是仍然是报错!!!!
此时的报错原因 就是,语音模块的开机,“你好 小美” 就会出现段错误
没办法继续找吧,但是此时可以确定,该程序能不能跑到这里去
-------------------------------------------------------------------------------------------------------------------------------
第四次找:
还是把这段注释掉就不会崩,此时还是没有找到报错的核心问题
---------------------------------------------------------------------------------------------------------------------------------
第五次找:
第四次找的每一步都加上打印,最后确定查询到哪里停止
解决思路:
推荐方法 : printf("running %d \n",__LINE__);
如果程序崩了的话就看看running停在了哪里 哪里就是问题所在
现在可以基本上确定问题所在 “change_status”的数据没有,所以造成了错误,逐渐向真相靠近
并且把这一步注释掉,没有任何意义,根本copy不了,gpio_status 这玩意又不是指针,所以留着也没什么意义
这一句的作用就相当于上面那一句了
当删了这句话之后,程序往前跑了一步
此时说明 cur_gdev->gpio_status 的状态根本就是一个空白的数据!!!拿不到数据才会段错误(这个时候才算是真正的发现了出现段错的核心所在了)
---------------------------------------------------------------------------------------------------------------------------------
第六次找:
跟着往上发现是cur_gdev 这个指针有问题
解决思路:
打印该指针的 io状态 、以及 地址(先打印地址,没有地址的话哪来的io状态???)
发现该指针的地址为空,这才是发生段错误的真相!根本就拿不到当前指针的地址,剩下的数据也不可能拿到
所以接下来的操作就是看看这个变量会经历什么过程,为什么会没有空间??
此时的核心问题已经转移到该函数 find_gdevice_by_key 上面
因为目前的状态就是该函数根本拿不到数据,打印出来的 cur_dgev 的地址就是一个空
此时就要进一步探讨这个函数的实现逻辑是怎么样的,对比了什么指令,对比指令,传入参数这些是否正确????
-------------------------------------------------------------------------------------------------------------------------------
第七次找:
打印 find_gdevice_by_key 的比对结果是怎么样的
发现是正常的结果
此时就要使用 gdb 调试,找到这个函数 打断点
多文件多函数打断点的方法 break myFile.c:myFunction
得把其他的线程注释掉来调试
解决思路:
此时考虑 find_gdevice_by_key 的主要功能,在这个函数进行打印调试
发现也是正确的
除此之外还进行了其他的调试
没办法这些也不是最主要的点
第八次找:
考虑一件事(最原始的问题,最初的问题),为什么是开机就会发生段错误???
打开客厅灯不会发生段错误,为什么就开机会发生段错误???
解决思路:
这时候灵光一现!“你说声音会不会是一种设备?作为指令传入到被控设备链表之中”
此时添加 voive_gfevice 文件
奇迹的出现!真的没有报错了
至此,问题得到了解决,就是没有把声音当作一个设备,进行传入到当前的设备链表之中,所以造成了只有开机的时候才会发生段错误,因为没有添加开机设备的指令的时候,此时开机就没有指令传到被控链表之中,而find_gdevice_by_key 这个函数只会到当前已加入的设备链表中比对发送的指令,自然也就比对不到声音发过来的0x40这样一个指令,所以就会报错!
========================================================================
更新于第二天:
问题的核心其实还是cur_gdevice为空,但是还是要补充
其实上面的解决的bug只能够解决一时,真正想让项目运行起来的是解决办法是
相关文章:

记录关于智能家居的路程的一个bug___Segmentation fault(段错误)
前言 其实发生段错误的情况有很多: 其实在项目的开发中最有可能的错误就是①和②,考虑到本项目数组用的比较少,所以主要是考虑错误①指针的误用。 有时候错误就是那么离谱,声音也算是一种设备??ÿ…...

由浅到深认识Java语言(39):网络编程
该文章Github地址:https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.c…...

PCL 彩色点云RGB转灰度并显示
目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 不同要素之间的灰度差异较为明显。点云灰度值与RGB属性的关系为:...

RHEL9部署Docker环境
华子目录 Docker引擎架构docker引擎架构示意图执行过程示例 RHEL9上安装Docker1.系统要求2.安装yum-utils工具包3.yum安装docker-ce4.配置docker镜像加速docker拉取镜像的过程配置阿里云镜像仓库重新加载守护进程重启Docker服务 5.拉取并运行hello-world镜像6.测试是否安装成功…...

Vue3.0云里雾里
目录:一篇通识Vue3.0 1.OptionsAPI(选项式)和CompositionAPI(组合式) 2.setup setup语法糖 ref响应式数据 reactive只能定义对象类型的响应式数据(用情专一) toRefs解构 计算属性computed watch侦听 WatchEffect 标签的Ref属性 组件上的ref就是获取组件实例…...

idea类已经存在却报错
一句话导读 在idea中导入新的项目,很多类都飘红报错,mvn compile可以通过,可能是因为idea缓存问题导致。 由于这个项目是由老项目复制过来后,再继续开发新的功能,很多同事导入后,都爆出新的类找不到。而编译…...

MySQL---视图
目录 一、介绍 二、语法 三、视图的更新 四、视图作用 一、介绍 视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。 通俗的讲&#…...

策略路由-IP-Link-路由协议简介
策略路由 策略路由和路由策略的不同 1.策略路由的操作对象是数据包,在路由表已经产生的情况下,不按照路由表进行转发,而是根据需要,依照某种策略改变数据包的转发路径 2.路由策略的操作对象是路由信息。路由策略的主要实现了路…...

数位五五(Java)
数位五五 题目描述 求出[a,b]区间内有多少个数数位之和为 55 的倍数。 输入格式 输入一行包含两个整数a ,b。 输出格式 输出一个整数。 样例输入输出 样例输入 10 20样例输出 2数据范围 对于 100% 的数据,保证 1≤a≤b≤1000000。 样例解释 …...

蓝桥杯G431RBT6——定时器中使用led冲突以及led与lcd冲突等一系列问题
本文是解决 同时在 定时器中点灯 与 LCD屏幕显示 冲突异常的问题 我们大家都知道,G431RBT6开发板上led与lcd是冲突的,所以在lcd.c文件中的这三个函数中 void LCD_WriteReg(u8 LCD_Reg, u16 LCD_RegValue) void LCD_WriteRAM_Prepare(void) void LCD_Wr…...

物联网(IoT)常用的通信协议
物联网(IoT)的通信协议是物联网设备之间交换数据的规则和标准。这些协议对于确保设备能够有效、安全地通信至关重要。下面是物联网通信协议的概述: 1. MQTT(消息队列遥测传输) 概述:MQTT是一种轻量级的发…...

关于C/C++,Linux/MacOS/Windows 平台虚拟内存分配
在 Windows 平台上面建议通过 VirtualAlloca、VirtualAllocaEx 核心库函数来分配虚拟内存,而不是通过 MMF(Memory Mapping File / 内存映射文件)技术来载入虚拟内存。 这是因为,在 Windows 平台上面,通过MMF技术分配的…...

如何在服务器上传/下载文件
从服务器下载文件到本地 打开xshell,输入:ssh root159.xxx.xxx.xx 然后需要输入密码 cd到目录文件夹下 cd /enmotech apt install zip zip -r uploads.zip uploads apt install lrzsz sz uploads.zip 从本地上传文件到服务器 如果文件是放在E盘…...

C++ 之多态虚函数原理及应用
文章目录 多态基本概念和原理虚函数的基本原理和概念虚析构和纯虚析构多重继承中的虚函数小结 多态基本概念和原理 多态的基本概念 **多态是C面向对象三大特性之一** 多态的定义 多态是一种面向对象编程概念,指同一个行为(方法)在不同的对象上…...

亮数据——让你的IP走出去,让价值返回来
亮数据——让你的IP走出去,让价值返回来 前言跨境电商最最最大的痛点——让IP走出去超级代理服务器加速网络免费的代理管理软件亮数据解决痛点亮数据优势介绍亮数据浏览器的使用示例总结 前言 当前社会信息的价值是不可想象的,今天在亮数据中看到了个【…...

spring boot-引入Redis并封装redistemplate操作工具类
文章目录 一、关于spring-redis二、springboot引入Redis及其使用案例三、封装redistemplate操作工具类 一、关于spring-redis spring-data-redis针对jedis提供了如下功能: 连接池自动管理,提供了一个高度封装的“RedisTemplate”类 针对jedis客户端中大…...

android 11 SystemUI 状态栏打开之后的界面层级关系说明之一
比如WiFi 图标的父layout为: Class Name: ButtonRelativeLayout Class Name: QSTileView Class Name: TilePage Class Name: PagedTileLayout Class Name: QSPanel Class Name: NonInterceptingScrollView Class Name: QSContainerImpl Class Name: FrameLayout Cl…...

C#___锁(lock)
lock是一种语言级别的关键字,用于实现线程同步和互斥。它提供了一种简单的方式来确保多个线程不会同时访问共享资源,从而避免竞争条件和数据不一致的问题。 作用: 1、避免并行运算中,共享数据的的读写安全问题; 2、并…...

JAVA的sort用法详解(二维数组排序,List<>排序,lambada表达式,自定义类型排序)
目录 前言: 一维数组降序: 方法1.Comparator接口: 代码实现: 方法2.Collections.reverseOrder(): 代码实现: 二维数组排序: 代码如下: List<>排序: 代码…...

数据分析能力模型分析与展示
具体内容: 专业素质 专业素质-01 数据处理 能力定义•能通过各种数据处理工具及数据处理方法,对内外部海量数据进行清洗和运用,提供统一数据标准,为业务分析做好数据支持工作。 L1•掌握一…...

BUG未解之谜01-指针引用之谜
在leetcode里面刷题出现的问题,当我在sortedArrayToBST里面给root赋予初始值NULL之后,问题得到解决! 理论上root是未初始化的变量,然后我进入insert函数之后,root引用的内容也是未知值,因此无法给原来的二叉…...

数据库事务编程
事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执行的结果必须使数据库从一种一致性状态到另一种一致性状态。事务是逻辑上的一组操作,要么都执行,要么都不执行。 事务的 4 大特性 ACID 原子性 Atomicit…...

专题二_滑动窗口(1)
目录 209. 长度最小的子数组 解析 题解 3. 无重复字符的最长子串 解析 题解 1004. 最大连续1的个数 III 解析 题解 209. 长度最小的子数组 209. 长度最小的子数组 - 力扣(LeetCode) 解析 题解 class Solution { public:int minSubArrayLen(int…...

把本地文件上传到HDFS上操作步骤
因为条件有限,我这里以虚拟机centos为例 实验条件:我在虚拟机上创建了三台节点,部署了hadoop,把笔记本上的数据上传到hdfs中 数据打包上传到虚拟机节点上 采用的是rz命令,可以帮我们上传数据 没有的话可以使用命令安装…...

Leo赠书活动-21期 《一篇讲明白 Hadoop 生态的三大部件》
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 赠书活动专栏 ✨特色专栏:…...

【Redis】Redis 介绍Redis 为什么这么快?Redis数据结构Redis 和Memcache区别 ?为何Redis单线程效率也高?
目录 Redis 介绍 Redis 为什么这么快? Redis数据结构 Redis 和Memcache区别 ? 为何Redis单线程效率也高? Redis 介绍 Redis 是一个开源(BSD 许可)、基于内存、支持多种数据结构的存储系统,可以作为数据…...

ArrayList和LinkedList有什么区别?
ArrayList和LinkedList的区别 ArrayList 和 LinkedList 是 Java 中常用的两种集合类,它们都实现了 List 接口,但在内部实现和性能上有一些区别。 内部实现: ArrayList 使用数组实现,它的元素在内存中是连续存储的,每…...

离线数仓(八)【DWD 层开发】
前言 1、DWD 层开发 DWD层设计要点: (1)DWD层的设计依据是维度建模理论(主体是事务型事实表(选择业务过程 -> 声明粒度 -> 确定维度 -> 确定事实),另外两种周期型快照事实表和累积型…...

Jenkins用户角色权限管理
Jenkins作为一款强大的自动化构建与持续集成工具,用户角色权限管理是其功能体系中不可或缺的一环。有效的权限管理能确保项目的安全稳定,避免敏感信息泄露。 1、安装插件:Role-based Authorization Strategy 系统管理 > 插件管理 > 可…...

简明conan教程
简明conan教程 1 关于conan1.1 来源1.2 作用 2 安装conan2.1 ubuntu2.1.1 安装python32.1.2 安装conan 2.2 Windows2.2.1 安装python32.2.2 安装conan 2.3 验证conan是否成功2.4 命令解释2.4.1 Consumer commands2.4.2 Creator commands2.4.3 Package development commands2.4.…...