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

时间:2017-10-30 17:53:52

标签: gcc address-sanitizer

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

==10823==Your application is linked against incompatible ASan runtimes

这让我觉得地址消毒剂的静态和动态版本不能和GCC混在一起,对吗?我无法在消毒剂GitHub页面上找到有关此信息。

1 个答案:

答案 0 :(得分:4)

<强> TLDR:

  • 如果你使用GCC / Clang并且主要的可执行文件和shlib都被清理了,你就不需要做任何特别的事情 - 只需坚持使用默认的-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开发人员决定优先使用共享运行时(例如,因为它允许只清理一个共享库并保持主要可执行文件未经过清理,有关其他示例,请参阅wiki)。这两种方法都是二进制不兼容的,因此您无法将部分应用程序与静态运行时链接,也可以与动态运行时链接。

粗略

  • GCC -fsanitize=address相当于Clangs -fsanitize=address -shared-libasan-shared-libasan是Clang的二等公民,所以不太受支持)
  • Clangs -fsanitize=address相当于GCC -fsanitize=address -static-libasan(同样,-static-libasan是海湾合作委员会的二等公民,所以有一些问题)

作为旁注,对于其他GCC / Clang Asan差异,请参阅this helpful wiki