一、使用过程

  • 操作过程参考:链接
  • 缘起:程序在移动端崩溃,mac端复现不了,于是在写个崩溃位置函数的调用demo,使用ASAN工具进行排查。
  • 验证过程
    1、代码
    main.cpp
#include <string.h>
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"template<typename T>
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>(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 <stdio.h>
#include <stdlib.h>
#include <string.h>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分配的。

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

使用asan检测内存泄漏、堆栈溢出等问题相关推荐

  1. VC使用CRT调试功能来检测内存泄漏

    信息来源:csdn      C/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:"最大的长处也可能成为最大的弱点",那么 C/C++ 应用程序正好印证 ...

  2. 如何在linux下检测内存泄漏

    1.开发背景 在 windows 下使用 VC 编程时,我们通常需要 DEBUG 模式下运行程序,而后调试器将在退出程序时,打印出程序运行过程中在堆上分配而没有释放的内存信息,其中包括代码文件名.行号 ...

  3. VC++ 6.0 中如何使用 CRT 调试功能来检测内存泄漏[转]

    /C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:"最大的长处也可能成为最大的弱点",那么 C/C++ 应用程序正好印证了这句话.在 C/C++ 应用程 ...

  4. vs2008 使用Visual Leak Detector检测内存泄漏

    http://hi.baidu.com/maydaygmail/item/8ea6ebef87ca9103560f1dfe 转自:http://hi.baidu.com/sunchongjing/bl ...

  5. Qt Creator使用Heob检测内存泄漏

    Qt Creator使用Heob检测内存泄漏 使用Heob检测内存泄漏 指定Heob设置 记录结果 处理异常 在错误上引发异常 保护页面 处理泄漏数据 使用Heob检测内存泄漏 Qt Creator集 ...

  6. Qt Creator使用Memcheck检测内存泄漏

    Qt Creator使用Memcheck检测内存泄漏 使用Memcheck检测内存泄漏 选择内存分析选项 显示可达和间接丢失的块 抑制错误 使用Memcheck检测内存泄漏 您可以使用Valgrind ...

  7. 使用CRT调试功能来检测内存泄漏

    C/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:"最大的长处也可能成为最大的弱点",那么 C/C++ 应用程序正好印证了这句话.在 C/C++ 应用 ...

  8. unity如何检测内存泄漏_如何排查Java内存泄漏?看懂这一篇就够用了

    原文:https://www.toptal.com/java/hunting-memory-leaks-in-java 作者:Jose Ferreirade Souza Filho 译者:Emma来源 ...

  9. 使用 Visual Leak Detector 检测内存泄漏

    个人心得:挺不错,可以定位到指针所在文件,甚至是函数及行号.使用也挺方便. 感谢开源代码!http://vld.codeplex.com/ 转载自:http://www.51testing.com/? ...

最新文章

  1. 工作中常用,实用工具推荐!
  2. python怎么按键开始与停止_python 图形化开始与停止功能的实现
  3. 定时器和promise_分析 Promise 内部实现
  4. 《javascript 高级程序设计》 笔记1 1~7章
  5. 国内各地图API坐标系统比较与转换
  6. 一种将排序值换算为得分值的方法
  7. Java并发编程的艺术(一)并发编程的挑战
  8. go语言查询某个值是否在数组中_一日一技:在 Golang 中如何快速判断字符串是否在一个数组中...
  9. 【Morgan Stanley IKM在线测试】C++
  10. 蓝牙---AVRCP协议
  11. 谷歌地球 最新hosts_给我一个Google地球app,可以领略全球3D风情
  12. idea破解最新版本
  13. html返回的状态值,iradon函数返回的是什么值
  14. 爬取豆瓣电影排行版数据
  15. Lab3:自行车码表
  16. 住城中村的散装女主播
  17. java net包 网关_Net分布式系统之六:微服务之API网关
  18. MATLAB求分数阶微分的数值解,G-L定义,R-L定义,Caputo定义
  19. [SDOI2013] 淘金
  20. AI人工智能实践技术

热门文章

  1. 新视野大学英语(第三版)视听说4Unit7必修答案
  2. LearnOpenGL笔记->入门->变换与坐标系统
  3. Android Camera HAL3 -SessionParameter
  4. 纯国产的大佬周志华,如何扛起了智能学界的一面大旗
  5. 【基础知识】~ 竞争/冒险
  6. 去哪儿实习面经(拿到offer)
  7. 研读Joint Multi-modal Aspect-Sentiment Analysis with Auxiliary Cross-modal
  8. 可编程直流稳压电源如何保养维护?
  9. 微信插件第一讲之自动回复机器人(护妻宝)
  10. 数仓知识12:PostgreSQL预写日志(WAL)和逻辑解码方案