我一直在大型項目中使用tcmalloc幾個月,到目前爲止,我必須說我對此非常高興,最重要的是它的HeapProfiling功能,它允許跟蹤內存泄漏並刪除他們。tcmalloc意外的行爲
儘管我們在應用程序中遇到了隨機崩潰,但在過去的幾周內,我們無法找到隨機崩潰的來源。在一個非常特殊的情況下,當應用程序崩潰時,我們發現自己的某個應用程序線程完全損壞了堆棧。好幾次,我發現線程卡在tcmalloc :: PageHeap :: AllocLarge(),但由於我沒有tcmalloc鏈接調試符號,我不明白是什麼問題。
經過近一個星期的調查,今天我嘗試了最簡單的事情:從鏈接中刪除tcmalloc以避免使用它,只是爲了看看發生了什麼。嗯...我終於發現了問題所在,並有問題的代碼看起來非常像這樣:
void AllocatingFunction()
{
Object object_on_stack;
ProcessObject(&object_on_stack);
}
void ProcessObject(Object* object)
{
...
// Do Whatever
...
delete object;
}
使用libc中的應用程序仍然崩潰,但我終於看到了,我在呼喚刪除對象這是上分配在堆棧上。
我仍然無法弄清楚爲什麼tcmalloc會讓應用程序繼續運行,而不管這種風險如何(如果不是完全錯誤的話)對象釋放,以及當AllocatingFunction結束時object_on_stack超出範圍時的雙重釋放。事實是,違規代碼可以被重複調用,而不會有任何暗示憎惡的暗示。
我知道,當未正確使用時,內存釋放是那些「未定義的行爲」之一,但我驚訝的是「標準」libc和tcmalloc之間的這種不同的行爲。
有沒有人有某種洞察力的解釋,爲什麼tcmalloc保持應用程序運行?
感謝提前:)
擁有美好的一天
他們選擇了他們的「未定義行爲」來*不崩潰*。我會依靠這個嗎? *一定不行*。 – WhozCraig