地址消毒fsanitizer选项细节探究

实验环境:
image.png

使用kernel5.4版本和gcc9.3.0版本

1.从最简单的-fsanitize=address开始

被测代码:预埋一个栈溢出bug


image.png

gcc命令如下:


image.png

结果:
image.png

很明显检测出了栈溢出行为.

2.预埋两个栈溢出bug,使用-fsanitize=address -fsanitize-recover=address -fno-omit-frame-pointer -O0 -Wall

image.png

-fno-omit-frame-pointer : 保留栈指针,打印有用的堆栈信息,方便asan定位问题时追踪
-fsanitize-recover=address : 在触发asan时,继续运行程序,需要配合环境变量ASAN_OPTIONS=halt_on_error=0:report_path=xxx使用
-O0 : 不适用编译期优化,避免优化asan效果
-Wall : 显示所有告警信息

开始实验:
image.png

image.png

image.png

可以看到出现了两个asan告警,说明编译选项生效了,非常开心

3.探究-fsanitize-recover=address 和-fsanitize-recover=address,all的区别

-fsanitize-recover=address :
关于asan,github上官方文档对编译选项后的可选项并没有很详细的说明,参见https://github.com/google/sanitizers/wiki/AddressSanitizer

image.png

此次在代码中埋一个整数溢出bug,一个除0,和两个栈溢出bug,在编译选项中加上-fsanitize=undefined , 结合环境变量export UBSAN_OPTIONS=print_stacktrace=1查看堆栈信息
image.png

编译运行
image.png

结论是触发了所有的预埋bug且没有退出程序,注意,这是没有在-fsantize-recover=address后面加上all的情况
-fsanitize-recover=address,all
image.png

与不加all的信息完全相同。
关于-fsanitize-recover选项的官方解释是这样的:
image.png

但在实际使用中暂时感受不到什么区别。