Linux ASAN 地址消毒

0、ASAN github

https://github.com/google/sanitizers/wiki/AddressSanitizer

1、升级GCC

http://mirrors-usa.go-parts.com/gcc/infrastructure/

2、编译选项

https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Instrumentation-Options.html#Instrumentation-Options

2.1     编译选项说明

Asan本身在发现错误后处理比较简单--终止进程退出。所以修改asan以支持发现错误后继续运行。经过近一个月的持续改进,发现错误继续运行特性已经相对稳定,无论发现多少内存错误,只要不触发异常,都可继续使用。

 

 ASAN_CFLAGS := -fsanitize=address
 ASAN_CFLAGS += -fsanitize-recover=address
 # conflict to sanitize
 ASAN_CFLAGS += -fno-stack-protector
 # ASAN_CFLAGS += -fgnu89-inline
 # -fvar-tracking is vvvv...very slow
 ASAN_CFLAGS += -fno-var-tracking
 # minimal debuginfo
 ASAN_CFLAGS += -g1
 ASAN_LDFLAGS = -fsanitize=address -g1

 

 

2.1.1       -fsanitize=address

支持应用程序内存越界检测,可检查全局变量、局部变量、堆内存等各种内存越界及内存释放后使用等错误。内核使用-fsanitize=kernel-address

2.1.2       -fsanitize-recover=address

编译器支持出错后继续运行,需要配置运行时环境变量ASAN_OPTIONS包含halt_on_error=0

2.1.3       -fno-stack-protector

关闭栈保护,使用asan不需要该功能,并且有些交叉编译器上并没有实现相应功能。

2.1.4       -fgnu89-inline

为了兼容代码中存在的大量不带static的inline函数。

 

GCC implements three different semantics of declaring a functioninline.  One is available with `-std=gnu89' or `-fgnu89-inline' or when`gnu_inline' attribute is present on all inline declarations, anotherwhen `-std=c99', `-std=c11', `-std=gnu99' or `-std=gnu11' (without`-fgnu89-inline'), and the third is used when compiling C++.

 

2.1.5       -g1

调试选项的级别总共有4,-g0,-g1,-g2,-g3,其中-g对应-g2g0表示不包含调试信息,-g3包含大量调试信息。嵌入式设备因为存储空间有限,不能使用-g,而为了方便开发定位,所以使用包含最小调试信息的-g1

 

3      运行时环境变量说明

3.1       LD_RPELOAD和XLD_PRELOAD

 

export XLD_PRELOAD=libasan.so.2:libprelib.so
   export LD_PRELOAD=$XLD_PRELOAD

 

目前有些新版本的linux不需要设置LD_PRELAOD=libasan.so.2,但是路由器目前使用的linux必须要手工设置LD_PRELOAD=libasan.so.2,另一个libprelib.soVRP和路由器为了使用malloc替代VRPDopra的相关VOS_Malloc等接口。

XLD_PRELOAD是为了规避frame启动后清除LD_PRELOAD增加的,同时在asan修改了exec相关函数,如果设置XLD_PRELOAD,则LD_PRELOAD=$XLD_PRELOAD

3.2       ASAN_OPTIONS

 

export ASAN_OPTIONS=halt_on_error=0:use_sigaltstack=0:fast_unwind_on_fatal=1:fast_unwind_on_check=1:fast_unwind_on_malloc=1:malloc_context_size=15:dump_instruction_bytes=1:quarantine_size=4194304:log_path=/opt/vrpv8/var/log/asan/asan.log:allow_user_segv_handler=1:intercept_tls_get_addr=0:detect_leaks=1:suppressions=$SUPP_FILE:print_suppressions=0

 

halt_on_error=0 出错后继续运行,除非遇到异常或不可处理的错误

use_sigaltstack=0 关闭asan提供sigaltstack,因为Dopra会提供,不适用Dopra应该不需要设置

fast_unwind_on_fatal=1:fast_unwind_on_check=1:fast_unwind_on_malloc=1直接使用任务栈解析调用栈,fast_unwind_on_malloc是为了性能,fast_unwind_on_fatalfast_unwind_on_check是因为部分CPU上根据代码解析调用栈不正确。

malloc_context_size=15 记录调用栈的层数

quarantine_size=4194304 每个内存cache允许缓存的free内存块大小,如果内存紧张可以进一步减小

log_path=/opt/vrpv8/var/log/asan/asan.log 记录asan日志的路径,会自动添加进程号以区别

detect_leaks=1 使能内存泄露检测,目前可支持路由器所有CPU

suppressions=$SUPP_FILE 屏蔽打印某些内存错误,目前主要屏蔽了部分初始化阶段的不存在反复泄露的内存泄露以减少报告数量

你可能感兴趣的:(ASAN,Linux)