【crash】浮点除0堆损坏

news/2024/11/23 2:35:01/
  • 摘要:工作中遇到一个crash,其现象真实的crash原因差别比较大,和我自身原本了解的只是冲突,因此在本片文档中简单描述下。
  • 关键字:除0、IEEE754

1 前情提要

  QA测试过程发现一个比较奇怪的crash,只会在特定机型特定素材上出现,而且出现crash的位置也比较诡异,具体堆栈如下:

0xxxxxxx split_buffer::construct_at_end
0xxxxxxx XXX::doProcess

  crash的具体原因是除0。

2 排查

  首先就是根据上面的堆栈分析可能crash的原因,因为是在vector在已经分配的内存上创建对象时崩溃,我们基本可以断定,这个vector的内存出现了问题。然后就去看代码排查调用链中可能导致堆损坏的地方(因为开发机无法复现,因此只能通过分析+日志来排查),在排查代码过程中发现了几处可能越界的操作以及除0。因为是堆损坏就朝着越界的方向去排查了,但是加了新的日志之后发现可能存在越界的代码实际上没有越界,而且实际崩溃的地方大概如下:

std::sort(vec.begin(), vec.end(), [](const bbox& a, const bbox& b){ return a.p > b.p;   //崩溃的地方
});

  具体崩溃是在访问a时出现的,此时就有点儿匪夷所思了,崩溃堆栈是construct_at_end这个只有需要在vector中新建元素才会调用的函数,但是std::sort只涉及元素的交换(因为对应的vector比较小只有20个元素)。
  然后在排查是通过日志发现vector中的元素一部分的pinf,比较反常,因此排查了该值的计算来源发现是有double除0。然后将该处加了check后就不会崩溃了。
  到现在为止崩溃的原因基本已经确定了,除0UB导致的问题。

3 具体原因

  我个人一直以为除0一定会出现除0异常,所以最初并没有怀疑此处,而简单测试发现:

  • int整型除0一定会崩溃;
  • double除0会得到inf。

在这里插入图片描述
  IEEE754规定了浮点除0运算的结果为+INF或者-INF,但是C++标准明确规定了该行为未定义的,使用可能会导致UB。实际测试过程中发现只有低版本的机器浮点除0是不支持的,而新机器无论是windows还是Mac浮点除0编译器只会报warning但是结果是INF不会出错。

在这里插入图片描述

  具体原因是,C++并不强制编译器实现IEEE 754标准,因为可能受限于硬件平台无法实现。所以上面问题的结论是:

  1. 整数除0,必现除0异常;
  2. 浮点除0,不同编译器不同硬件平台现象不同不具备可移植性,应该按照C++的标准描述,是UB行为:
    1. C标准附件F(IEC 60559/IEEE754)定义了浮点除0的结果;
    2. 如果硬件的FLU且编译器支持IEC 559,那浮点除0返回+inf/-inf都是符合预期的:
      1. clang和msvc针对该行为都会报warning,能够正常运行得到inf。

参考资料

  • Why does division by zero in IEEE754 standard results in Infinite value?
  • The behaviour of floating point division by zero
  • expr

http://www.ppmy.cn/news/901458.html

相关文章

51单片机的智能交通控制系统【含仿真+程序+演示视频带原理讲解】

51单片机的智能交通控制系统【含仿真程序演示视频带原理讲解】 1、系统概述2、核心功能3、仿真运行及功能演示4、程序代码 1、系统概述 该系统由AT89C51单片机、LED灯组、数码管组成。通过Protues对十字路口红绿灯控制逻辑进行了仿真。 每个路口包含了左转、右转、直行三条车道…

通达信,底峰形(买入信号之一)

OUT:1{从当前柱算起&#xff0c;需要5天的历史数据} AND REF(MAX(O,C),1) LLV(MAX(O,C),3) AND C>O AND REF(C,2) < REF(O,2) AND REF(ABS(C-O),2) > REF(ABS(C-O),1)*1.5{倒数&#xff0c;第二根的柱体很小} AND REF(C,3) > REF(C,2) AND REF(C,4) > REF(C,3)…

第十五章——友元、异常

友元 类并非只能拥有友元函数&#xff0c;也可以将类作为友元。在这种情况下&#xff0c;友元类的所有方法都可以访问原始类的私有成员和保护成员。因此尽管友元被授予从外部访问类的私有部分的权限&#xff0c;但它们并不与面向对象的编程思想相悖&#xff0c;相反提高了共有…

通达信,MACD底背离(买入信号之一)

SHORT:10;{三个可变参数&#xff0c;注意默认参数的修改} MID:7; LONG:20;DIF:EMA(CLOSE,SHORT)-EMA(CLOSE,LONG); DEA:EMA(DIF,MID); MACD:(DIF-DEA)*2;金叉:CROSS(DIF,DEA);周期:BARSLAST(金叉);{取得距离现在天数} 长度:周期1 NODRAW;{算上当天的这根柱} 条件一:C<REF(C,…

通达信服务器地址文件夹,通达信常用文件放置位置说明一览

通达信的指标模版保存在那个文件夹,如何迁移 在T0002文件夹里,PriCS.DAT是软件自带指标,PriGS.DAT是你的自定义指标。 自选股票T0002blocknewZXG.blk 自编公式T0002PriGS.DAT 自编模板T0002PriPack.DAT 系统设置(常用指标)T0002user.配置设置 通达信T0002blocknew中ZXG.blk这…

matlab 读取 通达信,Matlab 自动导入通达信板块文件

本文包括程序为作者原创。 通达信具有强大的板块处理能力&#xff0c;并且一些板块数据是动态更新的&#xff0c;做股票量化设计的时候&#xff0c;借助通达信的板块动态文件&#xff0c;取到事半功倍的效果&#xff0c;本文用实例说明如何利用通达信板块数据动态更新到自己的板…

怎样测试通达信软件,如何测试通达信指标成功率?

如何测试通达信指标成功率&#xff1f; 通达信作为一款功能齐全的免费软件肯定很多人使用&#xff0c;包括我&#xff0c;那么我们无论是朋友还是网上找到一款指标导入之后他具体的功能怎么样&#xff1f;实用性如何我们一时半刻单单用眼睛看是看不出来的&#xff0c;那么通达信…

如何用python获取通达信数据_Python读取通达信本地数据

一、介绍 python获取股票数据的方法很多,其中 Tushare 财经数据接口包很好用,当然,也可以通过通达信本地的数据获取,这样更为方便。 日线数据存在这路径下 D:\通达信\vipdoc\sh\lday(我的通达信安装目录是D盘) 接着我们需要的就是解析这些数据,在分别存为 csv 格式的数据就…