常见的C++软件异常场景分析与总结
根据排查软件异常问题的经历和经验,简单的总结一下软件异常的场景和原因,以供参考。
1、野指针问题
可能是指针没初始化就使用。也有可能是指针指向的内存已经被释放,但是指针没置为NULL,一旦访问这样的指针就会出问题。在很多情况(包括访问空指针的情况)下可能会访问64KB以内的系统禁止访问的NULL指针内存区,系统直接将程序终止掉。此处是某个变量没有初始化,也有可能某个dll库没初始化,就调用库中的接口了。
2、空指针问题
有可能内存已经释放,指针已经置为NULL,但是后面还是访问了空指针。比如在某个库已经unInitialize之后还调用库中的接口或者库中运行的代码访问了空指针。也有可能是调用接口返回了空指针,调用者没有添加指针是否为空判断。
3、堆内存被释放两次
已经释放了,但是又调用free或delete释放了一次,即释放了两次。对于空指针,释放多次也没问题。
4、栈内存被当做堆内存来释放
比如在类的函数中自动释放当前类对象的内存,即delete this,但是在用类定义的对象时,使用的栈内存,使用delete释放栈内存就有问题了。
5、内存访问越界
将相邻的内存中的内容破坏了,即将相邻的内存中的内容篡改了,会出现各种意想不到的问题。比如就会触发访问访问NULL指针内存区的异常、后续内存拷贝因为长度被篡改,导致另一个内存越界操作。不管是堆内存越界,还是栈内存越界,都可能导致异常。最直接的异常可能就是在越界的时候发生内存访问违例。
6、不同编译器对STL的实现不同
例如VS和MinGW在std::string\std::map均是不兼容的。
7、类对象没有初始化就直接访问问题
比如临界区对象,没调用初始化接口,就直接enter了,就会出异常。有可能代码中跳出异常,将初始化的代码跳过去。
8、内存泄漏
堆内存未释放。
指针赋值时托管另外一块内存,未释放、管理之前的内存。
内存分配器(C:malloc、calloc、realloc、free,C++:new、delete、new[]、delete[])混用、乱用。
9、系统内存不足
处理方法:
1)程序中尽量早释放不使用的内存、释放暂时空闲的内存
2)减少多余的拷贝
3)设置对内存不足的处理方法std::set_new_handler
4)使用内存池
5)使用虚拟内存
6)使用64位系统,增加物理内存大小
10、栈溢出
1)原因:递归过程的局部变量过多、递归深度过大,是造成系统栈溢出的原因,特别是递归列循环时肯定会发生系统栈溢出。
2)处理方法:
尾部递归优化
大内存的对象由栈改用堆
11、函数调用约定不一致引起的栈不平衡的问题
比如在给dll库中设置回调函数,回调函数没指定调用约定,使用VS默认的C调用。但是当dll被C#调用时,包含dll的头文件,C#中默认使用标准调用。回调函数在C#层实现时被设置为标准调用,函数内部负责清理栈,但是在dll中调用到回调函数,dll认为函数是C调用,dll中在调用回调函数时会在函数外部清理栈,这样在回调函数被调用后,多清理了一次栈,这样栈就不平衡了。
12、调用虚函数时的二次寻址
C++的虚函数存放在虚函数表中。如果要调用一个类对象的虚函数,需要通过类对象首地址,得到虚函数表首地址,然后根据调用的虚函数名称,到虚函数中找到虚函数的地址,然后call这个地址。在汇编代码中,能看到二次寻址的详细过程。
13、debug和release库混用的问题
可能dll导出接口在dll内部申请的堆内存,需要调用者在外部释放。如果该dll是release版本的,而调用者是debug版本的,这个在调用者释放内存时就会出现异常。因为debug和release下的内存管理是不同的。debug下包含调试信息,申请的内存较大。
14、死循环问题
死循环一般会导致系统的CPU占用会比较高。如果是UI主线程,则比较好办,就是0号线程,切换到0号线程,然后多go几次,查看堆栈是否一样。如果一样可以使用bp设置堆栈中的多个断点,看到底死循环发生在哪个函数中。一般是循环体中出现了较大的循环次数导致的,或者是循环条件设置有问题,一直为TRUE。可以看一下堆栈中的与循环条件相关的局部变量的值,从而定位问题。如果是远端传过来的值作为循环次数,可能要添加上限保护,放置传过来的是异常值。如果是底层的线程,可以借助Process Explorer查看一下堆栈,找到线程id和堆栈,到windbg中切换到目标线程中设置断点,判断是否有死循环。也可以直接在windbg中使用!runaway命令查看哪个线程占用CPU较高,有必要时可能还要看看是内核态的占用多,还是用户态的占用的多。
15、数据类型使用违规引起的问题
比如没有搞清楚某类的约束条件,随意使用其接口,导致使用违规,触发异常。
16、抛出异常后导致部分代码被跳过的问题
类中遇到异常数据抛出异常,程序仍在运行,但是有部分代码被跳过,导致代码逻辑出现异常。比如初始化CTime对象时传入了异常值报出异常。还比如新人对stl中的vetctor等类对象执行了memset的操作,破坏了stl内部的结构数据,导致stl内部产生异常。当然还有一种场景,直接抵CString进行memset操作,破坏了类中的维护结构的数据,一般都会触发异常。一般memset是对结构体操作的,但如果结构体中包含非基本数据类型,比如类对象就要注意了,只能在构造函数中初始化,不能直接进行memset。所以在使用memset时,遇到类对象就要注意了。
17、静态、全局对象的创建和释放有先后依赖关系
例如:静态对象A和B,由系统创建,所以无法确定创建先后顺序。但A的构造函数中调用了B对象。
18、共享指针(shared_ptr)的循环引用
参考:[C++弱引用智能指针weak_ptr的用处](二)(https://blog.csdn.net/qq_43148810/article/details/122540820)
19、多线程存在数据竞争,未同步问题
多线程加锁,该知识设计很深,在这这展开。
20、一个线程维护变量值,另外一个线程通过循环去读取
1)问题:
热访问(不加延时)造成CPU资源占用.
每次循环加入延时,容易遗漏变量变化过程,任务频繁切换效率低
2)处理方法:
条件变量,事件机制
21、死锁问题排查
VS的“并行堆栈”窗口工具可直接分析
日志等工具
目前用windbg排查关键代码的死锁相对简单,因为关键代码段是用户态的对象。
如果是内核对象的锁,则需要进行内核态的调试,不过内核态的调试比较复杂。
如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810
相关文章:
常见的C++软件异常场景分析与总结
根据排查软件异常问题的经历和经验,简单的总结一下软件异常的场景和原因,以供参考。 1、野指针问题 可能是指针没初始化就使用。也有可能是指针指向的内存已经被释放,但是指针没置为NULL,一旦访问这样的指针就会出问题。在很多情…...
【虹科公告】好消息!云展厅开放时间长达1年,2023年不限次云观展
云展厅开放通知 2023年,【虹科赋能汽车智能化云展厅】将持续开放,开放时间长达一年,开放期内,均可进入观展,没有次数及观看时长限制,欢迎大家随时进入云展厅观展。 虹科赋能汽车智能化云展厅 聚焦前沿技…...
Linux破解root密码
✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏:Linux操作…...
2023年信息与通信工程国际会议(JCICE 2023)
2023年信息与通信工程国际会议(JCICE 2023) 重要信息 会议网址:www.jcice.org 会议时间:2023年3月17-19日 召开地点:成都 截稿时间:2023年2月10日 录用通知:投稿后2周内 收录检索:EI,Scopus 会议简介…...
ASP.NET Core+Element+SQL Server开发校园图书管理系统(完)
随着技术的进步,跨平台开发已经成为了标配,在此大背景下,ASP.NET Core也应运而生。本文主要基于ASP.NET CoreElementSql Server开发一个校园图书管理系统为例,简述基于MVC三层架构开发的常见知识点,本系列共五篇文章&a…...
elasticsearch 批量写入(Python版).md
1. 插入数据 现在我们如果有大量的文档(例如10000000万条文档)需要写入es 的某条索引中,该怎么办呢? 1.1 顺序插入 import time from elasticsearch import Elasticsearches Elasticsearch()def timer(func):def wrapper(*arg…...
【排序算法】快速排序(Quick Sort)
快速排序(Quick Sort)使用分治法算法思想。快速排序介绍它的基本思想是: 选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按此方法对这两部分数据分别进行快速排…...
SpringIOC之创建Bean的核心方法doGetBean
概述面向资源(XML、Properties)、面向注解定义的 Bean 是如何被解析成 BeanDefinition(Bean 的“前身”),并保存至 BeanDefinitionRegistry 注册中心里面,实际也是通过 ConcurrentHashMap 进行保存。Spring…...
docker快速部署xxjob2.3.0-SpringBoot快速集成示例
xxjob 2.3.0 部署 参考资料 docker安装xxl-job-admin步骤_JEECG低代码平台的技术博客_51CTO博客 run前准备 1 新建数据库 xxl_job 2 建表sql(可以直接使) https://github.com/xuxueli/xxl-job/blob/master/doc/db/tables_xxl_job.sql建库sql # # XXL-JOB v2.4.0-SNAPSHOT…...
项目管理的前路,前辈能给一些意见吗?
什么是项目管理?关于项目管理的解释主要是基于国际项目管理三大体系不同的解释及本领域权威专家的解释!!!! 项目管理就是以项目为对象的系统管理方法,通过一个临时性的、专门的柔性组织,对项目进行高效率的计划、组织、指导和控制,…...
省钱的年轻人,钱包被折扣店钻了空子
【潮汐商业评论/原创】过年期间,除了商场超市,小区附近的折扣店成了Amy经常光顾的对象。用Amy的话来说,“跟附近超市比价格,跟大卖场比距离,综合下来折扣店就是我随时购物的不二选择。”从Amy的话里,我们可…...
【华为OD机试真题 js、python】优选核酸检测点、寻找核酸检测点【2022 Q4 100分】
代码请进行一定修改后使用,提供有js、python两种语言 题目描述 张三要去外地出差,需要做核酸,需要在指定时间点前做完核酸,请帮他找到满足条件的 核酸检测只点。 给出一组核酸检测点的距离和每个核酸检测点当前的人数给出张三要去做核酸的出发时间 出发时间是10分钟的倍数…...
【MySQL】MySQL 8.0 新特性之 - 公用表表达式(CTE)
MySQL 8.0 新特性之 - 公用表表达式(CTE)1. 公用表表达式(CTE) - WITH 介绍1.1 公用表表表达式1.1.1 什么是公用表表达式1.1.2 CTE 语法1.1.3 CTE示例1.3 递归 CTE1.3.1 递归 CTE 简介1.3.2 递归成员限制1.3.3 递归 CTE 示例1.3.4…...
基础面试题:C++中如何理解const修饰符
面试题目:1、题 int i10; const int*p &i; int *const* p &i; const在不同位置有什么不 同 2、const 修饰类成员变量是有什么特殊要求 3、const 修饰类成员函数会发什么 4、const 对象有什么意义 目录 前言 一、const的意义 二、const使用规则 1.初始化…...
在RT-Thread STM32F407平台下配置SPI flash为U盘
记录下SPI Flash U盘实现过程中踩过的坑,与您分享。前提条件是,需要先将SPI Flash 配置到elm fal文件系统,并挂载成功。如下图然后开始配置USB1,在CubeMX,选择SUB_OTG_FS2 选择USB Device3,确认USB时钟为48…...
数据存储技术复习(二)未完
module3存储是数据中心内的核心元素。请说明常用的存储选项及其特点。磁盘驱动器:具有很大的存储容量,随机读/写访问闪存驱动器:使用半导体介质,提供高性能,低功耗2.若某磁盘驱动器显示每个磁道有八个扇区&…...
使用 QuTrunk+Amazon Deep Learning AMI(TensorFlow2)构建量子神经网络
量子神经网络是基于量子力学原理的计算神经网络模型。1995年,Subhash Kak 和 Ron Chrisley 独立发表了关于量子神经计算的第一个想法,他们致力于量子思维理论,认为量子效应在认知功能中起作用。然而,量子神经网络的典型研究涉及将…...
python selenium浏览器复用技术
使用selenium 做web自动化的时候,经常会遇到这样一种需求,是否可以在已经打开的浏览器基础上继续运行自动化脚本? 这样前面的验证码登录可以手工点过去,后面页面使用脚本继续执行,这样可以解决很大的一个痛点。 命令行…...
第二章:创建虚拟机
创建Windows server:首先第一步就是打开我们的vm,然后找到上一章讲的主页图标创建新的虚拟机。点击这上面类似的,然后转站。博文地址:https://blog.csdn.net/ryduijftgvhj/article/details/127934939?spm1001.2014.3001.5502视频…...
码上【call,apply,bind】的手写
一、call (1)官方用法 call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。 语法:function.call(要绑定的this值,参数,参数,…)。不一定这些参数都需要,这些参数都…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
