首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ASAN的clang和clang++生成不同的输出

使用ASAN的clang和clang++生成不同的输出
EN

Stack Overflow用户
提问于 2017-10-19 18:45:29
回答 1查看 896关注 0票数 2

我试图将ASAN (Google/Clang的地址消毒)添加到我们的项目中,并解决了这个问题。

例如,我们有一个简单的C++代码

代码语言:javascript
复制
#include <iostream>
int main() {
    std::cout << "Started Program\n";
    int* i = new int(); 
    *i = 42;
    std::cout << "Expected i: " << *i << std::endl;
}

然后,我用clang++构建它。

代码语言:javascript
复制
clang++-3.8 -o memory-leak++ memory_leak.cpp -fsanitize=address -fno-omit-frame-pointer -g

程序给出了这个输出

代码语言:javascript
复制
Started Program
Expected i: 42

=================================================================
==14891==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4 byte(s) in 1 object(s) allocated from:
    #0 0x4f2040 in operator new(unsigned long) (memory-leak+++0x4f2040)
    #1 0x4f4f00 in main memory_leak.cpp:4:11
    #2 0x7fae13ce6f44 in __libc_start_main /build/eglibc-SvCtMH/eglibc-2.19/csu/libc-start.c:287

SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).

酷,它的工作和象征也提供有意义的信息。

现在,我用clang来构建这个

代码语言:javascript
复制
clang-3.8 -o memory-leak memory_leak.cpp -std=c++11 -fsanitize=address -fno-omit-frame-pointer -g -lstdc++

程序给出了这个输出

代码语言:javascript
复制
Started Program
Expected i: 42

=================================================================
==14922==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4 byte(s) in 1 object(s) allocated from:
    #0 0x4c3bc8 in malloc (memory-leak+0x4c3bc8)
    #1 0x7f024a8e4dac in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x5edac)
    #2 0x7f0249998f44 in __libc_start_main /build/eglibc-SvCtMH/eglibc-2.19/csu/libc-start.c:287

SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).

好的,它检测内存泄漏,但是堆栈跟踪看起来很奇怪,而且它实际上并不包括memory_leak.cpp:4:11行。

我花了很长一段时间试图缩小代码库中的这个问题,最终唯一的区别是clang++ clang++。

为什么这是一个问题,我们不能使用clang++吗?我们使用bazel,它使用CC编译器,而不是CXX,因为一些废话的原因.我们不能盲目地强制使用CXX,因为我们有CXX无法构建的CC依赖关系。所以..。

知道如何在使用clang和clang++时获得相同的ASAN输出吗?或者,如何使Bazel使用clang++作为C++目标,clang用于C目标?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-20 07:17:15

这似乎是Clang中的一个bug,您能在他们的追踪器中提交bug报告吗?(编辑:,这是解决为非a-bug,所以可能需要由Bazel开发人员来修复)。

一些细节:当您使用普通clang时,它决定不像在Tools.cpp中看到的那样链接Asan运行时的C++部分。

代码语言:javascript
复制
if (SanArgs.linkCXXRuntimes())
  StaticRuntimes.push_back("asan_cxx");

SanitizerArgs.cpp

代码语言:javascript
复制
LinkCXXRuntimes =
    Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX();

(注意D.CCCIsCXX部分,它检查clangclang++,而不是检查文件类型)。

运行时的C++部分包含用于operator new的拦截器,因此这将解释为什么当您使用clang而不是clang++链接时会丢失它。从积极的方面来说,您应该能够通过将-fsanitize-link-c++-runtime添加到您的标志来解决这个问题。

至于边缘堆栈,默认情况下,Asan使用基于框架指针的展开器展开堆栈,在没有使用-fno-omit-frame-pointer构建的代码中展开存在问题(就像您的例子中的libstdc++.so )。有关此类行为的另一个示例和可用的解决方案,请参见这个答案

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46836809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档