![](/img/trans.png)
[英]different output for -fsanitize=address with clang++ vs g++
[英]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");
LinkCXXRuntimes =
Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX();
(請注意D.CCCIsCXX
部分,它檢查clang
與clang++
而相反,他們需要檢查文件類型)。
運行時的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.