我正在开发一种产品,它由多个C ++可执行文件和彼此具有各种依赖关系的库组成。我正在用GCC和-fsanitize-address
构建它们。
据我所知,如果我想将地址清理程序与库一起使用,我必须将其构建为共享对象(这是GCC的默认选项)。因此,我认为最好的选择是使用-static-libasan
静态地为可执行文件构建地址清理程序,并为库构建它。但是,当我这样做时,我在构建一个C ++可执行文件时出现链接错误:
==10823==Your application is linked against incompatible ASan runtimes
这让我觉得地址消毒剂的静态和动态版本不能和GCC混在一起,对吗?我无法在消毒剂GitHub页面上找到有关此信息。
答案 0 :(得分:4)
<强> TLDR:强>
-fsanitize=address
。-fsanitize=address
并在运行应用程序时另外导出LD_PRELOAD=libasan.so
。-fsanitize-address -shared-libasan
进行编译/链接,并在运行应用时另外导出LD_PRELOAD=libclang_rt.asan-x86_64.so
。现在有些解释。原来Asan只存在于Clang中,默认情况下使用(并且仍然使用)-static-libasan
。当它被移植到GCC时,GCC开发人员决定优先使用共享运行时(例如,因为它允许只清理一个共享库并保持主要可执行文件未经过清理,有关其他示例,请参阅wiki)。这两种方法都是二进制不兼容的,因此您无法将部分应用程序与静态运行时链接,也可以与动态运行时链接。
粗略
-fsanitize=address
相当于Clangs -fsanitize=address -shared-libasan
(-shared-libasan
是Clang的二等公民,所以不太受支持)-fsanitize=address
相当于GCC -fsanitize=address -static-libasan
(同样,-static-libasan
是海湾合作委员会的二等公民,所以有一些问题)作为旁注,对于其他GCC / Clang Asan差异,请参阅this helpful wiki。