用mtrace定位内存泄漏
一. 緣起
有的公眾號讀者,看完我上次寫給大學生的查bug方法后,希望我多分享一些查bug的實踐經驗和具體步驟,比如如何查內存泄漏和core dump問題。所以,就打算寫這篇文章。
二. 內存泄漏簡介
內存泄漏,是一個談虎色變的問題。我個人的基礎非常差,大學畢業后,才第一次聽說內存泄漏。當時,我有點懵圈,心想內存泄漏了,是要重新去買新的內存設備嗎?很傻很天真!
后來,我又聽說了很多次內存泄漏,查資料后才知道,原來這是一個軟件層面的東西。比如,使用了malloc, 但沒有使用free, 或者使用了new, 但沒有使用delete, 都會造成內存泄漏。
為什么說內存泄漏會談虎色變呢?因為:
內存泄漏危害性大
內存泄漏潛伏時間長
內存泄漏不容易定位
那么,如果內存泄漏了,我們該如何去定位呢?在C/C++相關的面試中,不問這個問題的面試官,是不合格的;不會回答這個問題的面試者,也是不合格的。當然,這種說法,似乎有一點絕對。
有的面試者回答,只有小心配對使用malloc/free和new/delete, 就能避免內存泄漏。顯然,這種面試者缺乏基本的工程實踐認知,缺乏對敵人的敬畏。
有的面試者回答,使用智能指針,就能避免內存泄漏。顯然,這只是一種預防機制。在實際項目中,各種復雜因素導致的后果是內存已經泄漏,需要定位。
還有的面試者,更是想出了出人意料的答案,那就是檢查代碼!這又是對敵人缺乏了解啊。大型工程的代碼動輒幾十萬行,誰敢走讀代碼來查內存泄漏呢?
對我而言,查殺bug是我的相對強項(實話說,架構能力需要加強)。mtrace和valgrind是典型的內存泄漏分析工具。今天,我們聊mtrace定位內存泄漏。
三. mtrace簡介
我們來看下mtrace的用途:
顯然,mtrace命令是用來分析malloc函數的trace log.?
那么,這個trace log是怎么生成的呢??且看上面的see mtrace(3). 有的朋友看到這里,不知道怎么敲命令了,以為是:
ubuntu@VM-0-15-ubuntu:~$ man mtrace(3) -bash: syntax error near unexpected token `(' ubuntu@VM-0-15-ubuntu:~$其實,正確的姿勢如下:
顯然,mtrace函數是用來記錄malloc的trace log的。
所以,對于mtrace, 我們有如下的基本認知:
mtrace函數記錄malloc的trace log
mtrace命令分析上述記錄的trace log
這也就是用mtrace來定位內存泄漏的原理。那么,具體如何來查內存泄漏呢?不要著急,繼續往下看。
四. 用mtrace定位內存泄漏
首先,我們來寫一段有內存泄漏的程序:
我們來分析一下這段程序:
setenv是設置相關環境變量。
mtrace函數記錄malloc的trace log.
malloc函數用于分配堆內存
我們來編譯并運行一下(注意在編譯時帶-g參數):
顯然,編譯運行后,生成了trace log, 即test.log文件。用cat命令查看,貌似也發現不了什么東西,這是因為,姿勢錯了。
我們不僅僅要用test.log, 還要結合二進制文件a.out呢,如下:
ubuntu@VM-0-15-ubuntu:~$ mtrace a.out test.log - 0x00000000018ab010 Free 3 was never alloc'd 0x7fb41725fe9d - 0x00000000018ab0e0 Free 4 was never alloc'd 0x7fb41732a91f - 0x00000000018ab100 Free 5 was never alloc'd 0x7fb41739a23cMemory not freed: -----------------Address Size Caller 0x00000000018ab570??????0x8??at?/home/ubuntu/test.c:8 ubuntu@VM-0-15-ubuntu:~$Oh, nice啊!終于查出是第8行,存在內存泄漏。接下來,我們打算修復代碼,并再次驗證。
五. 修復后再驗證
修復內存泄漏后,代碼為:
#include <stdio.h>int main() {setenv("MALLOC_TRACE",?"test.log",?"1");mtrace();int *p = (int *)malloc(2 * sizeof(int));free(p);return 0; }編譯運行,并查看是否有內存泄漏:
ubuntu@VM-0-15-ubuntu:~$ gcc -g test.c ubuntu@VM-0-15-ubuntu:~$ ubuntu@VM-0-15-ubuntu:~$ ubuntu@VM-0-15-ubuntu:~$ ./a.out ubuntu@VM-0-15-ubuntu:~$ mtrace a.out test.log - 0x00000000006ad010 Free 4 was never alloc'd 0x7faa9b044e9d - 0x00000000006ad0e0 Free 5 was never alloc'd 0x7faa9b10f91f - 0x00000000006ad100 Free 6 was never alloc'd 0x7faa9b17f23c No memory leaks. ubuntu@VM-0-15-ubuntu:~$看到No memory leaks后,心情就好了,沒有內存泄漏了。
六. 最后的話
無論是筆試面試,還是平時工作,對于內存泄漏問題,都要有自己的一套處理辦法。
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
我的知識小密圈
關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。
歡迎點贊,關注,轉發,在看,您的每一次鼓勵,我都將銘記于心~
總結
以上是生活随笔為你收集整理的用mtrace定位内存泄漏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HiJson修改版,修改为按json字符
- 下一篇: 使用xsd文件验证xml