尝试在GCC中使用地址检测器时出现“未定义引用”错误

84

我正在尝试使用

来构建我的项目。

g++ -O0 -g -fsanitize=address -fno-omit-frame-pointer

但是遇到了很多错误,例如:

/home/user/libs/opencv/include/opencv2/core/mat.hpp:715: undefined reference to `__asan_report_load8'

如何编译支持 AddressSanitize 的项目?

我的 gcc 版本是 4.8.4。


7
这不是完整的编译行,因为您没有文件名。您是分别进行编译/链接的吗?您还忘记提到您使用的gcc版本... - Marc Glisse
2
请将正确答案设置为 @yugr,因为您标记的那个并不是真正的正确答案。 - ceztko
3个回答

168
你需要将-fsanitize=address添加到编译器标志(包括CFLAGSCXXFLAGS)和链接器标志(LDFLAGS)。你可能只将它添加到了编译器标志中。
请注意,使用显式的-lasan选项已被ASan开发人员广泛不建议使用(例如 这里),因为它会忽略一些其他重要的链接器标志。唯一推荐的链接方式是使用-fsanitize=address
顺便说一下,如果要使用更激进的验证标志,请查看 Asan FAQ(搜索“更激进的诊断”)。

1
如果我跳过-lasan,我会得到undefined reference to __asan_... - HeinrichStack
2
@HeinrichStack 没有复现情况很难发表评论。请注意,-fsanitize=address 相当于 -lasan 加上其他一些内容。 - yugr
2
当使用Clang和-Wl,--no-undefined一起时,必须将-shared-libasan添加到链接器标志中。 这也是官方FAQ的一部分,但以防万一,在这里提供此信息也很好。 - Dmitry Kochkin
@yugr 是的,我说它应该只与“-Wl,--no-undefined”一起使用。C++中的链接本身就是一个棘手的问题,无论你选择哪种语言,都注定会遇到这个问题。 而在你的另一个答案中,你也推荐Clang使用相同的方法。 - Dmitry Kochkin
1
@User10482 是的,你说得对,这是gcc/clang的一个选项(LDFLAGS变量通常用于“链接时使用的gcc标志”)。你可以通过在gcc/clang后面加上-v标志来查看它会扩展为哪些ld/lld标志。 - yugr
显示剩余4条评论

14

请确保您已安装libasan。例如,在Fedora中:

dnf install libasan libasan-static


1
实际上,当将Asan应用于单个共享库并使用-static-libasan时,可能会导致类似的错误。否则,gcc将发出不同的错误消息(libasan_preinit.o:没有这样的文件或目录无法找到-lasan)。在Ubuntu上,默认情况下使用gcc安装了libasan - yugr

11
您需要在编译和链接命令行中都添加开关-fsanitize=address,以链接正确的库。
注意:原始答案-lasan已过时,不应再使用,如评论所述。

这在WSL和Windows上都无法工作,即使安装了所有版本的libasan。 - CodeMonkey
2
根据我的经验,当出现这种情况时,通常是gcc安装不正确。 - Cruz Jean
19
这不应该是被接受的答案。@yugr下面的回答是正确的。只是加了这个评论,让人们不要在接受答案后停止阅读。 - hko
4
不要自己添加“-lasan”,应使用编译器进行链接。当存在“-fsanitize = address”时,编译器将添加正确的库。 - jww
1
同时确认这不是启用地址安全性检查的正确方法。 - ceztko
适用于gcc 12/debian。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接