如何为多个C ++二进制文件启用地址清理器 [英] How to enable address sanitizer for multiple C++ binaries

查看:462
本文介绍了如何为多个C ++二进制文件启用地址清理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on a product that is composed of multiple C++ executables and libraries that have various dependencies on one another. I am building them all with GCC and -fsanitize-address. From what I understand, if I want to use address sanitizer with a library I have to build it as a shared object (which is the default option for GCC). Because of this, I thought the best option would be to build address sanitizer statically with -static-libasan for the executables and build it dinamically for the libraries. However, when I do that I get a link error when building one of the C++ executables:

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

这使我认为地址清理器的静态和动态版本不能混合使用在海湾合作委员会,对吗?我在消毒剂GitHub页面上找不到有关此的任何信息。

This makes me think that static and dynamic version of address sanitizer cannot be mixed with GCC, am I right? I was not able to find any information about this on the sanitizers GitHub page.

推荐答案

TLDR:


  • 如果您使用GCC / Clang并且主可执行文件和shlibs都已被清理,则无需执行任何特殊操作-坚持使用默认 -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)

  • If you use GCC/Clang and both main executable and shlibs are sanitized, you don't need to do anything special - just stick with default -fsanitize=address.
  • If you use GCC and only shlibs are sanitized, again keep using -fsanitize=address and additionally export LD_PRELOAD=$(gcc -print-file-name=libasan.so) when running your application.
  • If you use Clang and only shlibs are sanitized, compile/link with -fsanitize-address -shared-libasan and additionally export LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) when running the app.

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

Now some explanations. Originally Asan existed only in Clang which by default used (and still uses) -static-libasan. When it was ported to GCC, GCC developers decided that shared runtime is preferred (e.g. because it allows one to sanitize just one shared library and keep main executable unsanitized e.g. sanitize Python module without recompiling python.exe, see wiki for other examples). Both approaches are binary incompatible so you can't link part of your applications with static runtime and part with dynamic runtime.

大致


  • GCC -fsanitize = address 等同于Clangs -fsanitize = address -shared-libasan (并且 -shared-libasan 是Clang的二等公民,因此不太受支持)

  • Clangs -fsanitize = address 等同于GCC -fsanitize = address -static-libasan (同样, -static-libasan 是GCC中的二等公民,因此有一些问题

  • GCCs -fsanitize=address is equivalent to Clangs -fsanitize=address -shared-libasan (and -shared-libasan is second-class citizen in Clang so not as well supported)
  • Clangs -fsanitize=address is equivalent to GCCs -fsanitize=address -static-libasan (and again, -static-libasan is second-class citizen in GCC so has some issues)

请注意,有关GCC / Clang Asan的其他区别,请参见此有用的Wiki

As a side note, for other GCC/Clang Asan differences see this helpful wiki.

这篇关于如何为多个C ++二进制文件启用地址清理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆