簡體   English   中英

來自tcmalloc的意外行為

[英]Unexpected Behaviour from tcmalloc

我在一個大型項目中使用tcmalloc已有幾個月了,到目前為止我必須說我很高興,最重要的是它的HeapProfiling功能允許跟蹤內存泄漏並刪除它們。

在過去的幾周里,雖然我們的應用程序中遇到了隨機崩潰,但我們無法找到隨機崩潰的來源。 在一個非常特殊的情況下,當應用程序崩潰時,我們發現自己的應用程序線程之一的堆棧已完全損壞。 相反,我發現線程被卡在tcmalloc :: PageHeap :: AllocLarge()中,但由於我沒有連接tcmalloc的調試符號,我無法理解問題是什么。

經過近一周的調查,今天我嘗試了最簡單的事情:從連接中刪除tcmalloc以避免使用它,只是為了看看發生了什么。 嗯......我終於找到了問題所在,而且有問題的代碼看起來非常像這樣:

   void AllocatingFunction()
   {
       Object object_on_stack;
       ProcessObject(&object_on_stack);

   }

   void ProcessObject(Object* object)
   {
       ...
       // Do Whatever
       ...
       delete object;
   }

使用libc,應用程序仍然崩潰,但我終於看到我在堆棧上分配的對象上調用了delete。

我仍然無法弄清楚的是為什么tcmalloc保持應用程序運行而不管這種非常危險(如果不是完全錯誤的)對象釋放,以及當AllocatingFunction結束時object_on_stack超出范圍時的雙重釋放。 事實是,可以反復調用違規代碼而不暗示潛在的憎惡。

我知道,如果使用不當,內存釋放是那些“未定義的行為”之一,但令我驚訝的是“標准”libc和tcmalloc之間存在這種不同的行為。

有沒有人對tcmalloc保持應用程序運行的原因有一些洞察力的解釋?

提前致謝 :)

祝你今天愉快

對象釋放非常危險(如果不是完全錯誤的話)

好吧,我在這里不同意,這完全錯誤的,因為你調用UB,任何事情都可能發生。

它在很大程度上取決於tcmalloc代碼在解除分配時的實際作用,以及它如何在該位置使用堆棧周圍的(可能是垃圾)數據。

我也看到過tcmalloc在這種情況下崩潰,以及glibc進入無限循環。 你看到的只是巧合。

首先,你的案件沒有雙重free 當object_on_stack超出范圍時,沒有free調用,只是堆棧指針減少(或者更確切地說,隨着堆棧增長...)。

其次,在刪除期間,TcMalloc應該能夠識別堆棧中的地址不屬於程序堆。 這是free(ptr)實現的一部分:

const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
Span* span = NULL;
size_t cl = Static::pageheap()->GetSizeClassIfCached(p);

if (cl == 0) {
    span = Static::pageheap()->GetDescriptor(p);
    if (!span) {
        // span can be NULL because the pointer passed in is invalid
        // (not something returned by malloc or friends), or because the
        // pointer was allocated with some other allocator besides
        // tcmalloc.  The latter can happen if tcmalloc is linked in via
        // a dynamic library, but is not listed last on the link line.
        // In that case, libraries after it on the link line will
        // allocate with libc malloc, but free with tcmalloc's free.
        (*invalid_free_fn)(ptr);  // Decide how to handle the bad free request
        return;
    }

調用invalid_free_fn崩潰。

暫無
暫無

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

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