sanitizer工具集

sanitizer工具集sanitizer工具集的介绍Sanitizers是谷歌发起的开源工具集,包括了AddressSanitizer,undefinedbehaviorSanitizer,ThreadSanitizer,LeakSanitizer。GCC从4.8版本开始支持Addresssanitizer和ThreadSanitizer,4.9版本开始支持LeakSanitizer和undefinedbehaviorSanitizer。AddressSanitizer(ASAN):  也即地址

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

sanitizer工具集的介绍

Sanitizers是谷歌发起的开源工具集,包括了Address Sanitizer, undefined behavior Sanitizer, Thread Sanitizer, Leak Sanitizer。GCC从4.8版本开始支持Address sanitizer和Thread Sanitizer,4.9版本开始支持Leak Sanitizer和undefined behavior Sanitizer。

Address Sanitizer(ASAN):

也即地址消毒技术,通过编译插桩(CTI),能够发现此堆/栈/全局变量读写溢出,内存泄露等问题,并将信息直接打印到日志中。Address Sanitizer(ASan)是一个快速的内存错误检测工具。它非常快,只拖慢程序两倍左右(比起Valgrind快多了)。它包括一个编译器instrumentation模块和一个提供malloc()/free()替代项的运行时库。

Thread Sanitizer(TSan):

是一个检查线程Data Race的C/C++工具。

Leak Sanitizer(LSan):

检测内存的LeakSanitizer是集成在Address Sanitizer中的一个相对独立的工具,它工作在检查过程的最后阶段。

Undefiend Behavior Sanitizer(UBSan):

检测未定义行为(使用空指针、有符号整数溢出等)。

环境配置

QMake:

在pro文件中添加:

QMAKE_CXXFLAGS+="-fsanitize=undefined,address,leak -fno-omit-frame-pointer"
QMAKE_CFLAGS+="-fsanitize=undefined,address,leak -fno-omit-frame-pointer"
QMAKE_LFLAGS+="-fsanitize=undefined,address,leak -fno-omit-frame-pointer"

Jetbrains全家桶1年46,售后保障稳定

用-fsanitize=address选项,编译和链接你的程序。
用undefined,可以使用undefined behavior sanitizer检测未定义行为。
用leak,可以使用leak sanitizer检测内存泄露(很多平台默认关闭,x86架构下默认开启的)。
用-fno-omit-frame-pointer(与相对)编译,以得到更容易理解stack trace。
注:-fomit-frame-pointer是打开优化选项(-O1打开),与-fno-omit-frame-pointer相反,即在函数调用时不保存栈帧指针SFP,代价是不能通过backtrace进行调试根据堆栈信息了。

TSan环境配置:
主要用于检测多线程资源竞争的问题,但是该选项不能与-fsanitize=address、-fsanitize=leak组合。
在pro文件中添加:

QMAKE_CXXFLAGS+="-fsanitize=thread"<br>
QMAKE_CFLAGS+="-fsanitize=thread"<br>
QMAKE_LFLAGS+="-fsanitize=thread"<br>

CMake

在CMakeLists添加:

set(CMAKE_CXX_FLAGS "-fsanitize=undefined,address,leak -fno-omit-frame-pointer")
set(CMAKE_C_FLAGS "-fsanitize=undefined,address,leak -fno-omit-frame-pointer")
set(CMAKE_L_FLAGS "-fsanitize=undefined,address,leak -fno-omit-frame-pointer")

TSan环境配置:

set(CMAKE_CXX_FLAGS "-fsanitize=thread")
set(CMAKE_C_FLAGS "-fsanitize=thread")
set(CMAKE_L_FLAGS "-fsanitize=thread")

工作原理和使用方法

原理

Address Sanitizer替换了malloc和free的实现。当调用malloc函数时,它将分配指定大小的内存A,并将内存A周围的区域标记为”off-limits“。当free方法被调用时,内存A也被标记为”off-limits“,同时内存A被添加到隔离队列,这个操作将导致内存A无法再被重新malloc使用。
  当访问到被标记为”off-limits“的内存时,Address Sanitizer就会报告异常。
  
=== 错误类型 ===

  • Use after free  释放后使用
  • Heap buffer overflow 堆缓冲区溢出
  • Stack buffer overflow 栈缓冲区溢出
  • Global buffer overflow 全局缓冲区溢出
  • Use after return 返回后使用
  • Use after scope 作用域后使用
  • Initialization order bugs 初始化顺序错误
  • Memory leaks 内存泄露
  • Using misaligned or null pointer  使用未对齐的指针
  • Signed integer overflow  有符号整数溢出
  • Conversion to, from, or between floating-point types which would overflow the destination  和浮点数相关转换溢出
  • data race  数据竞争

错误示例:

==== Address Sanitizer ====

int main()	{ 
   
	int* array = new int[100];
	delete [] array;
	return array[1];
}

====16829 ====
ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000044 at pc 0x00000065b3ea bp 0x7fffffffe3a0 sp
0x7fffffffe398
· 第一部分(ERROR)指出错误类型是heap-use-after-free; READ of
size 4 at 0x614000000044 thread T0
#0 0x65b3e9 in main …/…/deepin-image-viewer/viewer/main.cpp:33
#1 0x7ffff4b2409a in __libc_start_main …/csu/libc-start.c:308
#2 0x440319 in _start (/data/home/shuwenzhi/workspace/sp2/build-deepin-image-viewer-unknown-Debug/viewer/deepin-image-viewer+0x440319)
· 第二部分(READ), 指出线程名thread T0,操作为READ,发生的位置是main.cpp:33。
libc_start_main()函数应执行执行环境的任何必要初始化,使用适当的参数调用main函数,并处理main()的返回。
0x614000000044 is located 4 bytes inside of 400-byte region
[0x614000000040,0x6140000001d0) freed by thread T0 here:
#0 0x7ffff72f3c40 in operator delete (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xebc40)
#1 0x65b3ab in main …/…/deepin-image-viewer/viewer/main.cpp:32
#2 0x7ffff4b2409a in __libc_start_main …/csu/libc-start.c:308 · 第二部分(freed), 该heap块之前已经在main.cpp:32被释放了; previously allocated by
thread T0 here:
#0 0x7ffff72f2ef0 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xeaef0)
#1 0x65b38b in main …/…/deepin-image-viewer/viewer/main.cpp:31
#2 0x7ffff4b2409a in __libc_start_main …/csu/libc-start.c:308 · 第二部分(allocated), 该heap块是在main.cpp:31分配。 SUMMARY: AddressSanitizer:
heap-use-after-free …/…/deepin-image-viewer/viewer/main.cpp:33 in
main · 第三部分 (SUMMARY) 前面输出的概要说明。

==== Undefined Behavior Sanitizer ====

void testsignoverflow()	{ 
   
	int k = 0x7fffffff;
	k += 2;
}

…/worktest/testaddress/main.cpp:11:7: runtime error: signed integer overflow: 2147483647 + 2 cannot be represented in type ‘int’ ·
超过int范围,不能用int表达。

==== Leak Sanitizer ====

void* p;
int main(){ 
   
	p = malloc(4);
	p = 0;
	return 0;
}

==7089 == ERROR: LeakSanitizer: detected memory leaks 错误类型:detected memory leaks。 Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f13b7aab330 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe9330)
#1 0x65b36b in main …/…/deepin-image-viewer/viewer/main.cpp:33
#2 0x7f13b52de09a in __libc_start_main …/csu/libc-start.c:308 内存在main.cpp:33分配。 SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1
allocation(s)。

==== Thread Sanitizer ====

int Global;
void *Thread1(void *x) { 
   
	Global++;
	return NULL;
}
void *Thread2(void *x) { 
   
	Global--;
	return NULL;
}
int main(){ 
   
	pthread_t t[2];
	pthread_create(&t[0], NULL, Thread1, NULL);
	pthread_create(&t[1], NULL, Thread2, NULL);
	pthread_join(t[0], NULL);
	pthread_join(t[1], NULL);
}

WARNING: ThreadSanitizer: data race (pid=26333)
· 错误类型:data
race
Read of size 4 at 0x000000408174 by thread T2:
#0
Thread2(void*) …/worktest/testaddress/main.cpp:47
(testaddress+0x403520)
#1 (libtsan.so.0+0x29b3d)

· 在线程T2读取4个字节,发生在main.cpp:47。
Previous write of size 4 at
0x000000408174 by thread T1:
#0 Thread1(void*)
…/worktest/testaddress/main.cpp:42 (testaddress+0x4034db)
#1
(libtsan.so.0+0x29b3d)
·
在线程T1读取4个字节,发生在main.cpp:42。
Location is global ‘Global’ of size 4
at 0x000000408174 (testaddress+0x000000408174)
Thread T2
(tid=26336, running) created by main thread at:
#0 pthread_create
(libtsan.so.0+0x2be1b)
#1 main
…/worktest/testaddress/main.cpp:74 (testaddress+0x403672)
Thread
T1 (tid=26335, finished) created by main thread at:
#0
pthread_create (libtsan.so.0+0x2be1b)
#1 main
…/worktest/testaddress/main.cpp:73 (testaddress+0x403651)

SUMMARY: ThreadSanitizer: data race
…/worktest/testaddress/main.cpp:47 in Thread2(void*)
·
线程T1、T2在主线程main.cpp的73和74行创建。

=== 使用建议 ===
ASAN、LSan、UBSan:
对可能出现内存泄露、访问越界、堆栈溢出,可以使用此三种工具同时检查,建议在每次提交代码之前,开启此三项检查,可以排除大部分常见错误,项目不大的话也可以配置到debug里。
Thread Sanitizer(TSan):
由于此工具会和其他工具组合冲突,建议在新增线程或者线程中可能出现data trace的情况下使用。例如:出现多线程的线程安全问题,可以开启此工具检查。
错误输出:
在正常的项目开发中,会有存有大量的日志信息输出到应用程序输出里,这样会加大查找错误信息的难度,因此建议在将sanitizer错误信息输出到日志里。

#include <sanitizer/asan_interface.h>
__sanitizer_set_report_path("asan.log")

在指定的目录会生成一个asan.log.pid(进程号)的文件。

总结

环境兼容

  • x86:可以正常使用。
  • 盘古V(wayland):错误信息不在应用程序输出里,而在编译输出里,有一个问题,编译输出错误信息后将错误代码删除,重新编译仍有错误信息。
  • 鲲鹏(arm):可以正常使用,与x86使用相同。
  • 龙芯(MIPS):不支持MIPS,缺少对应环境。

使用人员

  • 研发人员:由于使用sanitizer工具集需要代码编译,因此建议研发人员使用。
  • 测试人员:使用建议使用valgrind,详细使用请参照valgrind工具使用。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/219122.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 黑苹果完整安装教程,内含后续系统优化「建议收藏」

    黑苹果完整安装教程,内含后续系统优化「建议收藏」第一种安装:VM虚拟机这类主讲装双系统,VM虚拟机参考博客https://blog.csdn.net/doudou19930614/article/details/81407446虚拟机下载:http://www.epinv.com/post/10434.html第二种安装:双系统准备工具:1.镜像https://osx.cx/tag/原版镜像/或者度盘链接:https://p…

  • Angular 2 前端 http 传输 model 对象及其外键的问题

    Angular 2 前端 http 传输 model 对象及其外键的问题

    2021年11月24日
  • android 上手维修设备和推断启动服务

    android 上手维修设备和推断启动服务

  • CSS面试题

    CSS面试题1.有哪些方式(CSS)可以隐藏页面元素?1.opacity:0本质是将元素的透明度降为0,看起来是隐藏了,但是依然占据空间2.visibility:hidden占据空间3.display:none彻底隐藏元素,元素从文档流中消失,不占据空间4.z-index:-9999原理是将层级放到底部,看起来是隐藏了5.overflow:hidden这个只是隐藏元素溢出的部分6.transform:scale(0,0)将元素缩放为0,但是依然占据空间2.em\px\rem区别?Px:绝对

  • chrome加载慢_多线程有什么用

    chrome加载慢_多线程有什么用谷歌浏览器采用的是单线程下载,想要提高下载速度,就得采用多线程的下载方式,Chrome默认还是单线程下载,如果想要谷歌多线程下载,就要手动开启,下面听MacW小编娓娓道来,介绍如何开启Chrome多线程下载!先来看看开启前的下载速度,(同一个文件)看到了吧!默认情况下,只有左右,远没有到达带宽的上限,接下来跟着小编一起开启这个隐藏的功能,国产Chrome内核的浏览器通通适用,包括前段时间推送的新版Edge也可以。chrome://flags/#enable-parallel-downloading

  • servlet异步请求

    servlet异步请求1、什么是servlet异步请求Servlet3.0之前,一个普通Servlet的主要工作流程大致如下:(1)、Servlet接收到请求之后,可能需要对请求携带的数据进行一些预处理;(2)、调用业务接口的某些方法,以完成业务处理;(3)、根据处理的结果提交响应,Servlet线程结束。其中第二步处理业务逻辑时候很可以碰到比较耗时的任务,此时servlet主线程会阻塞等待完成业务处理,对于并发比较大的请求可能会产生性能瓶颈,则servlet3.0之后再此处做了调整,引入了…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号