簡體   English   中英

解決消毒劑故障

[英]Address sanitizer failure

我正在使用gcc和嵌入了clang的消毒器,包括地址消毒器。 一切正常,但是在下一個演示代碼中,盡管有錯誤,但我沒有得到與錯誤相關的輸出(更確切地說,根本沒有輸出):

#include <string>
#include <iostream>

using std::string;
using std::cout;

class Foo
{
    string _member;
public:
    Foo(): _member("just a string") {}
    const string& get() const { return _member; }
};

const string& bar()
{
    // returning reference to a temp object on stack
    return Foo().get();
}

int main()
{
    cout << bar() << '\n';
    return 0;
}

我試過了g++ -O0 -g -fsanitize=address test.cc ,與clang++相同:g ++-version只輸出任何內容,clang一個版本打印了很長時間。 非儀器二進制文件上的Valgrind給出反饋: Syscall param write(buf) points to unaddressable byte(s)

是內部存在的問題還是我做錯了什么?

版本:gcc 4.9.2,clang 3.6.0

最初,我認為您在訪問臨時Foo對象時會遇到返回后使用錯誤。 由於內存開銷高,默認情況下ASan不會檢測到UAR(請參閱專用 wikipage上的更多詳細信息)。

但是現在我意識到情況更加復雜: std::string可以按原樣存儲輸入指針(寫時復制優化),將其復制到對象內部的小緩沖區(短字符串優化)或新的堆分配內存中。 實際行為取決於您使用的特定STL版本(例如,AFAIR libstdc ++實現最近已更改)。

我建議您將其報告給Asan的跟蹤器,以便在那里繼續調查。

#include <string>
#include <iostream>

using std::string;
using std::cout;

class Foo
{
    string _member;
public:
    Foo(): _member("just a string") {}
    const string& get() const { return _member; }
};

const string bar()
{
    // returning reference to a temp object on stack
    return Foo().get();
}

int main()
{
    cout << bar() << '\n';
    return 0;
}

如果刪除引用,效果很好。

同樣,您要創建的對象僅在bar()有效,此后它就無用了。

它適用於您的get方法,因為該變量在類的范圍內是預先存在的。


const string& bar()
{
    const string a = Foo().get();

    // returning reference to a temp object on stack
    return a;
}

如果您實際上不只是返回引用而是將其放在字符串中,則將收到警告:

main.cpp:23:12: warning: reference to stack memory associated with local variable 'a' returned [-Wreturn-stack-address]

我能想到的關於您的直接返回語句的原因是編譯器已經對其進行了優化。

暫無
暫無

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

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