用gcc fsanitize导致意外的提前退出

时间:2018-09-18 00:01:07

标签: c++ gcc clang++

我遇到了一个错误,该错误无法一致地再现,其中在无效的堆指针上调用了free()。使用所讨论的代码,基本上不可能将这个问题减少到“最小”((一旦完成,就解决了))。我无法发现任何明显的问题(例如从未调用calloc或双倍空闲等潜在情况)

我相信valgrind可以解决此问题,除了对性能的影响会非常极端(这些请求是客户端->服务器调用超时,并且操作开始时要花费昂贵的时间...> 4秒在某些情况下)

这让我留下fsanitize=address,我相信吗?到目前为止,我的经历还很糟糕。

我有两个静态库和一个与它们链接的可执行文件。我为他们三个都打开了fsanitize=address。使用-fsanitize=address,在非常经过全面测试并纠正初始化例程的过程中,代码可以在调试器下干净退出(在256字节memcpy中间,进入16兆堆分配-退出代码1)。

任何有使用fsanitize的实际经验的人都可以向我提供有关问题可能出在哪里的任何提示吗?我在cmake下使用gcc / ld,并且代码(根本上)是用C ++编译的。如果这样可以改善情况,则可能会选择切换到clang。

文件的典型编译命令:

"command": "/usr/bin/c++   -I. -I/home/redacted -fpermissive -g -g3 -fasynchronous-unwind-tables -fsanitize=address   
-std=gnu++11 -o core/CMakeFiles/nginx_core.dir/src/core/nginx.cpp.o -c /home/redacted.cpp",

1 个答案:

答案 0 :(得分:1)

我将把它留在这里,以供将来对fsanitize有疑问的搜索者使用。 tldr;-有效。我有两个基本问题:

  1. fsanitize正在输出有关退出原因的详尽错误信息。 nginx吞没了这个问题……并在我们的自定义版本中将其重定向到一个晦涩的日志文件。不知道为什么在gdb下没有得到调试中断,但是...正在检测合法错误。此处的关键信息:在__asan_report_error中设置断点将在退出之前暂停程序,以便您检查各种帧。

  2. 尽管初始化例程正确且经过了严格的测试,但正如我所提到的,它确实需要其客户端正确分配(非平凡的)配置结构。在这种情况下,结构缺少完整的1个字节,从而导致1个字节的过度读取。