检查 AddressSanitizer 等消毒剂是否处于活动状态

Check whether sanitizer like AddressSanitizer is active

我有几个版本的项目检出和编译。如果发现错误,我会比较版本以缩小问题范围。有时我会启用像 AddressSanitizer 这样的清理器。如果我重新使用一个可执行文件,我不记得它是否是用消毒剂编译的。如果可执行文件工作正常,我不确定错误是否不存在,或者我是否没有在此构建中包含消毒剂。所以我必须重新配置和重建以确保包含消毒剂。

有没有办法检查可执行文件是否已使用消毒剂编译?

您需要使用__has_feature(address_sanitizer),参见http://clang.llvm.org/docs/AddressSanitizer.html(其他消毒剂相同)。

来自 man ldd:

ldd prints the shared libraries required by each program or shared library specified on the command line.

只要地址消毒器需要 link 和 libasan.so 库(消毒器的实际实现),您就可以假设:

  • 如果ldd不会打印共享库libasan.so,这肯定意味着地址清理器已关闭。

  • 如果 ldd 将打印共享库 libasan.so 这意味着您的 linker 标志包括 -lasan,否则您将得到未解析的符号linking 期间出错。地址清理器很可能已启用,除非您在构建系统时遇到错误。

  • 第三个选项,如果你的构建系统有错误。 ldd 将打印 libasan.so 但如果您传递给 link 或 -lasan 但未传递 -fsanitize=address,地址清理程序将被关闭。这意味着您 link 使用地址清理程序编辑了您的可执行文件,但没有包含对您的可执行文件的检查。

    或者您可以执行 objdump -p 以查看动态部分是否需要 libasan.soNEEDED libasan.so.0objdump 可以提供与 ldd.

  • 相同(甚至更多)的信息

Address sanitizer 也可以使用 GCC 中的 -static-libasan 选项进行静态编译。静态编译地址清理器是 Clang 中的默认模式。

如果您静态编译地址清理器,那么显然不可能使用 ldd 来验证您的二进制文件是否经过清理。在这种情况下,我使用 nm 并检查二进制文件中是否有消毒剂符号:

nm -an <executable> | grep asan