C++(Qt)软件调试---内存分析工具Heob(26)
C++(Qt)软件调试—内存分析工具Heob(26)
文章目录
- C++(Qt)软件调试---内存分析工具Heob(26)
- @[toc]
- 1、概述🐜
- 2、环境配置🪲
- 3、功能说明
- 4、使用Heob分析qt 程序内存泄漏🦧
- 5、使用Heob检测qt 程序野指针/内存越界👓
- 6、使用Heob检测qt 程序空指针/throw抛出异常👕
- 7、使用Heob检测qt 程序重复释放👗
- 8、使用Heob检测qt 程序长生命周期式内存泄漏👙
- 9、相关地址🐐
文章目录
- C++(Qt)软件调试---内存分析工具Heob(26)
- @[toc]
- 1、概述🐜
- 2、环境配置🪲
- 3、功能说明
- 4、使用Heob分析qt 程序内存泄漏🦧
- 5、使用Heob检测qt 程序野指针/内存越界👓
- 6、使用Heob检测qt 程序空指针/throw抛出异常👕
- 7、使用Heob检测qt 程序重复释放👗
- 8、使用Heob检测qt 程序长生命周期式内存泄漏👙
- 9、相关地址🐐
更多精彩内容 |
---|
👉内容导航 👈 |
👉C++软件调试 👈 |
1、概述🐜
绝大部分的文章都说Heob是一个内存泄漏分析工具,其实Heob只是内存泄漏分析功能比较突出,实际上Heob可以分析很多内存问题。
Heob是一个Windows下检测缓冲区溢出(野指针、空指针、内存越界、重复释放、异常捕获等)和内存泄漏的工具,集成到Qt Creator中,功能强大,简单容易上手。
支持MSVC和MinGW编译器编译的程序内存泄漏检测;
支持32位和64位程序;
不支持Linux;
支持设置过滤内存泄漏字节大小;
支持异常处理;
支持与Qt调试器、事后调试器联动;
支持将分析结果导出位xml文件,后续通过加载xml文件查看分析结果;
Qt Creator支持4.6以上版本,低版本没有这个功能,可以自行安装高版本的QtCreator(注意:不是Qt版本,是IDE版本)。
处理速度块,占用资源少。
在Qt中使用Heob分析内存泄漏有4种用法:
方法1: 使用Heob分析MSVC编译生成的程序,对于 PDB 调试信息,使用 dbghelp.dll,速度块;
方法2: 使用Heob分析MinGW编译生成的程序, 对于DWARF 调试信息 (gcc) ,需要下载dwarfstack.dll库到Heob路径下才可以使用,性能会低很多;
- 方法3: 使用Heob分析MinGW编译生成的程序,通过cv2pdb将DWARF 转成PDB进行分析,性能和分析MSVC编译的程序差不多。
- 方法4: 命令行运行。
注意:
- MSVC版本<=2017时,Heob检测会出现误报,将内存泄漏包位外部错误的内存泄漏,所以如果使用的编译器版本比较低,过滤设置时就需要勾选上外部错误 项;
- 对MinGW和MSVC支持不同,有些情况使用MSVC编译器可以检测出来,使用MinGW检测不出来,有些情况相反。
- 运行Heob前需要保证代码已经完成编译并生成了可执行程序。
演示环境:
环境 | 版本 |
---|---|
系统 | Windows11 |
开发环境 | Qt5.9、Qt5.12.12、Qt5.14.2、Qt6.8 |
IDE | Qt Creator 5、Qt Creator 10、Qt Creator 14、Qt Creator 15 |
编译器 | mingw730_64、mingw1310_64、MSVC2015-64、MSVC2017-64、MSVC2022-64 |
分析工具 | Heob 4.0 |
依赖库 | dwarfstack 2.2 |
2、环境配置🪲
-
下载Heob 4.0和dwarfstack 2.2 解压到同一个文件夹中;
-
打开Qt Creator,选中【分析】【Heob】;
-
打开Heob窗口后点击【浏览】选择Heob路径,然后点击右下角图标保存配置。
-
创建一个Qt工程,测试代码如下所示
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}class Test
{
public:Test(){p = new int;}private:int* p;
};/*** @brief 内存泄漏1*/
void Widget::on_pushButton_clicked()
{Test* test = new Test();free(test);
}void fun()
{for(int i = 0; i < 1024; i++){int*p = new int[1000];qDebug() << p[1];}
}
/*** @brief 内存泄漏2*/
void Widget::on_pushButton_2_clicked()
{fun();
}/*** @brief 野指针1*/
void Widget::on_pushButton_3_clicked()
{int* p = new int;delete p;*p = 123;
}/*** @brief 野指针2*/
void Widget::on_pushButton_4_clicked()
{int* p;*p = 123;
}/*** @brief 空指针*/
void Widget::on_pushButton_5_clicked()
{int* p = nullptr;*p = 123;
}/*** @brief 内存越界*/
void Widget::on_pushButton_6_clicked()
{int*p = new int[12];p[123] = 123;p[12] = 1234;delete[] p;
}/*** @brief 重复释放*/
void Widget::on_pushButton_7_clicked()
{int*p = new int[12];p[1] = 123;delete[] p;delete[] p;
}/*** @brief 抛出异常*/
void Widget::on_pushButton_8_clicked()
{throw 123;
}/*** @brief 成员数组添加数据*/
void Widget::on_pushButton_9_clicked()
{for(int i = 0; i < 10000; i++){m_list.append(new int);qDebug() << i;}
}QList<int*> g_list;
/*** @brief 全局数组添加数据*/
void Widget::on_pushButton_10_clicked()
{for(int i = 0; i < 10000; i++){g_list.append(new int);qDebug() << i;}
}/*** @brief 释放内存*/
void Widget::on_pushButton_11_clicked()
{for(int i = 0; i < m_list.count(); i++){delete m_list[i];}for(int i = 0; i < g_list.count(); i++){delete g_list[i];}m_list.clear();g_list.clear();QMessageBox::about(this, "注意!", QString("已经释放内存:%1 %2").arg(m_list.count()).arg(g_list.count()));
}
3、功能说明
- 详细功能说明可以打开命令行,使用
heob.exe -H
命令查看;
如图所示:
-
点击【新建/删除】可以创建新的配置文件;
-
点击右下角软盘图标可以保存配置,配置文件保存在
C:\Users\MHF\AppData\Roaming\QtProject\QtCreator.ini
文件中; -
点击【OK】开始进行分析。
-
Heob Path: 下载解压的Heob.exe文件路径;
-
XML output file: 生成的xml文件名称,使用的相对路径,在可执行程序路径下,后续可通过【调试】窗口中的文件夹图标加载生成的xml文件;
-
Handle exceptions: 设置出现异常时的处理方式
- 设置为On则使用Heob处理,出现异常时程序退出,在调试窗口显示出现异常的信息;
- 设置为Off则在出现异常时,会使用事后调试器进行调试。
- 设置为Only则禁用所有Heob功能,除了安装异常处理程序。如果应用程序崩溃,则只显示崩溃的堆栈跟踪,不检测内存泄漏。因此,当在控制台上使用Heob或为子进程运行Heob时,此选项非常有用。
-
Run with debugger: 勾选上后会以Debug调试模式运行,当出现异常(例如空指针野指针)时会触发断点,定位到出现异常的位置;
- Raise breakpoint exception on error: 表示出现异常时触发断点,(主要用于重复释放)
- 如果没勾选,则出现重复释放、内存越界等问题时,不会触发异常断点,会将检测结果写入文件;
- 如果勾选上后,并且勾选了Run with debugger,则出现重复释放、内存越界等问题时,将会触发异常断点;
- Page protection: 这个功能更适合用于检测内存越界、野指针;
- 选择OFF时更适合检测内存泄漏;
- 选择After后会在分配的内存块末尾设置一个保护页,当访问到这个保护页时就会触发异常,从而识别出野指针、内存越界;
- 选择Before则会再分配的内存块前设置一个保护页;
- 这个功能会消耗内存、降低检查速度,建议仅用于64位或短时间运行的程序。
- Freed memory protection: 这个功能会增加释放内存保护功能,已经释放的内存就不会再被使用,对于检测野指针、重复释放问题有用,但是会大量消耗内存。
- Leak details: 这个选项用于设置程序退出时融合处理收集到的内存泄漏数据,不同的设置影响分析结果和处理速度;
- None:表示不收集内存泄漏数据,所以退出时速度最快;
- Simple:表示将所有未释放的内存写入结果文件,速度最慢,生成的xml文件也最大,所有内存泄漏分析结果都会被记录为
16 bytes in 1 blocks are lost in loss record 196 of 209 (#2513)
,无法通过过滤器进行过滤; - Detect Leak Types:会记录所有确定的直接内存泄漏、间接内存泄漏到文件中,速度会快一些;
- Detect Leak Types (Show Reachable):除了记录所有确定的直接内存泄漏、间接内存泄漏到文件中,还会将可能存在内存泄漏的结果记录到文件中,可以通过过滤器中【可能的内存泄漏】选项过滤;
- Fuzzy Detect Leak Types:选择模糊检测泄漏类型来标记内存块,或者它们是否引用了任何地址。当使用一些自定义分配器(例如:ffmpeg的av_malloc())时,此选项很有用,检测结果最少,只保留最有可能内存泄漏的记录,速度快,生成的文件小;
- Detect Leak Types (Show Reachable) :与Fuzzy Detect Leak Types类似,不过会将其它的记录认为是可能存在的内存泄漏,也会记录到文件中,可以通过过滤器中【可能的内存泄漏】选项过滤。
- Minimum leak size: 设置记录内存泄漏的最小字节数,低于设置值的内存泄漏不会被记录;
-
Control leak recording: 控制记录内存泄漏的开关、记录时间段等,更加灵活的记录分析内存泄漏的功能(例如记一个数组不断添加堆内存数据,很长一段时间才会释放一次,这种就是特殊情况的内存泄漏,就可以通过n/f快捷键来控制检测);
- OFF:关闭终端,始终开启内存泄漏记录;
- On (Start Disabled):打开终端,Heob启动时不记录内存泄漏,可在终端中进行控制;
- On (Start Enabled):打开终端,Heob启动时就开始记录内存泄漏,并且可在终端中进行控制。
-
Extra arguments: 用于输入运行其它Heob参数,例如输入
-vleaks.svg
会将检测结果生成svg矢量图;- 更多Heob参数使用命令行
Heob64.exe -H
查看。
- 更多Heob参数使用命令行
4、使用Heob分析qt 程序内存泄漏🦧
-
打开测试代码,使用MSVC编译器、Debug模式进行编译,保留pdb符号表;
-
编译生成可执行程序;
-
点击【分析】【Heob】【OK】启动程序进行分析;
-
当程序运行后分别点击【泄漏1】【泄漏2】按键,然后退出程序,程序退出后会将分析结果生成位leaks.xml文件,并在调试窗口显示检测到的内存泄漏;
-
生成的检测结果会有许多动态库中的误报,可以点击调试窗口上的过滤图标,取消勾选【外部错误】项(如果MSVC版本<=2017则勾选外部错误);
-
检测结果如下所示,出现两个内存泄漏,大小分别是409600字节和16字节。
5、使用Heob检测qt 程序野指针/内存越界👓
- 打开Heob窗口;
- 将Page protection选为【After】或者【Before 】;
- 点击开始检测,运行野指针代码就可以成功捕获到野指针异常。
- 由于野指针、内存越界都是不可恢复的异常,所以检测到这类异常后会直接终止Heob。
6、使用Heob检测qt 程序空指针/throw抛出异常👕
- 打开Heob窗口;
- 使用默认设置;
- 点击开始检测,运行野指针代码就可以成功捕获到空指针、抛出异常。
- 由于空指针异常无法恢复,检测到后会终止Heob;
- 如果throw抛出异常后没有被try捕获,则会被Heob检测到,并触发终止,如果被try捕获,则Heob无法检测。
7、使用Heob检测qt 程序重复释放👗
- 打开Heob窗口;
- 勾选Raise breakpoint exception on error: 表示出现异常时触发断点,如果不勾选就只会保存到检测结果;
- 再勾选Run with debugger ,在出现重复释放异常时,就会触发断点,进入调试。
8、使用Heob检测qt 程序长生命周期式内存泄漏👙
这里的长生命周期式内存泄漏不同于普通内存泄漏使用new分配了而没有delete;
长生命周期内存泄漏指使用new分配了内存,过了很长时间才会delete,例如成员指针、全局变量、静态变量等;
这类内存泄漏会更加难以排查,也容易造成严重问题。
测试方法1: 无法检测到长生命周期内存泄漏
- 打开Heob进行检测;
- 点击按键,向成员数组中new大量变量;
- 过一段时间后再释放成员数组中的所有内存;
- 无法检测到出现内存泄漏;
测试方法1: 无法检测到长生命周期内存泄漏
-
打开Heob窗口;
-
如下图所示,选择Detect Leak Types(不必须),避免文件写入太多内存,检测大小设置为500字节(不必须),选择On(Start Disabled),在程序启动前不记录,在运行过程中通过终端命令行控制开始/结束记录的时机;
-
点击【OK】启动Heob;
-
程序运行后按下
n
键开始记录; -
然后在程序中分别给成员数组、全局数组分配内存;
-
在终端按下
f
键停止记录,并按下s
键将当前内存泄漏分析结果写入文件; -
然后点击按键释放数组分配的内存;
-
退出程序后就可以看见检测到的内存泄漏了。
9、相关地址🐐
- Heob
- 下载dwarfstack.dll
- 通过cv2pdb将DWARF 转成PDB
- Heob | Qt Creator Documentation
- Detect memory leaks with Heob | Qt Creator Documentation
相关文章:

C++(Qt)软件调试---内存分析工具Heob(26)
C(Qt)软件调试—内存分析工具Heob(26) 文章目录 C(Qt)软件调试---内存分析工具Heob(26)[toc]1、概述🐜2、环境配置🪲3、功能说明4、使用Heob分析qt 程序内存泄漏🦧5、使用Heob检测qt 程序野指针…...

Redis五大基本类型——String字符串命令详解(命令用法详解+思维导图详解)
目录 一、String字符串类型介绍 二、常见命令 1、SET 2、GET 3、MGET 4、MSET 使用MGET 和 使用多次GET的区别 5、DEL 6、SETNX SET、SET NX和SET XX执行流程 7、INCR 8、INCRBY 9、DECR 10、DECYBY 11、INCRBYFLOAT 12、APPEND 13、GETRANGE 14、SETRANGE …...

Flutter中的Material Theme完全指南:从入门到实战
Flutter作为一款热门的跨平台开发框架,其UI组件库Material Design深受开发者喜爱。本文将深入探讨Flutter Material Theme的使用,包括如何借助Material Theme Builder创建符合产品需求的主题风格。通过多个场景和代码实例,让你轻松掌握这一工…...
Python 第三方库 PyQt5 的安装
目录 前言 PyQt5安装 不同操作系统PyQt5安装 一、Windows 系统 二、macOS 系统 三、Linux 系统(以 Ubuntu 为例) 安装 PyQt5 可能会遇到的问题 一、环境相关问题 二、依赖问题 三、网络问题 四、安装工具问题 五、运行时问题 六、环境配置问…...

CSS基础也要进行模电实验
盒子阴影 圆角边框已经介绍过哩,现在先介绍一下盒子阴影的效果如何实现 CSS3中新增了盒子阴影,可以使用box-shadow属性为盒子添加阴影 这是固定的语法: text-shadow: h-shadow v-shadow blur color; 它有这些可选的值: 哦。 …...

贴代码框架PasteForm特性介绍之markdown和richtext
简介 PasteForm是贴代码推出的 “新一代CRUD” ,基于ABPvNext,目的是通过对Dto的特性的标注,从而实现管理端的统一UI,借助于配套的PasteBuilder代码生成器,你可以快速的为自己的项目构建后台管理端!目前管…...
3D Gaussian Splatting 代码层理解之Part3
最后,内容到达了高斯泼溅过程中最有趣的阶段:渲染!这一步可以说是最关键的,因为它决定了模型的真实性。然而,它也可能是最简单的。在本系列的Part 1和Part2,文章演示了如何将 Raw 3D椭球 转换为可渲染的格式,但现在我们实际上必须完成这项工作并渲染到一组固定的像素上。…...
Ceph 中PG与PGP的概述
在Ceph分布式存储系统中,PG(Placement Group)和PGP(Placement Group for Placement purpose)是两个至关重要的概念,它们共同决定了数据在集群中的分布和复制方式。以下是关于Ceph中PG和PGP关系的详细解释&a…...

已解决:spark代码中sqlContext.createDataframe空指针异常
这段代码是使用local模式运行spark代码。但是在获取了spark.sqlContext之后,用sqlContext将rdd算子转换为Dataframe的时候报错空指针异常 Exception in thread "main" org.apache.spark.sql.AnalysisException: java.lang.RuntimeException: java.lang.Nu…...

flutter字体大小切换案例 小字体,标准字体,大字体,超大字体案例
flutter字体大小切换案例 小字体,标准字体,大字体,超大字体案例 Android iOS设备带有选择记录 我的flutter项目版本 environment: sdk: ‘>3.4.4 <4.0.0’ 图片案例 pubspec.yaml 添加依赖 # 屏幕尺寸适配 https://github.com/OpenF…...

智慧建造-运用Trimble技术将梦幻水族馆变为现实【上海沪敖3D】
项目概述 西雅图水族馆耗资1.6亿美元对海洋馆进行扩建。该项目包括建造三个大型栖息地,每个建筑物几乎都没有直边,其中一个主栖息地由520立方米混凝土和355吨钢筋组成。特纳建筑公司的混凝土团队通过强大的贸易合作伙伴和创新的数字制造技术,…...

【NOIP提高组】计算系数
【NOIP提高组】计算系数 C语言实现C实现Java实现Python实现 💐The Begin💐点点关注,收藏不迷路💐 给定一个多项式 (ax by)^k ,请求出多项式展开后 x^n y^m 项的系数。 输入 共一行,包含 5 个整数&#x…...

IDEA部署AI代写插件
前言 Hello大家好,当下是AI盛行的时代,好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风,然后写实什么的,现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…...

【阅读记录-章节1】Build a Large Language Model (From Scratch)
目录 1. Understanding large language models1.1 What is an LLM?补充介绍人工智能、机器学习和深度学习的关系机器学习 vs 深度学习传统机器学习 vs 深度学习(以垃圾邮件分类为例) 1.2 Applications of LLMs1.3 Stages of building and using LLMs1.4…...

微服务day08
Elasticsearch 需要安装elasticsearch和Kibana,应为Kibana中有一套控制台可以方便的进行操作。 安装elasticsearch 使用docker命令安装: docker run -d \ --name es \-e "ES_JAVA_OPTS-Xms512m -Xmx512m" \ //设置他的运行内存空间&#x…...
JAVA接入WebScoket行情接口
Java脚好用的库很多,开发效率一点不输Python。如果是日内策略,需要更实时的行情数据,不然策略滑点太大,容易跑偏结果。 之前爬行情网站提供的level1行情接口,实测平均更新延迟达到了6秒,超过10只股票并发请…...

使用Axios函数库进行网络请求的使用指南
目录 前言1. 什么是Axios2. Axios的引入方式2.1 通过CDN直接引入2.2 在模块化项目中引入 3. 使用Axios发送请求3.1 GET请求3.2 POST请求 4. Axios请求方式别名5. 使用Axios创建实例5.1 创建Axios实例5.2 使用实例发送请求 6. 使用async/await简化异步请求6.1 获取所有文章数据6…...

Vue2+ElementUI:用计算属性实现搜索框功能
前言: 本文代码使用vue2element UI。 输入框搜索的功能,可以在前端通过计算属性过滤实现,也可以调用后端写好的接口。本文介绍的是通过计算属性对表格数据实时过滤,后附完整代码,代码中提供的是死数据,可…...

抖音热门素材去哪找?优质抖音视频素材网站推荐!
是不是和我一样,刷抖音刷到停不下来?越来越多的朋友希望在抖音上创作出爆款视频,但苦于没有好素材。今天就来推荐几个超级实用的抖音视频素材网站,让你的视频内容立刻变得高大上!这篇满是干货,直接上重点&a…...
spring-cache concurrentHashMap 自定义过期时间
1.自定义实现缓存构建工厂 import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap;import lombok.Getter; import lombok.Setter; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...