記憶體洩漏排查

2021-07-27 05:36:17 字數 2909 閱讀 1132

在工作中發現乙個tuexdo服務存在記憶體洩漏的情況,之前也嘗試過用valgrind等工具查詢,但是因為**直接載入在tuexdo的服務中,不知道怎麼直接啟動,所以沒有用valgrind。在經過查詢資料後,決定自己寫重寫malloc/free等函式,列印出分配位址和釋放位址,進行對比,如果發現只有malloc沒有free,則能定位到相關**

如何實現乙個malloc

基礎知識,介紹了linux記憶體管理的基本知識,簡單介紹了malloc的實現機制,並逐漸實現乙個malloc

memory allocation hooks

有用例,比man__malloc_hook 中的用例更適合

man__malloc_hook

malloc_hook鉤子函式的官方文件

memory leak & double free如何排查?

首先介紹了如何定位呼叫函式的幾種方法 其次介紹了收集記憶體分配和釋放的兩種方法,最後這兩種方法都除錯成功了

1. 通過巨集替換掉發起記憶體分配的函式(malloc、realloc、calloc、memalgin、new),但是確定在於必須有源**,否則無法替換

2. 在無**情況下,用malloc鉤子函式替換malloc函式,man__malloc_hook

攔截malloc、free等庫函式(malloc鉤子)

函式實現時參考了這裡和官方頁面用例(memory allocation hooks)的**

在應用程式中替換linux中glibc的malloc的四種方法

介紹了替換malloc的四種方法:

1. 使用環境變數ld_preload,使用ld_preload後,自己編寫的malloc的載入順序高於glibc中的malloc

2. malloc除錯變數,即使用malloc鉤子函式,優點是沒有源**的情況下也可以實現malloc替換,缺點是不適用於多執行緒環境中,本文主要通過該方法實現記憶體洩漏的排除

3. 編譯自己的libmalloc.a,沒看懂這個方法

4. 鏈結過程控制,即在gcc編譯時,使用 –wl –wrap,當查詢某個符號時,它優先先解析__wrap_symbol, 解析不到才去解析symbol,這個方法嘗試了但是沒成功,參考:定製化的malloc/free

根據memory leak & double free如何排查? 裡面介紹的兩種方法,首先實現了巨集定義的方式,發現我們自己的**裡面沒有分配了沒釋放的情況,然後採用了方法2,即寫malloc_hook的方法,替換原malloc,在自己的malloc函式my_malloc中列印位址,my_free中也列印位址,通過awk指令碼解析log日誌,對比malloc的位址在後面是否有對應的free,如果沒有,則列印出來包括呼叫位址在內的資訊,進行進一步排除,發現是oracle的庫檔案函式在malloc,但是沒有對應的函式會呼叫free函式釋放這塊記憶體,導致記憶體增長

**在 tool-checkmemory

在檔案中包含 memcheck.h檔案

#include 

"memcheck.h"

在main或只呼叫一次的函式中呼叫my_malloc_ini(),從這個函式開始,後面的malloc函式都會被my_malloc_hook函式,會print出相關資訊,如果想要列印出注釋資訊,以*開頭

int main()
執行程式,將資訊列印到指定的日誌檔案中,修改check.sh中的$log配置,指向你的日誌檔案

logs=~/logs/20170220.

out//your log file

可以看到日誌如下:

malloc 0x83c2128 from   0x804b418 size 4696

****start main****

malloc 0x83c2140

from

0xb79b29ad

size

11free 0x83bf518

from

0x4ee876

free 0x83bd510

from

0xb79b26b8

free 0x83bf680

from

0xb79b2fcc

malloc 0x83bd510

from

0xb79b3da6

size

7realloc0x83bba60 from

0xb79c31be

size

117 oldptr 0x83bba60

free 0x83bd510

from

0xb78ed599

free 0x83c2140

from

0xb79c3b6a

執行check.sh進行解析,會列印出有malloc/realloc但是沒有對應free的地方,像這樣:

0x8425f00 6201 0x804b418  4696

****start main****

每一行分別代表 %記憶體位址% %日誌行數% %呼叫函式位址% %記憶體大小%

可以看出在**0x804b418處,宣告了大小為4696的記憶體,但是沒有free

呼叫addr2line,檢視0x804b418對應的源**

[cindyhua@dev-spytux-68 tool-memcheck]$addr2line -e a.out -f 0x804b418

main

/main.c:4

iOS 記憶體洩漏排查方法

動態分析方法 instrument工具庫里的leaks 點選左上角的紅色圓點,這時專案開始啟動了,由於leaks是動態監測,所以手動進行一系列操作,可檢查專案中是否存在記憶體洩漏問題。如圖所示,橙色矩形框中所示綠色為正常,如果出現如右側紅色矩形框中顯示紅色,則表示出現記憶體洩漏。選中leaks ch...

c 記憶體洩漏排查簡單完美

callocbuffer cb char str cb.callocchar 2048,function cb.freechar 這裡注釋掉會列印記憶體沒有釋放 h class callocbuffer cpp include callocbuffer.h include callocbuffer ...

iOS 記憶體洩漏排查以及處理

第一步 開啟xcode7自帶的instruments 或者 按上面操作,build成功後跳出instruments工具,選擇leaks選項 選擇之後介面如下圖 到這裡之後,我們前期的準備工作做完啦,下面開始正式的測試 1.選中xcode先把程式 command r 執行起來 2.再選中xcode,按...