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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Dockerfile:自定义镜像

Dockerfile 是一个文本文件,其中包含了一系列用于自动化构建Docker镜像的指令。通过编写Dockerfile,开发者能够明确地定义一个软件应用及其运行环境应该如何被封装进一个可移植、可重复构建的Docker镜像中。 第一步:在/tmp文件下新建docker…

GEE:将分类特征和标签提取到样本点,并以(csv/shp格式)下载到本地

作者:CSDN @ _养乐多_ 本文将介绍在Google Earth Engine(GEE)平台上,下载用于机器学习分类或者回归的样本点数据,样本点数据携带了分类特征和标签信息,可以以csv格式或者SHP格式。 结果如下图所示, 文章目录 一、核心函数1.1 采样1.2 下载函数二、代码链接三、完整代码…

Machine Learning机器学习之K近邻算法(K-Nearest Neighbors,KNN)

目录 前言 背景介绍: 思想: 原理: KNN算法关键问题 一、构建KNN算法 总结: 博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共…

Python入门练习 - 学生管理系统

Python 实现读书管理系统 """ 实现一个命令行版的读书管理系统 """ import os.path import sys# 使用这个全局变量,来管理所有的学生信息 # 这个列表的每个元素都是一个‘字典’,每 个 字典就分别表示了一个同学students …

电脑访问网页获取路由器WAN口内网IP

因为运维过程中容易出现路由器配置了固定IP但是没人知道后台密码,不确定这个办公室的IP地址,且使用tracert路由追踪也只会出现路由器的LAN口网关并不会出现WAN口IP。 今日正好遇到了个好方法,经过测试可以正常使用。 方法如下: 内…

机器视觉矿山安全生产风险预警系统

一、简介 十四五规划和2035年远景目标纲要针对企业安全生产提出了多项要求。其中,提高安全生产水平要求完善和贯彻执行安全生产责任制,建立公共安全隐患排查和安全预防控制体系,要求将安全生产提升至预防和控制阶段。 目前,矿山…

0DAY漏洞是什么,如何进行有效的防护

零日漏洞,指的是软件或系统中未被公开的、未被厂商知晓的安全漏洞。这些漏洞未被修复,因此黑客可以利用它们进行攻击,而受害者往往无法防范。由于这些漏洞的存在时间很短,因此称之为“零日漏洞”,也称为“0day漏洞”。…

LeetCode:1319. 连通网络的操作次数(并查集 Java)

目录 1319. 连通网络的操作次数 题目描述: 实现代码与解析: 并查集 原理思路: 1319. 连通网络的操作次数 题目描述: 用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示…

【Bug-ModuleNotFoundError: No module named ‘models‘】

🚀 作者 :“码上有前” 🚀 文章简介 :Python 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 出现这个错误: 出现了ModuleNotFoundError: No module named models’的问题。 文件在Model…

春秋云境CVE-2023-27179

简介 GDidees CMS v3.9.1及更低版本被发现存在本地文件泄露漏洞,漏洞通过位于 /_admin/imgdownload.php 的 filename 参数进行利用。 正文 进入靶场发现没有什么可以利用的地方,那么就按照靶场提示来,直接访问/_admin/imgdownload.php 打开…

SQLite数据库浏览器sqlite-web

什么是 sqlite-web ? sqlite-web是一个用 Python 编写的基于 Web 的 SQLite 数据库浏览器。 软件特点: 可与您现有的 SQLite 数据库配合使用,也可用于创建新数据库。添加或删除: 表格列(支持旧版本的 SQLite&#xff…

网络链路层之(1)基础概念

网络链路层之(1)基础概念 Author: Once Day Date: 2024年3月27日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文章可参考专栏: 通信网络技术_Once-Day的博客-CSD…

Spring(详细介绍)

目录 一、简介 1、什么是Spring? 2、Spring框架的核心特性 3、优点 二、IOC容器 介绍 1、获取资源的传统方式 2、控制反转方式获取资源 3、DI 4、IOC容器在Spring中的实现 入门案例 1、创建Maven Module 2、引入依赖 3、创建HelloWorld类 4、在Spring的配…

EdgeGallery开发指南

API接口 简介 EdgeGallery支持第三方业务系统通过北向接口网关调用EdgeGallery的业务接口。调用流程如下图所示(融合前端edgegallery-fe包含融合前端界面以及北向接口网关功能,通过浏览器访问时打开的是融合前端的界面,通过IP:Port/urlPref…

Overcooked!(并查集区间元素合并优化)

本题链接:登录—专业IT笔试面试备考平台_牛客网登录—专业IT笔试面试备考平台_牛客网登录—专业IT笔试面试备考平台_牛客网 题目: 样例: 输入 5 5 1 1 2 3 1 2 2 2 4 3 1 4 3 2 5 输出 YES YES NO 思路: 根据题意,这…

KubeSphere简单介绍及安装使用

KubeSphere 概述 官网地址:https://kubesphere.io/zh/ 什么是 kubesphere KubeSphere 是一个开源的多云容器管理平台,旨在简化企业级 k8s 集群的部署、管理和运维。它提供了一个可视化的管理界面,帮助用户更轻松地管理和监控 k8s 集群&…

『Apisix进阶篇』动态负载均衡:APISIX的实战演练与策略应用

🚀『Apisix系列文章』探索新一代微服务体系下的API管理新范式与最佳实践 【点击此跳转】 📣读完这篇文章里你能收获到 🎯 掌握APISIX中多种负载均衡策略的原理及其适用场景。📈 学习如何通过APISIX的Admin API和Dashboard进行负…

设计模式——行为型——策略模式Strategy

Q:策略模式的特点 A: 具体算法从具体的业务方法中独立出来策略模式是同行为的不同实现 Q:什么时候使用策略模式 A:多个if-else使用策略模式 收费对象类 public class CashContext {private CashStrategy cashStrategy;public…

备考ICA----Istio实验10---为单个主机配置TLS Istio Ingress Gateway实验

备考ICA----Istio实验10—为单个主机配置 TLS Istio Ingress Gateway实验 1. 环境准备 部署httpbin kubectl apply -f istio/samples/httpbin/httpbin.yaml 2. 证书生成 2.1 生成根证书 生成根证书keyfile和crt文件 mkdir example_certs_root openssl req -x509 -sha256 …

Code Review 最佳实践

成功的同行评审策略要求严格记录的流程与非威胁性、协作性环境之间保持平衡。高度规范的同行评审可能会抑制生产力,然而,过于随意的流程往往效果不佳。经理们需要找到一种折中方案,使同行评审既高效又有效,同时促进团队成员之间的…