簡體   English   中英

clang和clang ++與ASAN生成不同的輸出

[英]clang and clang++ with ASAN generate different output

我正在嘗試將ASAN(Google / Clang的地址清理)添加到我們的項目中,並陷入了這個問題。

例如,我們有這個簡單的C ++代碼

#include <iostream>
int main() {
    std::cout << "Started Program\n";
    int* i = new int(); 
    *i = 42;
    std::cout << "Expected i: " << *i << std::endl;
}

然后,我用clang ++構建它

clang++-3.8 -o memory-leak++ memory_leak.cpp -fsanitize=address -fno-omit-frame-pointer -g

程序給出此輸出

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).

很酷,它的工作原理和符號器也提供有意義的信息。

現在,我用c

clang-3.8 -o memory-leak memory_leak.cpp -std=c++11 -fsanitize=address -fno-omit-frame-pointer -g -lstdc++

然后程序給出這個輸出

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 vs clang ++。

為什么會出現問題,我們不能使用clang ++嗎? 我們使用bazel,出於某些原因,它使用CC編譯器而不是CXX。 我們不能盲目地強制使用CXX,因為我們具有CC依賴關系,而C依賴關系不能由CXX構建。 所以...

知道與clang和clang ++一起使用時如何獲得相同的ASAN輸出嗎? 或者,如何使Bazel將clang ++用於C ++目標並將clang用於C目標?

這似乎是Clang中的錯誤,您可以在其跟蹤器中提交錯誤報告嗎? 編輯: [已解決為非bug](Asan開發人員https://github.com/google/sanitizers/issues/872 ),因此可能需要由Bazel開發人員修復)。

一些細節:使用普通的clang ,它決定不鏈接Asan運行時的C ++部分,如在Tools.cpp中可以看到的那樣

if (SanArgs.linkCXXRuntimes())
  StaticRuntimes.push_back("asan_cxx");

SanitizerArgs.cpp

LinkCXXRuntimes =
    Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX();

(請注意D.CCCIsCXX部分,它檢查clangclang++而相反,他們需要檢查文件類型)。

運行時的C ++部分包含用於operator new攔截器,因此這可以解釋為什么當您使用clang而不是clang++鏈接時缺少它。 從積極的方面-fsanitize-link-c++-runtime ,您應該可以通過在標志中添加-fsanitize-link-c++-runtime來解決此問題。

至於沉悶的堆棧,默認情況下,Asan使用基於框架指針的展開器來展開堆棧,在通過-fno-omit-frame-pointer構建的代碼中展開時會遇到問題(例如libstdc++.so )。 請參見此答案的此類行為和可用解決方法的另一個示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM