使用asan检测内存泄漏、堆栈溢出等问题
创始人
2025-05-29 04:02:56
0

一、使用过程

  • 操作过程参考:链接
  • 缘起:程序在移动端崩溃,mac端复现不了,于是在写个崩溃位置函数的调用demo,使用ASAN工具进行排查。
  • 验证过程
    1、代码
    main.cpp
#include 
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"template
inline T fastMin(const T a, const T b) {return (a < b ? a : b);
}cv::Mat letterbox(const cv::Mat &src, const cv::Size &target_size, int stride = 32, bool hold_target = true,int resize_func = 0) {int ori_w = src.cols;int ori_h = src.rows;int tar_w = target_size.width;int tar_h = target_size.height;auto r = fastMin(float(tar_h) / float(ori_h), float(tar_w) / float(ori_w));int in_w = int(round(float(ori_w) * r));int in_h = int(round(float(ori_h) * r));int pad_w = tar_w - in_w;int pad_h = tar_h - in_h;if (!hold_target) {pad_w = pad_w % stride;pad_h = pad_h % stride;}cv::Mat resize_img;cv::resize(src, resize_img, cv::Size(in_w, in_h), 0, 0, resize_func);float nw = float(pad_w) / 2;float nh = float(pad_h) / 2;int top = int(round(nh - 0.1));int bottom = int(round(nh + 0.1));int left = int(round(nw - 0.1));int right = int(round(nw + 0.1));auto pad_color = cv::Scalar(114, 114, 114);cv::copyMakeBorder(resize_img, resize_img, top, bottom, left, right, cv::BORDER_CONSTANT, pad_color);return resize_img;
}void pre_process(unsigned char *image_rgba, cv::Mat &input, int img_height, int img_width) {cv::Size target;switch (0) {case 1:target = cv::Size(160,160);//cfg_.MID_DEVICE_INFER_SIZE, cfg_.MID_DEVICE_INFER_SIZE);break;case 2:target = cv::Size(120,120);//cfg_.LOW_DEVICE_INFER_SIZE, cfg_.LOW_DEVICE_INFER_SIZE);break;default://get model input h,wsize_t height_ = 320;//detector_helper_->GetInputHeight();size_t width_ = 320;//detector_helper_->GetInputWidth();target = cv::Size((int) width_, (int) height_);}bool hold_target = true;//(options_.coreML_mode ||options_.NPU_mode);if(hold_target){size_t height_ = 320;//detector_helper_->GetInputHeight();size_t width_ = 320;//detector_helper_->GetInputWidth();target = cv::Size((int) width_, (int) height_);}cv::Mat image = cv::Mat(img_height, img_width, CV_8UC4, image_rgba);input = letterbox(image, target, 32, hold_target,0);
}int main() {cv::Mat image_bgr = cv::imread("/root/Downloads/llp.png");cv::Mat imgrgba;cv::cvtColor(image_bgr, imgrgba, cv::COLOR_BGR2RGBA);int width = image_bgr.cols;int height = image_bgr.rows;cv::Mat input;pre_process(imgrgba.data, input, height, width);//letterbox(imgrgba, cv::Size(320, 320), 32, true,0);return 0;
}

使用附加ASAN工具的方式进行编译:

g++ main.cpp -o detectBug  -fsanitize=leak -g `pkg-config --cflags --libs opencv`

执行:

./detectBug

没有问题,以上是验证过程,如有问题执行时ASAN会提示有问题的相关位置。

二、ASAN资料

  • 介绍

首先,先介绍一下 Sanitizer 项目,该项目是谷歌出品的一个开源项目,该项目包含了 ASAN、LSAN、MSAN、TSAN等内存、线程错误的检测工具,这里简单介绍一下这几个工具的作用:

ASAN: 内存错误检测工具,在编译命令中添加-fsanitize=address启用

LSAN: 内存泄漏检测工具,已经集成到 ASAN 中,可以通过设置环境变量ASAN_OPTIONS=detect_leaks=0来关闭ASAN上的LSAN,也可以使用-fsanitize=leak编译选项代替-fsanitize=address来关闭ASAN的内存错误检测,只开启内存泄漏检查。

MSAN: 对程序中未初始化内存读取的检测工具,可以在编译命令中添加-fsanitize=memory -fPIE -pie启用,还可以添加-fsanitize-memory-track-origins选项来追溯到创建内存的位置

TSAN: 对线程间数据竞争的检测工具,在编译命令中添加-fsanitize=thread启用 其中ASAN就是我们今天要介绍的重头戏。

ASAN,全称 AddressSanitizer,可以用来检测内存问题,例如缓冲区溢出或对悬空指针的非法访问等。

根据谷歌的工程师介绍 ASAN 已经在 chromium 项目上检测出了300多个潜在的未知bug,而且在使用 ASAN 作为内存错误检测工具对程序性能损耗也是及其可观的。

根据检测结果显示可能导致性能降低2倍左右,比Valgrind(官方给的数据大概是降低10-50倍)快了一个数量级。

而且相比于Valgrind只能检查到堆内存的越界访问和悬空指针的访问,ASAN 不仅可以检测到堆内存的越界和悬空指针的访问,还能检测到栈和全局对象的越界访问。

这也是 ASAN 在众多内存检测工具的比较上出类拔萃的重要原因,基本上现在 C/C++ 项目都会使用ASAN来保证产品质量,尤其是大项目中更为需要。

  • 如何使用 ASAN

作为如此强大的神兵利器,自然是不会在程序员的战场上失宠的。

从LLVM3.1、GCC4.8、XCode7.0、MSVC16.9开始ASAN就已经成为众多主流编译器的内置工具了,因此,要在项目中使用ASAN也是十分方便。

现在只需要在编译命令中加上-fsanitize=address检测选项就可以让ASAN在你的项目中大展神通,接下来通过几个例子来看一下 ASAN 到底有哪些本领。

注意:

在下面的例子中打开了调试标志-g,这是因为当发现内存错误时调试符号可以帮助错误报告更准确的告知错误发生位置的堆栈信息,如果错误报告中的堆栈信息看起来不太正确,请尝试使用-fno-omit-frame-pointer来改善堆栈信息的生成情况。
如果构建代码时,编译和链接阶段分开执行,则必须在编译和链接阶段都添加-fsanitize=address选项。

检测内存泄漏

// leak.c
#include 
#include 
#include int main(int argc, const char *argv[]) {char *s = (char*)malloc(100);strcpy(s, "Hello world!");printf("string is: %s\n", s);return 0;
}

上述代码中我们分配了100个字节的内存空间,但在main函数返回前始终没有释放,接下来我们使用ASAN看一下是否能够检测出来,添加-fsanitize=address -g参数构建代码并执行:

~/Code/test$ gcc noleak.c -o noleak -fsanitize=address -g
~/Code/test$ ./leak 
string is: Hello world!=================================================================
==1621572==ERROR: LeakSanitizer: detected memory leaks    // 1)Direct leak of 100 byte(s) in 1 object(s) allocated from:   // 2)#0 0x7f5b986bc808 in __interceptor_malloc ../../../../src/libsanitizer/ASAN/ASAN_malloc_linux.cc:144#1 0x562d866b5225 in main /home/chenbing/Code/test/leak.c:7#2 0x7f5b983e1082 in __libc_start_main ../csu/libc-start.c:308SUMMARY: AddressSanitizer: 100 byte(s) leaked in 1 allocation(s).

这里,ASAN 提供的报告说明了错误原因是detected memory leaks内存泄漏了1),同时,2)说明ASAN检测到应用程序分配了100个字节,并捕获到了内存分配位置的堆栈信息,还告诉了我们内存是在leak.c:7分配的。

有了这么详细的且准确的错误报告,内存问题是不是不那么头疼了?

相关内容

热门资讯

玩转k8s(六)—— Heal... 用户可以利用Liveness和Readiness探测机制设置更精细的健康检查,进而实现...
财经大V走进广州,感受新质生产... 5月27日,由广州市自媒体协会主办的第四届湾区自媒体创新发展大会在广州鸣泉居酒店圆满举行。在互联网快...
华谊兄弟:从影视巨头到断臂求生... 近日,华谊兄弟董事长王忠军油画作品流拍事件引发市场热议——这幅曾以368万元高价成交的作品,如今30...
嵌入式学深度学习:1、Pyto... 嵌入式学深度学习:1、Pytorch框架搭建1、介绍2、Pytorch开发环境搭建2....
springcloud学习总结 springcloud 构建微服务项目步骤 导入依赖编写配置文件开启这个功能 @Enable...
刚刚,德勤中国官宣新CEO 德... 5月30日,德勤中国宣布,刘明华将接替曾顺福出任德勤中国首席执行官,自2025年6月1日起生效,任期...
React 执行架构流程详细-... React 执行架构流程详细----归阶段 mount 时流程(三) 目...
险资活水入市来 超1700亿元... 既有新的保险系私募证券基金管理人完成备案,也有新的保险系私募基金产品发起设立,还有险企宣布将设立私募...
石药集团:就三项潜在交易进行磋... 新京报贝壳财经讯 5月30日,石药集团在港交所公告,集团目前正与若干独立第三方就三项潜在交易进行磋商...
Spring学习(三) Spring的AOP的XML开发(重要指数五颗星*****) 一、AOP...
缓存穿透,缓存雪崩,缓存击穿 注:该文章基于黑马程序员中《黑马点评》软件的学习 视频链接 涉及视频 p40p42p4...
去年净利增五成,厦门国际银行遭... 来源:密探财经(ID:Spy Finance)刚刚,号称“中国第一家中外合资银行”的厦门国际银行被“...
石药集团:就三项潜在交易进行磋... 新京报贝壳财经讯 5月30日,石药集团在港交所公告,集团目前正与若干独立第三方就三项潜在交易进行磋商...
「开盘」A股三大股指集体低开,... A股三大股指5月30日集体低开。其中,沪指跌0.14%报3358.81点,深成指跌0.36%报100...
淘宝天猫消费者频频上当维权艰难... 文丨顾小白 编辑丨百进来源丨正经社(ID:zhengjingshe)(本文约为3100字)【正经社“...
哪吒汽车“债转股”失败,知情人... 据媒体5月29日报道,哪吒汽车上海总部外墙的“哪吒汽车”LOGO目前被拆除,一并被拆除的还有位于总部...
Struts2—Ognl 表达... 0x00 前言 补充一下Ognl表达式的相关的知识点。尽量调有用的知识点来进行记录。 Ognl&#x...
恒生指数开盘跌0.99%,恒生... 5月30日,恒生指数开盘跌0.99%,网易跌近4%领跌蓝筹,恒生科技指数跌1.26%。手回集团上市首...
昨日获资金净流入,科创板人工智... 5月30日,三大指数集体低开,科技方向震荡走低。截至发稿,上证科创板人工智能指数下跌1.69%。相关...
25. 在QWidget窗口中... 1. 说明: QML开发界面是最近才开始流行,在之前的老项目中一般都是使...