Valgrind簡介

Valgrind是一款用於內存調試、檢測內存泄露、分析程序性能的工具。Valgrind工作在Linux環境下。Valgrind的官方網站是: http://valgrind.org。
 
在Linux系統下,可以用命令wget http://valgrind.org/downloads/valgrind-3.7.0.tar.bz2來下載valgrind。
 
Valgrind語法是:
  valgrind [valgrind options] your_program [your_program options]
 
一些啓動參數的意義:
  -h --help 幫助信息
  -q --quiet 安靜模式
  --version 顯示版本
  -v --verbose 顯示詳細信息
  --trace-children=<yes|no> 是否追蹤子進程[默認no]
  --log-file=<filename> 將輸出打印到文件
  --xml=<yes|no> 以xml格式輸出
  --leak-check=<no|summary|full> 是否進行內存泄露檢查[默認summary]
  --xml-file=<filename> 制定xml輸出文件
  --vgdb=<no|yes|full> 是否使用gdb調試
 
valgrind會將一個庫函數,比如malloc、new等重新定位爲valgrind內部的函數,來檢查內存使用情況。當valgrind監測到內存使用問題時,會立即輸出結果,而不是像gprof那樣,在程序調正常退出時才輸出結果。當使用valgrind運行程序時,如果使用了--vgdb=yes或者--vgdb=full,可以使用GDB來調試程序。方法如下:
  valgrind --vgdb=yes ./your_program
  gdb your_program
  (gdb) target remote | vgdb --pid=YOUR_PROGRAM_PID
其中,--pid部分不是必須的,但如果有多個your_program在運行,必須使用這個參數時vgdb找到正確的進程。
 
valgrind可以檢測內存泄露、非法指針、未初始化變量、非法釋放。valgrind不檢查靜態數組的訪問越界。
 
下面給出一個例子:
/*
 * ValgrindSample.cpp
 *
 * g++ -g -o ValgrindSample ValgrindSample.cpp
 * valgrind --leak-check=full --log-file=ValgrindSample.report ./ValgrindSample
 */
 
#include <cstdlib>
#include <new>
 
void memoryLeak(void);
void invalidPointer(void);
void uninitializedVariable(void);
void invalidRelease(void);
void outOfRange(void);
 
int main(void){
    memoryLeak();
    invalidPointer();
    uninitializedVariable();
    invalidRelease();
    outOfRange();
 
    return 0;
}
 
void memoryLeak(void){
    void *p = malloc(10);
    int *pi = new int(0);
}
 
void invalidPointer(void){
    char *pc = (char *)malloc(10);
    pc[10] = 'a';
}
 
void uninitializedVariable(void){
    int x;
    int y;
 
    if (x != 0){
        y = x + 1; 
    }
}
 
void invalidRelease(void){
    void *p =malloc(10);
    free(p);
    free(p);
 
    int *pi = new int(0);
    delete pi;
    delete pi;
}
 
void outOfRange(void){
    char x[10];
    x[11] = 'a';
}
 
valgrind輸出:
==8349== Memcheck, a memory error detector
==8349== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8349== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==8349== Command: ./a.out
==8349== Parent PID: 7943
==8349== 
==8349== Invalid write of size 1
==8349== at 0x4006A6: invalidPointer() (ValgrindSample.cpp:35)
==8349== by 0x400735: main (ValgrindSample.cpp:20)
==8349== Address 0x4c200ea is 0 bytes after a block of size 10 alloc'd
==8349== at 0x4A0776F: malloc (vg_replace_malloc.c:263)
==8349== by 0x400699: invalidPointer() (ValgrindSample.cpp:34)
==8349== by 0x400735: main (ValgrindSample.cpp:20)
==8349== 
==8349== Conditional jump or move depends on uninitialised value(s)
==8349== at 0x400670: uninitializedVariable() (ValgrindSample.cpp:42)
==8349== by 0x40073A: main (ValgrindSample.cpp:21)
==8349== 
==8349== Invalid free() / delete / delete[] / realloc()
==8349== at 0x4A07384: free (vg_replace_malloc.c:427)
==8349== by 0x4006FF: invalidRelease() (ValgrindSample.cpp:50)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== Address 0x4c20130 is 0 bytes inside a block of size 10 free'd
==8349== at 0x4A07384: free (vg_replace_malloc.c:427)
==8349== by 0x4006F6: invalidRelease() (ValgrindSample.cpp:49)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== 
==8349== Invalid free() / delete / delete[] / realloc()
==8349== at 0x4A07096: operator delete(void*) (vg_replace_malloc.c:457)
==8349== by 0x400725: invalidRelease() (ValgrindSample.cpp:54)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== Address 0x4c20180 is 0 bytes inside a block of size 4 free'd
==8349== at 0x4A07096: operator delete(void*) (vg_replace_malloc.c:457)
==8349== by 0x40071C: invalidRelease() (ValgrindSample.cpp:53)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== 
==8349== 
==8349== HEAP SUMMARY:
==8349== in use at exit: 24 bytes in 3 blocks
==8349== total heap usage: 5 allocs, 4 frees, 38 bytes allocated
==8349== 
==8349== LEAK SUMMARY:
==8349== definitely lost: 24 bytes in 3 blocks
==8349== indirectly lost: 0 bytes in 0 blocks
==8349== possibly lost: 0 bytes in 0 blocks
==8349== still reachable: 0 bytes in 0 blocks
==8349== suppressed: 0 bytes in 0 blocks
==8349== Rerun with --leak-check=full to see details of leaked memory
==8349== 
==8349== For counts of detected and suppressed errors, rerun with: -v
==8349== Use --track-origins=yes to see where uninitialised values come from
==8349== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4)
 
 
參考資料:
valgrind官方網站:www.valgrind.org
一份valgrind --help的翻譯:http://www.cppblog.com/Wealth/archive/2008/06/04/52118.html
通過例子介紹valgrind用法:http://www.cprogramming.com/debugging/valgrind.html
valgrind用法簡介:http://www.cnblogs.com/napoleon_liu/articles/2001802.html
http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/
http://www.redhat.com/magazine/015jan06/features/valgrind/
http://www.stlinux.com/devel/debug/mudflap
http://rdc.taobao.com/blog/cs/?p=455
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章