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

标签 gcc address-sanitizer

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

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

这让我觉得地址清理器的静态和动态版本不能与 GCC 混合,对吗?我无法在 sanitizers GitHub 页面上找到有关此的任何信息。

最佳答案

TLDR:

  • 如果你使用 GCC/Clang 并且主要的可执行文件和 shlib 都被清理了,你不需要做任何特别的事情——只要坚持默认的 -fsanitize=address .
  • 如果您使用 GCC 并且只清理 shlib,请再次继续使用 -fsanitize=address并额外导出 LD_PRELOAD=$(gcc -print-file-name=libasan.so)运行您的应用程序时。
  • 如果您使用 Clang 并且仅清理 shlib,请使用 -fsanitize-address -shared-libasan 进行编译/链接并额外导出 LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)运行应用程序时。

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

    大致
  • GCC -fsanitize=address相当于 Clang -fsanitize=address -shared-libasan (并且 -shared-libasan 在 Clang 中是二等公民,因此不太受支持)
  • clang -fsanitize=address相当于 GCC -fsanitize=address -static-libasan (同样,-static-libasan 是 GCC 中的二等公民,所以有一些 issues )

  • 作为旁注,有关其他 GCC/Clang Asan 差异,请参阅 this helpful wiki .

    关于gcc - 如何为多个 C++ 二进制文件启用地址清理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47021422/

    相关文章:

    linux - 是否可以更改 gcc *默认* 库搜索路径?

    c++ - 有什么方法可以将 unique_ptr 插入到 C++0x/gcc 4.4.7 中的映射中)?

    c++ - 将 .o 库文件链接到共享对象时出现问题

    c++ - 如何运行完全相互隔离的谷歌测试?

    c++ - 关于我在 OS X 上可用的各种 C++ 编译器的许多问题

    c - Scanf 跳过 C 中的每个其他 while 循环

    ios - XCode AddressSanitizer 结果解读

    c++ - 用结构体数据减去指针

    c++ - SDL_LockTexture()/AddressSanitizer/双免

    c++ - Clang 8 与 MinGW-w64 : How do I use address- & UB sanitizers?