萬盛學電腦網

 萬盛學電腦網 >> Linux教程 >> Linux系統中怎麼使用valgrind檢查內存

Linux系統中怎麼使用valgrind檢查內存

  在使用Linux系統編寫代碼過程中,有可能會發送內存洩露的問題。所以用戶就應該要學會檢查內存,那麼Linux如何檢查內存呢?一般都是使用一些工具,本文就來介紹一下Linux系統中怎麼使用valgrind檢查內存。

Linux系統中怎麼使用valgrind檢查內存

  請看一下代碼:

  #include 《stdlib.h》

  #include 《stdio.h》

  #include 《string.h》

  static void mem_leak1(void)

  {

  char *p = malloc(1);

  }

  static void mem_leak2(void)

  {

  FILE *fp = fopen(“test.txt”, “w”);

  }

  static void mem_overrun1(void)

  {

  char *p = malloc(1);

  *(short*)p = 2;

  free(p);

  }

  static void mem_overrun2(void)

  {

  char array[5];

  strcpy(array, “hello”);

  }

  static void mem_double_free(void)

  {

  char *p = malloc(1);

  free(p);

  free(p);

  }

  static void mem_use_wild_pointer(void)

  {

  char *p = (void*)0x80184800;

  *p = 1;

  }

  static void mem_free_wild_pointer(void)

  {

  char *p;

  free(p);

  }

  int main()

  {

  mem_leak1();

  mem_leak2();

  mem_overrun1();

  mem_overrun2();

  mem_double_free();

  //mem_use_wild_pointer();

  mem_free_wild_pointer();

  return 0;

  }

  常見的內存問題:

  1. 動態內存洩露;

  2. 資源洩露,這裡以文件描述符為例;

  3. 動態內存越界;

  4.數組內存越界;

  5.動態內存double free;

  6.使用野指針,即未初始化的指針;

  7.釋放野指針,即未初始化的指針;

  其中由於本示例代碼過於簡單,第6中情況,使用野指針會直接導致crash,所以在main中,並沒有真正的調用那個示例代碼。由於 valgrind只能檢測執行到的代碼,所以在後面的報告中,不會報告第6種錯誤情況。但是,在大型的項目中,有可能使用野指針並不會導致程序 crash。另外上面的7中情況,有些情況嚴格的說,實際上可以歸為一類。 上一頁12下一頁共2頁

  執行valgrind來檢測內存錯誤:

  valgrind --track-fds=yes --leak-check=full --undef-value-errors=yes 。/a.out

  上面那些option的具體含義,可以參加valgrind --help,其中有些option默認就是打開的,不過我習慣於明確的使用option,以示清晰。

  執行後的報告:

  ==2326== Memcheck, a memory error detector

  ==2326== Copyright (C) 2002-2009, and GNU GPL‘d, by Julian Seward et al.

  ==2326== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info

  ==2326== Command: 。/a.out

  ==2326==

  /* 這裡檢測到了動態內存的越界,提示Invalid write。*/

  ==2326== Invalid write of size 2

  ==2326== at 0x80484B4: mem_overrun1 (in /home/fgao/works/test/a.out)

  ==2326== by 0x8048553: main (in /home/fgao/works/test/a.out)

  ==2326== Address 0x40211f0 is 0 bytes inside a block of size 1 alloc’d

  ==2326== at 0x4005BDC: malloc (vg_replace_malloc.c:195)

  ==2326== by 0x80484AD: mem_overrun1 (in /home/fgao/works/test/a.out)

  ==2326== by 0x8048553: main (in /home/fgao/works/test/a.out)

  ==2326==

  /* 這裡檢測到了double free問題,提示Invalid Free */

  ==2326== Invalid free() / delete / delete[]

  ==2326== at 0x40057F6: free (vg_replace_malloc.c:325)

  ==2326== by 0x8048514: mem_double_free (in /home/fgao/works/test/a.out)

  ==2326== by 0x804855D: main (in /home/fgao/works/test/a.out)

  ==2326== Address 0x4021228 is 0 bytes inside a block of size 1 free‘d

  ==2326== at 0x40057F6: free (vg_replace_malloc.c:325)

  ==2326== by 0x8048509: mem_double_free (in /home/fgao/works/test/a.out)

  ==2326== by 0x804855D: main (in /home/fgao/works/test/a.out)

  ==2326==

  /* 這裡檢測到了未初始化變量 */

  ==2326== Conditional jump or move depends on uninitialised value(s)

  ==2326== at 0x40057B6: free (vg_replace_malloc.c:325)

  ==2326== by 0x804853C: mem_free_wild_pointer (in /home/fgao/works/test/a.out)

  ==2326== by 0x8048562: main (in /home/fgao/works/test/a.out)

  ==2326==

  /* 這裡檢測到了非法是否野指針 */

  ==2326== Invalid free() / delete / delete[]

  ==2326== at 0x40057F6: free (vg_replace_malloc.c:325)

  ==2326== by 0x804853C: mem_free_wild_pointer (in /home/fgao/works/test/a.out)

  ==2326== by 0x8048562: main (in /home/fgao/works/test/a.out)

  ==2326== Address 0x4021228 is 0 bytes inside a block of size 1 free’d

  ==2326== at 0x40057F6: free (vg_replace_malloc.c:325)

  ==2326== by 0x8048509: mem_double_free (in /home/fgao/works/test/a.out)

  ==2326== by 0x804855D: main (in /home/fgao/works/test/a.out)

  ==2326==

  ==2326==

  /*

  這裡檢測到了文件指針資源的洩露,下面提示說有4個文件描述符在退出時仍是打開的。

  描述符0,1,2無需關心,通過報告,可以發現程序中自己明確打開的文件描述符沒有關閉。

  */

  ==2326== FILE DESCRIPTORS: 4 open at exit.

  ==2326== Open file descriptor 3: test.txt

  ==2326== at 0x68D613: __open_nocancel (in /lib/libc-2.12.so)

  ==2326== by 0x61F8EC: __fopen_internal (in /lib/libc-2.12.so)

  ==2326== by 0x61F94B: fopen@@GLIBC_2.1 (in /lib/libc-2.12.so)

  ==2326== by 0x8048496: mem_leak2 (in /home/fgao/works/test/a.out)

  ==2326== by 0x804854E: main (in /home/fgao/works/test/a.out)

  ==2326==

  ==2326== Open file descriptor 2: /dev/pts/4

  ==2326==

  ==2326==

  ==2326== Open file descriptor 1: /dev/pts/4

  ==2326==

  ==2326==

  ==2326== Open file descriptor 0: /dev/pts/4

  ==2326==

  ==2326==

  ==2326==

  /* 堆信息的總結:一共調用4次alloc,4次free。之所以正好相等,因為上面有一函數少了free,有一個函數多了一個free */

  ==2326== HEAP SUMMARY:

  ==2326== in use at exit: 353 bytes in 2 blocks

  ==2326== total heap usage: 4 allocs, 4 frees, 355 bytes allocated

  ==2326==

  /* 檢測到一個字節的內存洩露 */

  ==2326== 1 bytes in 1 blocks are definitely lost in loss record 1 of 2

  ==2326== at 0x4005BDC: malloc (vg_replace_malloc.c:195)

  ==2326== by 0x8048475: mem_leak1 (in /home/fgao/works/test/a.out)

  ==2326== by 0x8048549: main (in /home/fgao/works/test/a.out)

  ==2326==

  /* 內存洩露的總結 */

  ==2326== LEAK SUMMARY:

  ==2326== definitely lost: 1 bytes in 1 blocks

  ==2326== indirectly lost: 0 bytes in 0 blocks

  ==2326==

copyright © 萬盛學電腦網 all rights reserved