日志记录控制,用于地址清理器以及未定义行为清理器?



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

不过,来自生成的可执行文件的日志记录似乎有问题。

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

  • 对于仅使用 Asan 构建的 exe,并将ASAN_OPTIONS设置为包含"log_path=./ASAN",地址清理器缺陷将进入名为 ASAN 的文件中。
  • 对于仅使用 Ubsan 构建的 exe,并将UBSAN_OPTIONS设置为包含"log_path=./UBSAN",未定义行为缺陷将进入名为 UBSAN 的文件中。
  • 对于同时使用牙山和乌布桑构建的exe o Asan 输出转到指定的日志文件,但 ubsan 输出仅转到 stderr o 即使仅通过UBSAN_OPTIONS设置log_path,并且未设置ASAN_OPTIONS,上述规定也适用 o 如果同时在ASAN_OPTIONS和UBSAN_OPTIONS中设置log_path,则使用log_path是 UBSAN 结果,但仅包含 ASAN 结果

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


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

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 都显示了相同的基本行为)

仅牙山 - 按预期工作

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==错误:地址清理器:PC 0x0000004009a5 bp 0x7fffffffe090 sp 0x7fffffffe088 的地址 0x000000400aca 上的全局缓冲区溢出

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

仅限 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 包含

噗。C:6:6:运行时错误:移位指数 32 对于 32 位类型"int"来说太大

牙山加乌布桑 - 奇怪的日志记录行为

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被忽略,所有缺陷都会在 stderr 上报告。现在尝试设置UBSAN_OPTIONS:

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

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

==30352==错误:地址清理器:PC 0x0000004009a5 bp 0x7fffffffe090 sp 0x7fffffffe088 的地址 0x000000400aca 上的全局缓冲区溢出 在线程 T0 0x000000400aca读取大小为 1 0x4009a4 in main/tmp/foo.C:7

并且 Ubsan 缺陷只写入 stderr:

噗。C:6:6:运行时错误:移位指数 32 对于 32 位类型"int"来说太大

并且 Ubsan 缺陷只写入 stderr:

这听起来像是一个错误(或者至少是未经测试的设置组合)。

也就是说,一般来说,ASan 开发人员并不认为halt_on_error=0是一个有用的功能 - 您应该在发现错误时修复它们,因为在您已经过度飞行缓冲区或使用悬空内存之后寻找 UB 是没有意义的。在那之后,任何事情都可能发生。

因此,如果您确实提交了有关这种奇怪日志记录行为的错误,我希望该错误很少受到关注。

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

我一直在寻找一种在没有控制台来检测运行时代码已崩溃的avr-gcc中使用 AddressSantizer 的方法。我仍然需要尝试它,但我相信这个用例是此功能无用的反例。

相关内容

最新更新