记录关于智能家居的路程的一个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只能够解决一时,真正想让项目运行起来的是解决办法是

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

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

相关文章

35.HarmonyOS App(ArkUI)使用父组件@Builder装饰的方法初始化子组件@BuilderParam报错

HarmonyOS App(ArkUI)使用父组件Builder装饰的方法初始化子组件BuilderParam报错 Type void is not assignable to type () > void. <tsCheck> 去掉括号()就可以了 装饰器&#xff1a; 用于装饰类、结构、方法以及变量&#xff0c;并赋予其特殊的含义。如上述示例中En…

SpringBoot实现RabbitMQ的简单队列(SpringAMQP 实现简单队列)

文章目录 1. 前言2. Basic Queue 简单队列模型2.1 父工程导入依赖2.2 消息发送2.2.1 消息发送方必要的配置2.2.2 发消息 3. 消息接收3.1 消息接收方必要的配置3.2 接收消息 1. 前言 SpringAMQP 是基于 RabbitMQ 封装的一套模板&#xff0c;并且还利用 SpringBoot 对其实现了自…

2024.3.26学习总结

一&#xff0c;正则匹配 正则匹配是用来搜索&#xff0c;匹配&#xff0c;替换的一种字符串模式&#xff0c;使用正则匹配可以让搜索匹配的语句更加简洁&#xff0c;在php中会使用一些函数来处理正则匹配 常用的语法&#xff1a; 字符类 [abc]: 匹配单个字符a、b或c[^abc]: 匹…

DevSecOps平台架构系列-互联网企业私有化DevSecOps平台典型架构

目录 一、概述 二、私有化DevSecOps平台建设思路 2.1 采用GitOps公有云建设 2.2 采用GitOps私有云建设 2.3 总结 三、GitOps及其生态组件 3.1 采用GitOps的好处 3.1.1 周边生态系统齐全 3.1.2 便于自动化的实现 3.1.3 开发人员属性GitOps 3.2 GitOps部分生态组件介绍…

搜维尔科技【应急推演】虚拟仿真技术的发展为煤炭矿井的安全生产找到新的出口

煤炭矿井的安全生产一直是我国关注的重大事项&#xff0c;保证煤炭矿井的安全生产&#xff0c;减少人员伤亡等不可逆的损失成为重中之重。虚拟仿真技术的发展为煤炭矿井的安全生产找到了新的出口。依托虚拟仿真技术&#xff0c;对煤炭矿井进行实时的生产监测&#xff0c;对矿井…

华为昇腾asend

昇腾Ascend C编程语言 Ascend C原生支持C/C编程规范&#xff0c;通过多层接口抽象、并行编程范式、孪生调试等技术&#xff0c;极大提高了算子的开发效率&#xff0c;帮助AI 参考文章 手把手教你在昇腾平台上搭建PyTorch训练环境 - 哔哩哔哩 (bilibili.com)https://www.bilibi…

科普 | Runes 预挖矿概念

作者&#xff1a;Jacky X/推&#xff1a;zxl2102492 关于 Runes 协议的前世今生&#xff0c;可以点击阅读这篇文章 &#x1f447; 《简述 Runes 协议、发展历程及最新的「公开铭刻」发行机制的拓展讨论》 什么是传统预挖矿概念 这轮比特币生态爆发之前&#xff0c;预挖矿&…

2024 MCM数学建模美赛2024年A题复盘,思路与经验分享:资源可用性与性别比例 | 性别比例变化是否对生态系统中的其他生物如寄生虫提供优势(五)

审题 第四问让我们探究性别比例变化是否对生态系统中的其他生物如寄生虫提供优势。这里我们可以把问题简化一下&#xff0c;只探究性别比例会不会对寄生虫提供优势。因为考虑太多生物&#xff0c;会使模型更复杂&#xff0c;我这个水平处理不了这么复杂的问题&#xff0c;是我…

Healix Protocol 的 HLX 通证预售:医疗领域的未来展望

Healix Protocol推出 HLX 通证预售&#xff0c;将带来医疗领域的重要变革。通过其区块链技术&#xff0c;Healix Protocol致力于重新定义医疗服务的可及性与负担性&#xff0c;成为医疗行业的希望之光。该项目旨在增强透明度、可及性和效率&#xff0c;推动医疗体系向更加公平和…

ripro子主题wori-child集成后台美化包(适用于设计素材站+资源下载站等)

新内容如下 1、子主题独立运行,彻底摆脱覆盖原主题文件 2、下载信息插件升级优化 3、细节优化 V1.0更新内容如下 1、同步暗黑美化、手机端美化 2、新增菜单合成幻灯片&#xff08;后台自行设置&#xff09; 3、新增公告统计 &#xff08;后台自行设置&#xff09; 4、新增…

【小沐学AI】智谱AI大模型的一点点学习(Python)

文章目录 1、简介1.1 大模型排行榜 2、智谱AI2.1 GLM2.1.1 模型简介2.1.2 开源代码2.1.2.1 GLM-130B 2.2 ChatGLM2.2.1 模型简介2.2.2 开源代码2.2.2.1 ChatGLM2.2.2.2 ChatGLM22.2.2.3 ChatGLM3 2.3 CodeGeeX2.3.1 模型简介2.3.2 开源代码 2.4 CogView2.4.1 模型简介2.4.2 开源…

如何使用 ArcGIS Pro 自动矢量化水系

对于某些要素颜色统一的地图&#xff0c;比如电子地图&#xff0c;可以通过图像识别技术将其自动矢量化&#xff0c;这里为大家介绍一下 ArcGIS Pro 自动矢量化水系的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的电子地图数据&#…

政安晨:【深度学习神经网络基础】(二)—— 神经元与层

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: 政安晨的机器学习笔记 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 神经元是深度学习神经网络中的基本单元&#xff0c;模拟了…

CheatFetcher风灵月影修改器快速下载器

地址:https://github.com/MartinxMax/CheatFetcher/releases/tag/v1.0 CheatFetcher网络爬虫风灵月影作弊器快速下载器 采用翻译接口,实现输入中文转为英文搜索,并且英文结果转为中文输出你可以在此更快的下载到游戏修改器 示例 打开cmd窗口,或者其他终端运行 >CheatFe…

C++:变量和常量(3)

变量 什么是变量&#xff1a;变量就是一个装东西的盒子 通俗&#xff1a;变量是用于存放数据的容器。我们通过变量名获取数据&#xff0c;甚至数据可以修改 变量的作用&#xff1a;给指定的内存空间起名&#xff0c;后期通过起的名字就可以调用整个内存空间 定义变量的格式 &a…

AXI Memory Mapped to PCI Express 学习笔记(四)——仿真设计

本文包含有关Vivado Design Suite中对AXI Memory Mapped to PCI Express core进行仿真的示例设计信息。 一、仿真设计概述 在仿真设计中&#xff0c;事务是从Root Port模型发送到配置为Endpoint的AXI Memory Mapped to PCI Express core&#xff0c;并在AXI块RAM控制器设计中…

基于模糊控制算法的倒立摆控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 对倒立摆模型进行模糊控制器simulink建模&#xff0c;利用倒立摆的摆角角度与小车的位置来控制小车的推力&#xff0c;控制了倒立摆的摆角问题&#xff0c;使得小车最终停在稳…

SpringBoot实现RabbitMQ的WorkQueue(SpringAMQP 实现WorkQueue)

文章目录 1. 前言2. 思路3. 消息发送4. 消息接收4.1 能者多劳 总结 1. 前言 上一篇文章,实现了用 SpringBoot实现RabbitMQ的简单队列, 篇文章 操作 用SpringBoot实现RabbitMQ的WorkQueue(SpringAMQP 实现WorkQueue) Work queues&#xff0c;也被称为&#xff08;Task queues&…

Python Flask-Mail实现邮件发送

一、邮件发送的扩展 关于如何找到flask发送邮件的插件&#xff1f;&#xff0c;上一篇已经分享了如何找到第三方插件&#xff0c;也找到了插件flask-mail的使用文档&#xff0c;那我们就来实战吧 二、根据文档&#xff0c;总结发送邮件的流程 从文档中可以总结出发送邮件的步…

springboot-vue前后端分离项目实例

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…