首页 > 解决方案 > 日志控制,用于 Address Sanitizer PLUS Undefined Behavior Sanitizer?

问题描述

几个消毒剂(来自 GCC 或 Clang)不能组合 - 即在同一构建中同时使用,但 Asan 和 Ubsan 是可组合的 - 即我可以使用“-fsanitize=address,undefined -fsanitize-recover=all ...”构建并有一个执行两个消毒剂检查的 exe。到目前为止一切都很好。

不过,生成的可执行文件中的 LOGGING 似乎有问题。

在所有情况下,如果未在选项中设置“log_path”,则所有缺陷都会在 stderr 上报告。到目前为止还可以。但是尝试使用 log_path ,事情变得很奇怪:

是否有一些隐藏的魔法可以让两个消毒剂写入同一个缺陷日志?


要重现,请使用每个消毒剂都有缺陷的简单测试用例:

char *hello = "hello";

int main (int argc, char *argv[])
{
   int x = 1;
   x <<= 32; // Error: (1 << 32) can't be represented in a (32-bit) int
   char some_char = hello [argc *10];
}

构建并运行:(此处使用 g++ 7.3.0,但其他 GCC 版本以及 clang 7.1.0 也显示出相同的基本行为)

仅限 Asan - 按预期工作

g++ foo.C -fsanitize=address -fsanitize-recover=all -g
setenv ASAN_OPTIONS "log_path=./ASAN:halt_on_error=0:handle_abort=1:exitcode=0"
a.out 

归档 ASAN。29648 包含以

==29648==错误:AddressSanitizer:全局缓冲区溢出地址 0x000000400aca 在 pc 0x0000004009a5 bp 0x7ffffffffe090 sp 0x7ffffffffe088

在 main /tmp/foo.C:7 中的 0x000000400aca 线程 T0 0x4009a4 处读取大小 1

仅 Ubsan - 按预期工作

g++ foo.C -fsanitize=undefined -fsanitize-recover=all -g
setenv UBSAN_OPTIONS "log_path=./UBSAN:halt_on_error=0:handle_abort=1:exitcode=0”
a.out

文件 UBSAN.29675 包含

foo.C:6:6:运行时错误:移位指数 32 对于 32 位类型“int”而言太大

Asan PLUS Ubsan - 奇怪的日志记录行为

g++ foo.C -fsanitize=address,undefined -fsanitize-recover=all -g

setenv ASAN_OPTIONS "log_path=./ASAN:halt_on_error=0:handle_abort=1:exitcode=0"
a.out 

ASAN_OPTIONS 被忽略,所有缺陷都报告在标准错误上。现在尝试设置 UBSAN_OPTIONS:

setenv UBSAN_OPTIONS "log_path=./UBSAN:halt_on_error=0:handle_abort=1:exitcode=0”
a.out

文件 UBSAN.30352 仅包含Asan缺陷:

==30352==错误:AddressSanitizer:全局缓冲区溢出地址 0x000000400aca 在 pc 0x0000004009a5 bp 0x7ffffffffe090 sp 0x7ffffffffe088 读取大小 1 在 0x000000400aca 线程 T0 0x4009a4 在主 /tmp/foo.C:7

并且 Ubsan 缺陷仅写入 stderr:

foo.C:6:6:运行时错误:移位指数 32 对于 32 位类型“int”而言太大

标签: address-sanitizersanitizerubsan

解决方案


已确认这实际上是一个错误。 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94328适用


推荐阅读