Linux 應用程式除錯技術/堆損壞
Electric Fence 仍然是處理堆損壞的參考工具,即使它已經有一段時間沒有維護了。RedHat 釋出了一個可以作為中間庫使用的版本。
缺點:可能不適用於使用mmap()分配記憶體的程式碼。
Duma 是 Electric Fence 的一個分支。
man (3) malloc: 最新的 Linux libc 版本(高於 5.4.23)和 GNU libc(2.x)包含一個可透過環境變數調整的 malloc 實現。當MALLOC_CHECK_被設定時,會使用一個特殊的(效率較低)實現,該實現旨在容忍簡單的錯誤,例如使用相同引數對 free() 進行兩次呼叫,或者越界一個位元組(越界錯誤)。但是,並非所有此類錯誤都能得到保護,可能會導致記憶體洩漏。如果MALLOC_CHECK_被設定為 0,則會靜默忽略任何檢測到的堆損壞,不會生成錯誤訊息;如果設定為 1,則會將錯誤訊息列印到 stderr,但程式不會中止;如果設定為 2,則會立即呼叫 abort(),但不會生成錯誤訊息;如果設定為 3,則會將錯誤訊息列印到 stderr,並中止程式。這很有用,因為否則可能會在很晚的時候發生崩潰,而實際的錯誤原因很難追查。
使用以下命令進行編譯-D_GLIBCXX_DEBUG- 它會在 C++ 標準庫中開啟除錯檢查。
一個透過以下命令實現的快速記憶體錯誤檢測器-fsanitize=address, 使用最新的 gcc(從 4.8 開始)或 clang(從 3.1 開始)。記憶體訪問指令會被檢測到堆、棧和全域性緩衝區溢位以及使用後釋放錯誤。為了獲得更友好的堆疊跟蹤,請使用 -fno-omit-frame-pointer。AddressSanitizer 可用於 IA-32/x86-64/x32/PowerPC/PowerPC64 GNU/Linux 和 x86-64 Darwin。
從 gcc 4.9 及更高版本開始,您可以使用 ubsan 編譯器 進行邊界檢查。
使用 GDB 時不會出現,但未使用 GDB 時出現的與記憶體相關的錯誤通常是由 GDB 停用 ASLR 引起的。這通常對除錯會話的可重複性很有用,但確實會使地址空間佈局過於可預測,從而無法重現錯誤。嘗試使用 GDB 命令 “set disable-randomization off”(不帶引號)來撤銷此行為,從而在正常的隨機環境中啟動程式。