常见的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值,参数,参数,…)。不一定这些参数都需要,这些参数都…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
