使用 Address Sanitizer 和 gcc7.1.0 时如何生成核心转储
Posted
技术标签:
【中文标题】使用 Address Sanitizer 和 gcc7.1.0 时如何生成核心转储【英文标题】:How to generate core dump when use Address Sanitizer and gcc7.1.0 【发布时间】:2017-09-01 09:31:20 【问题描述】:我在 centOS 7.2.1511 上使用 -fsanitize=address
编译了我的代码。当我将 gcc 更新到 7.1.0 时,它不能再生成核心转储文件了。有人可以帮帮我吗?
gcc 编译选项:
-lm -g3 -Wall -Wno-unknown-pragmas --std=c++11 -Werror -ggdb -fsanitize=address -fno-omit-frame-pointer -D_GLIBCXX_USE_CXX11_ABI=0
链接选项:
-lxml2 -lpthread -lmysqlclient -L/usr/lib64/mysql/ -llog4cxx -lprotobuf -llua -lluabind -lhiredis -lcrypto -lcurl -ljsoncpp -Wl,-E -fsanitize=address -ldl
当我使用 gcc 4.8.5 时,通常会使用选项 ASAN_OPTIONS 生成核心转储,如下所示:
export ASAN_OPTIONS="disable_core=0:unmap_shadow_on_exit=1:abort_on_error=1"
当我将 gcc 更新到 7.1.0 时,即使 ASAN_OPTIONS 设置为如上,也无法再生成核心转储。
【问题讨论】:
【参考方案1】:问题解决了。新的消毒选项ASAN_OPTIONS应该设置为“disable_coredump”,我是这样设置的:
ASAN_OPTIONS="disable_coredump=0:unmap_shadow_on_exit=1:abort_on_error=1"
【讨论】:
【参考方案2】:嗯,理论上它应该是这样工作的:
ulimit -c unlimited
当然(可选调整sysctl kernel.core_pattern
)
export ASAN_OPTIONS=disable_coredump=0,abort_on_error=1
运行,获取核心(理想情况下,如果一切正常)。
但是,我尝试了更多disable_coredump=0
、halt_on_error=1
、abort_on_error=1
、handle_abort=0
的组合——我每次得到的只是一个恼人的 ASAN 错误(@ LLVM 8,提交 1473e85213404eccb4d018d41c24d2f5834f81b5 ):
nested bug in the same thread, aborting.
并退出代码 1(无核心)。从我对源代码的一瞥中,似乎 asan 处理了它发出的相同 SIGABRT,但将其解释为崩溃时处理崩溃。不完全是-help
所说的;也许有待改进。
不过,我还是可以通过另外一个选项来规避这种令人讨厌的错误处理:
ASAN_OPTIONS+=:sleep_before_dying=150
然后,当它按照指示休眠时,在终端中点击^\
(Ctrl\,相当于kill -QUIT
)。
最后,生成了我一直试图获取的核心文件。
【讨论】:
谢谢!在 gcc 8.3.1 中仍然遇到这个“在同一个线程中的嵌套错误”的事情。我开始有点发疯了。 :-( @MikeAndrews 欢迎您! :) 让我建议将这种挫败感转化为建设性的错误报告,“abort_on_error 不起作用” 或类似的东西。 github.com/google/sanitizers/issues 可能是一个很好的起点。 已经在这里报告github.com/google/sanitizers/issues/1072以上是关于使用 Address Sanitizer 和 gcc7.1.0 时如何生成核心转储的主要内容,如果未能解决你的问题,请参考以下文章
Address Sanitizer - 我可以在 N 个缺陷后停止吗?
在Android上使用Address Sanitizer构建但使用CMake
Address Sanitizer 调用了 OOM-killer
Advanced Debugging and the Address Sanitizer