0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

valgrind檢測內存問題的原理

嵌入式應用研究院 ? 來源:嵌入式應用研究院 ? 2023-05-23 09:30 ? 次閱讀

1、valgrind檢測原理

valgrind 是一個提供了一些 debug 和優(yōu)化的工具的工具箱,可以使得你的程序減少內存泄漏或者錯誤訪問。valgrind 默認使用 memcheck 去檢查內存問題。memcheck 檢測內存問題的原理如下圖所示:

469125e8-f8f5-11ed-90ce-dac502259ad0.png

Memcheck 能夠檢測出內存問題,關鍵在于其建立了兩個全局表。

valid-value map:對于進程的整個地址空間中的每一個字節(jié)(byte),都有與之對應的 8 個 bits;對于 CPU 的每個寄存器,也有一個與之對應的 bit 向量。這些 bits 負責記錄該字節(jié)或者寄存器值是否具有有效的、已初始化的值。

valid-address map:對于進程整個地址空間中的每一個字節(jié)(byte),還有與之對應的 1 個 bit,負責記錄該地址是否能夠被讀寫。在兩個全局表的基礎上,以如下方式進行檢測:

當要讀寫內存中某個字節(jié)時,首先檢查 valid-address map 中這個字節(jié)對應的 A bit。

如果該A bit顯示該位置是無效位置,memcheck 則報告讀寫錯誤。內核(core)類似于一個虛擬的 CPU 環(huán)境,這樣當內存中的某個字節(jié)被加載到真實的 CPU 中時,該字節(jié)對應的 V bit (在 valid-value map 中) 也被加載到虛擬的 CPU 環(huán)境中。一旦寄存器中的值,被用來產生內存地址,或者該值能夠影響程序輸出,則 memcheck 會檢查對應的 V bits,如果該值尚未初始化,則會報告使用未初始化內存錯誤。

不過valgrind也不是萬能的,對于棧上的內存空間操作就無法檢測到。

2、命令選項

基本命令:valgrind --leak-check=yes ./a.out arg1 arg2

為了能夠定位到源代碼的行,建議編譯時加上-g選項,并選擇O0優(yōu)化

3、使用示例

示例代碼:

#include
intmain()
{
int*x=(int*)malloc(10*sizeof(int));
x[10]=1;//問題1,越界了
return0;//問題2,沒有釋放內存
}

執(zhí)行valgrind檢測后的結果:

barret@Barret-PC:~$valgrind--leak-check=yes./a.out
==393==Memcheck,amemoryerrordetector
==393==Copyright(C)2002-2017,andGNUGPL'd,byJulianSewardetal.
==393==UsingValgrind-3.15.0andLibVEX;rerunwith-hforcopyrightinfo
==393==Command:./a.out
==393==
==393==Invalidwriteofsize4
==393==at0x10916B:main(a.cpp:6)
==393==Address0x4a47068is0bytesafterablockofsize40alloc'd
==393==at0x483B7F3:malloc(in/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==393==by0x10915E:main(a.cpp:5)
==393==
==393==
==393==HEAPSUMMARY:
==393==inuseatexit:40bytesin1blocks
==393==totalheapusage:1allocs,0frees,40bytesallocated
==393==
==393==40bytesin1blocksaredefinitelylostinlossrecord1of1
==393==at0x483B7F3:malloc(in/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==393==by0x10915E:main(a.cpp:5)
==393==
==393==LEAKSUMMARY:
==393==definitelylost:40bytesin1blocks
==393==indirectlylost:0bytesin0blocks
==393==possiblylost:0bytesin0blocks
==393==stillreachable:0bytesin0blocks
==393==suppressed:0bytesin0blocks
==393==
==393==Forlistsofdetectedandsuppressederrors,rerunwith:-s
==393==ERRORSUMMARY:2errorsfrom2contexts(suppressed:0from0)

結果解析如下:

==393==:執(zhí)行程序的進程ID

Invalid write of size 4:表示發(fā)現(xiàn)一個錯誤,這里顯示源代碼第6行有錯誤,這里很明顯是越界了,所以顯示invalid write錯誤

40 bytes in 1 blocks are definitely lost in loss record 1 of 1:內存泄露錯誤,泄漏的大小是10* sizeof(int)40byte。

LEAK summary也會顯示內存泄漏的情況

4、分析常見內存問題

4.1、寫入非法內存地址

上面的例子已經展示了這種情況,訪問分配的內存區(qū)域之外的空間,valgrind會上報如下的錯誤:

Invalid

write of size x

后跟調用棧信息

4.2、讀取非法內存地址

和上一個情況類似,不同 的是讀取而不是寫入,錯誤信息如下:

Invalid

read of size x

后跟調用棧信息

4.3、讀取未初始化內存區(qū)域

#include

intmain()
{
int*x=(int*)malloc(10*sizeof(int));
inta=x[1]+1;//不初始化就使用內存的值
free(x);
returna;
}

valgrind顯示如下錯誤:

==427==Syscallparamexit_group(status)**containsuninitialisedbyte(s)**
==427==at0x4938136:Exit(exit.c:31)
==427==by0x489BB41:__run_exit_handlers(exit.c:132)
==427==by0x489BBDF:exit(exit.c:139)
==427==by0x48790B9:(belowmain)(libc-start.c:342)

4.4、內存雙重釋放

示例:

#include

intmain()
{
int*x=(int*)malloc(10*sizeof(int));
free(x);//free兩次
free(x);
return0;
}

valgrind顯示如下錯誤,顯示兩次free的位置:

==436==Invalidfree()/delete/delete[]/realloc()
==436==**at0x483CA3F:free(in/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==436==by0x10919A:main(a.cpp:7)
==436==Address0x4a47040is0bytesinsideablockofsize40free'd
==436==at0x483CA3F:free(in/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==436==by0x10918E:main(a.cpp:6)**
==436==Blockwasalloc'dat
==436==at0x483B7F3:malloc(in/usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==436==by0x10917E:main(a.cpp:5)
審核編輯:彭靜
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 內存
    +關注

    關注

    8

    文章

    3025

    瀏覽量

    74054
  • 程序
    +關注

    關注

    117

    文章

    3787

    瀏覽量

    81049
  • Valgrind
    +關注

    關注

    0

    文章

    9

    瀏覽量

    6811

原文標題:Linux內存泄漏調試利器-valgrind

文章出處:【微信號:嵌入式應用研究院,微信公眾號:嵌入式應用研究院】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    檢測內存泄漏和內存違例,Valgrind不可少!

    Valgrind可以檢測內存泄漏和內存違例,但是用Valgrind生成的日志信息結合kcachegrind就可以查看C程序的執(zhí)行線路圖,調用
    的頭像 發(fā)表于 05-07 08:45 ?6494次閱讀
    <b class='flag-5'>檢測</b><b class='flag-5'>內存</b>泄漏和<b class='flag-5'>內存</b>違例,<b class='flag-5'>Valgrind</b>不可少!

    使用valgrind對代碼進行內存泄露檢測

    代碼可能存在內存泄露怎么辦?
    發(fā)表于 08-21 15:30 ?401次閱讀
    使用<b class='flag-5'>valgrind</b>對代碼進行<b class='flag-5'>內存</b>泄露<b class='flag-5'>檢測</b>

    嵌入式相關的動態(tài)檢測工具Valgrind簡介

    Valgrind是一套Linux下,開放源代碼(GPL V2)的仿真調試工具的集合。
    的頭像 發(fā)表于 11-08 09:41 ?2039次閱讀
    嵌入式相關的動態(tài)<b class='flag-5'>檢測</b>工具<b class='flag-5'>Valgrind</b>簡介

    一種利用調試軟件Valgrind進行嵌入式應用程序錯誤查找的技術

    本文介紹了一種利用調試軟件Valgrind進行嵌入式應用程序錯誤查找的技術,利用它可以高效、自動地查找出程序中的多種錯誤。首先介紹了嵌入式程序常見錯誤,接著研究了Valgrind的工作原理,介紹了利用Valgrind進行程序錯誤
    發(fā)表于 04-23 06:49

    valgrind是怎樣去移植源碼的

    嵌入式內存檢測工具-valgrind移植源碼較快)準備:解壓tar -jxvf valgrind-3.16.1.tar.bz2進入valgrind
    發(fā)表于 12-17 07:56

    寫了一個內存泄漏檢查工具

    嵌入式環(huán)境內存泄漏檢查比較麻煩,valgrind比較適合于在pc上跑,嵌入式上首先移植就很麻煩,移植完了內存比較小,跑起來也比較費勁。所以手動寫了一個內存泄漏檢查工具,基本思路是,ho
    發(fā)表于 12-17 08:25

    如何編譯使用內存泄漏的定位工具

    1.我們知道有個內存泄漏的定位工具: valgrind, 非常優(yōu)秀?,F(xiàn)在已經支持arm版本,下面看看如何編譯使用:2.下載源碼:
    發(fā)表于 12-17 08:13

    Linux C/C++內存泄漏檢測工具:Valgrind

    Valgrind 是一款 Linux下(支持 x86、x86_64和ppc32)程序的內存調試工具,它可以對編譯后的二進制程序進行內存使用監(jiān)測(C語言中的malloc和free,以及
    發(fā)表于 04-02 14:33 ?619次閱讀

    電腦的內存頻率該如何檢測

    ,選購電腦內存條的時候,需要檢測電腦的內存頻率,那么一個電腦的內存頻率到底該如何檢測呢,下面跟小編去學習幾招輕松解決
    發(fā)表于 06-14 10:55 ?2121次閱讀

    內存泄漏的檢測方法

    的。其實不然,防止內存泄露要從良好的編程習慣做起,另外重要的一點就是要加強單元測試(Unit Test),而valgrind就是這樣一款優(yōu)秀的工具。
    的頭像 發(fā)表于 06-20 11:01 ?3156次閱讀

    使用valgrind的callgrind工具進行多線程性能分析

    valgrind是開源的性能分析利器。 根據它的文檔,可以用它來檢查內存泄漏等問題,還可以用來生成函數(shù)的調用圖,就這兩個功能就足夠有吸引力了。
    的頭像 發(fā)表于 06-22 09:51 ?2961次閱讀

    valgrind基本功能介紹、基礎使用方法說明

    Valgrind是一套Linux下,開放源代碼(GPL V2)的仿真調試工具的集合。
    的頭像 發(fā)表于 11-14 12:40 ?2507次閱讀

    如何使用valgrind對代碼進行內存泄露檢測

    代碼可能存在 內存泄露 怎么辦? 使用 valgrind 可以對代碼進行內存泄露檢測valgrind下載安裝 安裝: 1 、tar –j
    的頭像 發(fā)表于 10-04 14:56 ?864次閱讀
    如何使用<b class='flag-5'>valgrind</b>對代碼進行<b class='flag-5'>內存</b>泄露<b class='flag-5'>檢測</b>

    如何發(fā)現(xiàn)內存泄漏

    檢測兩個角度介紹在 Linux 環(huán)境進行內存泄漏檢測的方法,并重點介紹靜態(tài)分析工具 BEAM、動態(tài)監(jiān)測工具 Valgrind 和 rational purify 的使用方法。相信通過本
    的頭像 發(fā)表于 11-13 15:41 ?604次閱讀

    如何檢測內存泄漏

    檢測內存泄漏是軟件開發(fā)過程中一項至關重要的任務,它有助于識別和解決那些導致程序占用過多內存資源,從而影響程序性能甚至導致程序崩潰的問題。以下將詳細闡述幾種常見的內存泄漏
    的頭像 發(fā)表于 07-30 11:50 ?1903次閱讀