如何为多个C ++二进制文件启用地址清理器

Per*_*sta 2 gcc address-sanitizer

我正在开发一种产品,该产品由多个C ++可执行文件和相互依赖的各种库组成。我正在使用GCC和-fsanitize-address。据我了解,如果我想将地址清理器与库一起使用,则必须将其构建为共享对象(这是GCC的默认选项)。因此,我认为最好的选择是-static-libasan为可执行文件静态地构建地址清理器,并为库动态地构建地址清理器。但是,当我这样做时,在构建C ++可执行文件之一时出现链接错误:

==10823==Your application is linked against incompatible ASan runtimes
Run Code Online (Sandbox Code Playgroud)

这使我认为静态和动态版本的地址清除器不能与GCC混合使用,对吗?我在消毒剂GitHub页面上找不到关于此的任何信息。

yug*_*ugr 5

TLDR:

  • 如果您使用GCC / Clang并且主要可执行文件和shlibs都经过了清理,则无需执行任何特殊操作-只需坚持使用default即可-fsanitize=address
  • 如果您使用GCC,并且只清理了shlib,请在运行应用程序时再次使用-fsanitize=address并额外导出LD_PRELOAD=libasan.so
  • 如果您使用Clang且仅清理了shlib,请在运行该应用程序时进行编译/链接-fsanitize-address -shared-libasan并另外导出LD_PRELOAD=libclang_rt.asan-x86_64.so

现在一些解释。最初,Asan仅存在于默认使用(现在仍在使用)的Clang中-static-libasan。当将其移植到GCC时,GCC开发人员决定首选共享运行时(例如,因为它允许一个人仅清理一个共享库并保持主要的可执行文件不被清理,例如不重新编译python.exe就清理Python模块,有关其他示例,请参见Wiki)。两种方法都是二进制不兼容的,因此您不能将应用程序的一部分与静态运行时链接,而将一部分与动态运行时链接。

大致

  • GCC -fsanitize=address等同于Clang -fsanitize=address -shared-libasan(并且-shared-libasan是Clang的二等公民,因此没有得到很好的支持)
  • lang -fsanitize=address等同于GCC -fsanitize=address -static-libasan(同样,它-static-libasan是GCC中的二等公民,因此存在一些问题

另外,对于GCC / Clang Asan的其他区别,请参见此有用的Wiki

  • @MarcGlisse是的,但是它不会拦截标准符号,因为它不是库列表中的第一个。我也隐约记得还有其他重要问题,所以目前Asan会[如果缺少LD_PRELOAD就会中止执行](https://github.com/gcc-mirror/gcc/blob/36093749ff955d9e8cf208b04724c3a1a2ac9b04/libsanitizer/asan/asan_linux.cc #L137)。 (2认同)