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)


相关推荐

  • elk查询语法_elk配置

    elk查询语法_elk配置记录了ElasticSearch、Logstash和Kibana的简单安装方法和ES的常用查询操作命令,Logstash还未整理,去官网查比较全。ElasticSearch安装#下载安装包wgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.2.1-linux-x86_64.tar.gz#解压修改文件夹名tar-zxvfelasticsearch-7.2.1-linux-x86_

    2022年10月30日
  • 【idea】推荐一个idea翻译插件:Translation「建议收藏」

    【idea】推荐一个idea翻译插件:Translation「建议收藏」打开settings-plugins,打开Browserepositories(如图):搜索”Translation”,往下找,找到图中插件install即可(我是已经安装了的)我的插件版本现在是支持谷歌、有道、百度三种翻译,其中有道和百度的需要填写应用id及secret等才能用,这个需要到有道智云(百度的没有试过)申请。使用很简单:选中单词或者段落ctrl+shift+…

  • tabnine激活(JetBrains全家桶)「建议收藏」

    (tabnine激活)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html4M7HSKPBXS-eyJsaWN…

  • service mesh框架对比_k8s外部访问内部service

    service mesh框架对比_k8s外部访问内部serviceservice用于4层路由负载 ingress用于7层路由负载1 Service介绍在kubernetes中,Pod是应用程序的载体,我们可以通过Pod的IP来访问应用程序,但是Pod的IP地址不是固定的,这就意味着不方便直接采用Pod的IP对服务进行访问。为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个Pod进行聚合,并且提供一个统一的入口地址,通过访问Service的入口地址就能访问到后面的Pod服务。Service在很多情况下只是一个概念

  • python strip()函数

    python strip()函数函数原型声明:s为字符串,rm为要删除的字符序列s.strip(rm)删除s字符串中开头、结尾处,位于rm删除序列的字符s.lstrip(rm)删除s字符串中开头处,位于rm删除序列的字符s.rs

  • eclipse搭建安卓开发环境

    eclipse搭建安卓开发环境总结起来,Android开发环境搭建可以分为以下四步:第一步、安装JDK;第二步、安装Eclipse;第三步、下载并安装AndroidSDK;第四步、为Eclipse安装ADT插件 下面详细介绍。第一步、安装JDKAndroid开发工具要求必须安装JDK(JavaDevelopmentKit),不能只安装JRE(JavaRuntimeEdition),在安装A…

发表回复

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

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