【问题标题】:How to use AddressSanitizer with GCC?如何在 GCC 中使用 AddressSanitizer?
【发布时间】:2016-10-24 13:21:14
【问题描述】:

我正在尝试使用

构建我的项目
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。

【问题讨论】:

  • 这不是完整的编译行,因为您没有文件名。您是否在单独的步骤中编译/链接?您还忘记提及您正在使用的 gcc 版本...
  • 请设置正确答案@yugr 1,因为您标记的答案并不正确。

标签: gcc address-sanitizer


【解决方案1】:

您需要将-fsanitize=address 添加到编译器标志(CFLAGSCXXFLAGS)和链接器标志(LDFLAGS)。您可能只将它添加到您的编译器标志中。

请注意,使用显式 -lasan 选项已被 ASan 开发人员(例如 here)广泛反对,因为它错过了一些其他重要的链接器标志。唯一推荐的链接方式是使用-fsanitize=address

附带说明,对于更积极的验证标志,请检查 Asan FAQ(查找“更积极的诊断”)。

【讨论】:

  • 如果我跳过-lasan,我会得到undefined reference to __asan_...
  • @HeinrichStack 没有复制很难评论。请注意,-fsanitize=address 等同于 -lasan + 其他一些东西。
  • -Wl,--no-undefined 与Clang 一起使用时,还必须将-shared-libasan 添加到链接器标志中。这也是官方常见问题解答的一部分,但以防万一,在这里也能提供这些信息。
  • @DmitryKochkin 选择静态/共享运行时库是一个充满蠕虫的罐头(LLVM 和 GCC 之间的默认选择不同,-static-libasan 在 GCC 中实际上不起作用,共享/静态运行时的工作方式不同取决于主应用程序是否经过消毒等)。一般来说,我建议尽可能坚持使用编译器做出的默认选择,并且仅在极端情况下切换到-shared-libasan(仅清理一个库和/或使用-Wl,--no-undefined)。这是another answer 的链接,它提供了血腥的细节。
  • @yugr 是的,我说过它只能与-Wl,--no-undefined 一起使用。 C++ 中的链接本身就是一堆蠕虫,无论如何,你注定要选择这种语言。在您的另一个答案中,您为 Clang 推荐相同的答案。
【解决方案2】:

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

dnf install libasan libasan-static

【讨论】:

  • 确实,在将 Asan 应用到单个共享库并使用 -static-libasan 时,这可能会导致类似的错误。否则gcc 将发出不同的错误消息(libasan_preinit.o: No such file or directorycannot find -lasan)。在 Ubuntu 上,libasan 默认安装为 gcc
【解决方案3】:

您需要将开关 -lasan -fsanitize=address 添加到您的 both 您的编译 链接命令行以链接正确的库.

注意:根据 cmets,原始答案 -lasan 已过时,不应使用

【讨论】:

  • 这既不适用于 WSL,也不适用于 Windows。安装了所有版本的 libasan。
  • 根据我的经验,这是必要的 gcc 安装不正确
  • 这不应该是公认的答案。以下来自@yugr 的回答是正确的。只需添加此评论,这样人们就不会在接受答案后停止阅读。
  • 您应该自己添加-lasan。您应该使用编译器来驱动链接。当-fsanitize=address 存在时,编译器将添加正确的库。
  • 另外确认这不是启用地址清理程序的正确方法。
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多