我有几个版本的项目检出和编译。如果我发现错误,我会比较版本以缩小问题范围。有时我会启用像 AddressSanitizer 这样的消毒剂。如果我重用一个可执行文件,我不记得它是否是用消毒剂编译的。如果可执行文件工作正常,我不确定该错误是否不存在,或者我是否没有在此构建中包含消毒剂。所以我必须重新配置和重建以确保我有消毒剂。
有没有办法检查可执行文件是否已使用消毒剂编译?
我有几个版本的项目检出和编译。如果我发现错误,我会比较版本以缩小问题范围。有时我会启用像 AddressSanitizer 这样的消毒剂。如果我重用一个可执行文件,我不记得它是否是用消毒剂编译的。如果可执行文件工作正常,我不确定该错误是否不存在,或者我是否没有在此构建中包含消毒剂。所以我必须重新配置和重建以确保我有消毒剂。
有没有办法检查可执行文件是否已使用消毒剂编译?
Address sanitizer 也可以使用-static-libasan
GCC 中的选项进行静态编译。静态编译地址清理器是 Clang 中的默认模式。
如果您静态编译地址清理程序,那么显然无法ldd
用于验证您的二进制文件是否已清理。在这种情况下,我使用nm
并检查二进制文件中是否有消毒剂符号:
nm -an <executable> | grep asan
您需要使用 __has_feature(address_sanitizer),请参阅http://clang.llvm.org/docs/AddressSanitizer.html(其他消毒剂相同)。
来自man ldd
:
ldd 打印命令行上指定的每个程序或共享库所需的共享库。
只要地址清理程序需要与 libasan.so 库(清理程序的实际实现)链接,您就可以假设:
如果ldd
不打印共享库libasan.so
,那肯定意味着地址清理程序已关闭。
如果ldd
将打印共享库libasan.so
,则意味着您的链接器标志包含-lasan
,否则在链接期间您将收到未解决的符号错误。除非您在构建系统时遇到错误,否则很有可能启用了地址清理程序。
如果您的建筑系统中有错误,则可以选择第三个选项。ldd
将打印,libasan.so
但如果您传递给链接器,地址清理程序将被关闭-lasan
,但没有通过-fsanitize=address
。这意味着您将可执行文件与地址清理程序相关联,但未将检查包含到可执行文件中。
或者您可以执行 objdump -p 以查看libasan.so
在动态部分中是否需要:NEEDED libasan.so.0
. objdump
可以提供与 相同(和更多)的信息ldd
。