内存问题检测

news2024/9/21 18:47:18

内存检测方式

gcc/g++ 内存检测方式如下,添加一些编译标签:

  • -fsanitize=leak   检测内存泄漏。例如添加标签:-fsanitize=leak -g -O0
  • -fsanitize=address  检测内存越界。例如添加标签:-fsanitize=address -g -O2,优化级别开启 O2 也可以检测到
  • -fsanitize=undefined  检测未定义的行为,例如:使用未初始化的变量、除 0、空指针解引用等

编译完,代码跑起来后,回放录包,录包跑完后,可以按 ctrl c,会输出内存检测结果(对应的调用栈)到标准出错

【注意:这种检测方式是运行时检测,如果有些代码没有运行到,这些代码就检测不到,需要链接 asan 库,或者 export LD_PRELOAD=/lib/aarch64-linux-gnu/libasan.so.5:${LD_PRELOAD}】

使用这种方式,实际上已经帮助系统组解决了一些中间件的 coredump 问题、planning 的内存泄漏问题、perception 的内存越界问题,比较好用

其中,协助 rs_perception 杨代玉解决内存问题时,【内存越界|内存泄漏检测方法-CSDN博客】文档很好:

内存问题,出现过的 case

可能导致内存问题的原因(后续协助算法做内存问题检测时,新的 case 可以继续在下面加):

1. 释放了没有分配的内存,报错为:AddressSanitizer: attempting free on address which was not malloc()-ed

2. new 和 delete 不匹配,报错为:AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete)

new 分配一个数组,应该用 delete[] 去释放,而不是用 delete 释放

例如:auto output = std::shared_ptr(new float[num_obj * 9]);
应该改为:
auto output = std::shared_ptr(new float[num_obj * 9], [](float* p) { delete[] p; });

3. 内存越界,报错为:AddressSanitizer: heap-buffer-overflow on address 或者 AddressSanitizer: stack-buffer-overflow on address

例如:使用 for(int i = 1; i < 4; ++i) 去遍历修改数组中的对象,数组长度为 3 的话,会存在内存越界问题

4. 内存泄漏,报错为:LeakSanitizer: detected memory leaks

  • 忘记释放内存
  • 存在循环引用问题。例如伪代码如下:

    struct A {

        std::shared_ptr<struct A> sa;

        std::shared_ptr<struct A> sb;

    }

    struct B {

        std::shared_ptr<struct A> sa;

        std::shared_ptr<struct B> sb;

    }

    int main () {

        shared_ptr<A> pa(new A());

        pa->sa = pa;  // 案例一:循环引用,自己的成员指向自己,出现循环引用。释放时,无法释放 pa

        shared_ptr<B> pb(new B());

        pa->sb = pb;  // 案例二:pa->sb 指向 pb,pb->sa 指向 pa,出现循环引用。释放时,会导致 pa 和 pb 都无法释放

        pb->sa = pa;

        return 0;

    }

5. 第三方库内存 bug

如下 pcl 库的 bug,升级到 pcl1.9 可解决

==9889==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x007f6ab4eeb8 at pc 0x007f9b129370 bp 0x007c3bdf3940 sp 0x007c3bdf3960

READ of size 8 at 0x007f6ab4eeb8 thread T36

==9889==AddressSanitizer: while reporting a bug found another one. Ignoring.

    #0 0x7f9b12936f in Eigen::internal::handmade_aligned_free(void*) /usr/include/eigen3/Eigen/src/Core/util/Memory.h:118

    #1 0x7f9b12936f in Eigen::internal::aligned_free(void*) /usr/include/eigen3/Eigen/src/Core/util/Memory.h:206

    #2 0x7f9b12936f in void Eigen::internal::conditional_aligned_free<true>(void*) /usr/include/eigen3/Eigen/src/Core/util/Memory.h:259

    #3 0x7f9b12936f in void Eigen::internal::conditional_aligned_delete_auto<floattrue>(float*, unsigned long) /usr/include/eigen3/Eigen/src/Core/util/Memory.h:446

    #4 0x7f9b12936f in Eigen::DenseStorage<float, -1, -1, -10>::~DenseStorage() /usr/include/eigen3/Eigen/src/Core/DenseStorage.h:415

    #5 0x7f9b12936f in Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -10, -1, -1> >::~PlainObjectBase() /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:98

    #6 0x7f9b12936f in Eigen::Matrix<float, -1, -10, -1, -1>::~Matrix() /usr/include/eigen3/Eigen/src/Core/Matrix.h:178

    #7 0x7f9b12936f in void Eigen::internal::call_assignment<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const>, Eigen::internal::assign_op<floatfloat> >(Eigen::Matrix<float, -1, -10, -1, -1>&, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0constconst&, Eigen::internal::assign_op<floatfloatconst&, Eigen::internal::enable_if<Eigen::internal::evaluator_assume_aliasing<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const>, Eigen::internal::evaluator_traits<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const> >::Shape>::value, void*>::type) /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:840

    #8 0x7f9b12936f in void Eigen::internal::call_assignment<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const> >(Eigen::Matrix<float, -1, -10, -1, -1>&, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0constconst&) /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:826

    #9 0x7f9b12936f in Eigen::Matrix<float, -1, -10, -1, -1>& Eigen::PlainObjectBase<Eigen::Matrix<float, -1, -10, -1, -1> >::_set<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const> >(Eigen::DenseBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const> > const&) /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:779

    #10 0x7f9b12936f in Eigen::Matrix<float, -1, -10, -1, -1>& Eigen::Matrix<float, -1, -10, -1, -1>::operator=<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const> >(Eigen::DenseBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<floatfloat>, Eigen::Matrix<float, -1, -10, -1, -1const, Eigen::Product<Eigen::Product<Eigen::Matrix<float, -1, -10, -1, -1>, Eigen::Matrix<float, -1, -10, -1, -1>, 0>, Eigen::Matrix<float, -1, -10, -1, -1>, 0const> > const&) /usr/include/eigen3/Eigen/src/Core/Matrix.h:225

    #11 0x7f9b12936f in robosense::KalmanFilter::update(Eigen::Matrix<float, -110, -11>&) /home/mogo/data/yangdaiyu/perception_ws/src/perception/lidar/robosense/modules/perception/lidar/tracking/src/filter/kalman_filter.cpp:137

6. coredump 文件,用 gdb 看到堆栈被踩坏,报错为:previous frame identical to this frame(corrupt stack?)

此时通过 gdb 看到的堆栈不一定是踩坏内存的堆栈,

栈是从高到低分配的,入栈时,sp 指针向低地址移动。假如在栈 #10 分配一个 int arr[100]。如果内存越界,例如执行了 arr[10000] = 123, 此时,10000 是高地址位,是有可能把栈踩坏的。踩坏时,不一定导致 coredump,程序继续运行,直到运行时报错,此时再看 coredump 文件,堆栈已经不是把内存踩坏时的堆栈了。

解问题方法:

    使用-fsanitize=address ,然后回放录包检测

    可以用反汇编看看,是不是把一些全局变量踩坏了,例如 futex

内存越界 demo

cat main.cpp

#include <stdio.h>

#include <string.h>

void fun(int n)

{

    printf("The %d step begin.\n", n);

    int a[10];

    for (int i = 0; i< n; i++) {

        a[i] = i;

    }

    if (n < 20) {

        fun(n +1);

    }

    printf("The %d step end\n", n);

}

int main(void)

{

    fun(8);

    return 0;

}

$ g++ main.cpp -o main -fsanitize=address -g -O2

$ ./main

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

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

相关文章

ThreadLocal详解及ThreadLocal源码分析

提示&#xff1a;ThreadLocal详解、ThreadLocal与synchronized的区别、ThreadLocal的优势、ThreadLocal的内部结构、ThreadLocalMap源码分析、ThreadLocal导致内存泄漏的原因、要避免内存泄漏可以用哪些方式、ThreadLocal怎么解决Hash冲突问题、避免共享的设计模式、ThreadLoca…

Android DexOpt七种触发流程解析【原创硬核】

Android 13 DexOpt七种触发流程解析 众所周知&#xff0c;DexOpt是安卓应用性能优化非常重要的手段&#xff0c;相当于将应用对虚拟机的多层调用直接转化成了arm机器码。Dex优化过和没优化过&#xff0c;效果千差万别。本文深入解析android系统DexOpt机制的触发流程。 1 DexOpt…

如何学习自动化测试工具!

要学习和掌握自动化测试工具的使用方法&#xff0c;可以按照以下步骤进行&#xff1a; 一、明确学习目标 首先&#xff0c;需要明确你想要学习哪种自动化测试工具。自动化测试工具种类繁多&#xff0c;包括但不限于Selenium、Appium、JMeter、Postman、Robot Framework等&…

安全编程的代码示例

一、python代码示例 一个安全编程的示例是对输入进行严格的验证和过滤。比如&#xff0c;当用户在网页上输入用户名和密码时&#xff0c;应该对这些输入进行验证&#xff0c;防止恶意用户输入恶意代码或进行 SQL 注入等攻击。下面是一个简单的示例代码&#xff1a; import…

OpenFeign微服务调用组件

一、跨服务、跨进程调用方式 1)Httpclient 使用Httpclient我们首先需要引入依赖 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </depend…

Meta/东京电子/FPT软件等共同贡献,Aitomatic发布首个半导体行业开源大模型,「锁死」企业技术自主权

2024 年初&#xff0c;研究机构 Market.us 发布报告预测&#xff0c;全球半导体市场规模将大幅增长&#xff0c;预计 2024 年可达到 6,731 亿美元&#xff0c;到 2032 年预计将增长至 1.3 万亿美元。 毫无疑问&#xff0c;这个万亿级市场与充满想象空间的 AI 密不可分。技术层…

【根号分治】 通知

通知 分析&#xff1a; 这道题根号分治看起来就没有前面几题那么明显了 emm当然也可能是我境界还没到 我们考虑如果暴力修改&#xff0c;复杂度是 O ( n m ) O(nm) O(nm)&#xff0c;其实m为这个点的度数 考虑根号分治的思想&#xff0c;我们令 m M m\sqrt M mM ​ 并命度数大…

申瓯通信设备有限公司在线录音管理系统(复现过程)

漏洞简介 申瓯通信设备有限公司在线录音管理系统 index.php接口处存在任意文件读取漏洞&#xff0c;恶意攻击者可能利用该漏洞读取服务器上的敏感文件&#xff0c;例如客户记录、财务数据或源代码&#xff0c;导致数据泄露 一.复现过程 fofa搜索语句:title"在线录音管…

idea显示properties文件中文乱码的解决方法

1.如下 File-》Settings-》File Encodings,修改如下图中绿框标注的内容 2.点击Apply-->OK 3.修改完成后显示

ROS八股

目录 一、ros1和ros2的区别是什么&#xff1f; 二、rostopic 和 rosserver的区别是什么&#xff1f; 三、讲一下ros的navigation框架 一、ros1和ros2的区别是什么&#xff1f; ROS 1和ROS 2是两个主要版本的机器人操作系统&#xff0c;它们在多个方面存在显著差异&#xff…

【Stable Diffusion】(基础篇七)—— lora

lora 本系列博客笔记主要参考B站nenly同学的视频教程&#xff0c;传送门&#xff1a;B站第一套系统的AI绘画课&#xff01;零基础学会Stable Diffusion&#xff0c;这绝对是你看过的最容易上手的AI绘画教程 | SD WebUI 保姆级攻略_哔哩哔哩_bilibili 除了大模型和VAE之外&…

MySQL:集合运算符

集合运算符 MySQL中的 集合运算符&#xff08;Set operators&#xff09;主要用于结合两个或多个SELECT语句的结果集&#xff0c;这些结果集应该具有相同的列数和数据类型&#xff0c;以便能够进行比较或合并。 需要注意的是&#xff0c;MySQL本身并没有直接称为“Set operat…

Flask目录结构路由重定向简单实例讲解——轻量级的 Python Web 框架

假设一个flask目录结构如下&#xff1a; my_flask_app/ │ ├── app.py ├── routes/ │ ├── __init__.py │ ├── ZhejiangProvince/ │ │ ├── __init__.py │ │ ├── la.py │ │ └── el.py │ ├── GuangdongProvince/ │ │ ├…

常见服务限流方法

一、令牌桶算法&#xff08;Token Bucket&#xff09; 原理其实很简单&#xff0c;就是设置同一时刻服务器能处理请求的最大数量&#xff0c;如果超过这个数据&#xff0c;则需要等待&#xff0c;或者不处理请求。相当于设置最大并发量&#xff0c;但是细节是&#xff0c;还设…

解决nginx端口转发后,获取不到真实IP问题

文章目录 1&#xff0c;设置nginx端口转发1.2&#xff0c;无法获取客户端真实IP 2&#xff0c;nginx配置文件增加配置&#xff0c;保留客户端信息2.2&#xff0c;可以看到真实IP信息 1&#xff0c;设置nginx端口转发 location /AWAPI/ {proxy_pass http://172.28.43.19:9607; …

组件化开发

1.组件化开发 组件化&#xff1a;一个页面可以拆分成一个个组件&#xff0c;每个组件有着自己独立的结构[html]、样式[css]、行为 [js]。好处&#xff1a;便于维护&#xff0c;利于复用 → 提升开发效率。组件分类&#xff1a;普通组件、根组件。比如&#xff1a;下面这个页面…

二级MySQL(十二)——分组聚合查询

首先整理常用的聚合函数&#xff1a; 函数名说明COUNT&#xff08;*&#xff09;记录数COUNT&#xff08;列名&#xff09;一列的记录数MAX&#xff08;列名&#xff09;一列的最大值 MIN&#xff08;列名&#xff09; 一列的最小值 SUM&#xff08;列名&#xff09;一列…

M12电连接器航插插座L-code

M12电连接器概述 M12电连接器是一种广泛应用于工业自动化、传感器、仪器仪表、数据通信和控制系统等领域的圆形连接器。它的核心特点在于其小巧的尺寸、强大的多信号传输能力和出色的防水性能&#xff0c;使其成为众多工业应用的首选。M12连接器通常具有3至12个引脚&#xff0…

redis主从复制、哨兵模式、集群

redis集群 高可用 redis集群的三种模式&#xff1a; 1.主从复制&#xff08;奇书 3台 一主两从&#xff09; 2.哨兵模式 &#xff08;3台 一主两从&#xff09; 3.cluster &#xff08;集群 6 333&#xff09; 主从复制&#xff1a;喝MySQL的主从复制类似&#xff0c;主可以写…