開発事例:メモリリークを検出する関するインストールメモ(2002/05/02) 
 

メモリリーク ぅう?

C/C++ でプログラム開発をしていると、アドレスの開放を忘れたり、間違ったアドレスを開放しちゃったりしてメモリリーク(core)が出るのです〜〜〜ぅ。たちの悪い事にこのメモリリークって奴は、何処で起こっているのか判断しずらい時が往々にしてあり、毎回悩まされてしまうのです。

で下記のツール(ライブラリ)を使うと、ちょっと楽になるって代物なんですぅ (^o^)丿

本家 : mpatrol (英語サイト)

本家 : ccmalloc (英語サイト)

参考 : Cプログラミングのメモ

 

mpatrol 1.4.8 の設定方法

1.mpatrol ライブラリをインストールします。

% cd /opt/local/src
% wget http://www.cbmamiga.demon.co.uk/mpatrol/files/mpatrol_1.4.8.tar.gz
% gzip -cd mpatrol_1.4.8.tar.gz | tar xf -
% cd mpatrol
% cd pkg/auto
% ./setup
% ./configure
% make
% su
# make install

2.failサンプルプログラムを実行してみましょう。

% setenv MPATROL_OPTIONS "LOGALLOCS LOGFREES USEDEBUG"
% gcc -g -o test1 test1.c -I/usr/local/include -lmpatrol -lbfd -liberty -lelf
% ./test1

3.どこが悪いのか判断してみましょう。下記の例ですと mallocしたアドレス(0x08061074)と、そのアドレスをfreeするアドレス(0x08061075)が異なっているのでエラーとなってしまいました。

% vi mpatrol.log
    ALLOC: malloc (18, 16 bytes, 4 bytes) [main|test1.c|36]
        0x080506D2 main+38
        0x080505C3 _start+87

    returns 0x08061074

    FREE: free (0x08061075) [main|test1.c|37]
        0x080506FD main+81
        0x080505C3 _start+87

    ERROR: [MISMAT]: free: 0x08061075 does not match allocation of 0x08061074
        0x08061074 (16 bytes) {malloc:18:0} [main|test1.c|36]
        0x080506D2 main+38
        0x080505C3 _start+87

4.プログラム動作が正常か異常かは、mleak コマンドの結果により判断することができます。

正常の場合:
    unfreed allocations: 0 (0 bytes)

異常の場合:
    unfreed allocations: 1 (16 bytes)
        0x08061074 (16 bytes) {malloc:18:0} [main|test1.c|36]
            0x080506D2 main+38
            0x080505C3 _start+87

ccmalloc 0.3.9 の設定方法

1.ccmalloc ライブラリをインストールします。

% cd /opt/loca/src
% wget http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/ccmalloc-0.3.9.tar.gz
% gzip -cd ccmalloc-0.3.9.tar.gz | tar xf -
% cd ccmalloc-0.3.9
% ./configure
% make
% cp ccmalloc.cfg ~
% vi ~/ccmalloc.cfg 
    log /tmp/ccmalloc.log
% su
# make install

2.コンパイル方法です。

% gcc -g -o ctest01 ctest01.c /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl

3.実行するとトレースが表示されます。ちょっと見にくいなぁー。

.--------------------------------------------------------------------------.
|================ ccmalloc-0.3.9 (C) 1997-2001 Armin Biere ================|
+--------------------------------------------------------------------------+
| executable = ./ctest01 |
| startup file = .ccmalloc (but not found) |
| log file = stderr |
| start time = Thu May 2 17:19:03 2002 |
| operating system = SunOS 5.8 i86pc on rain |
+--------------------------------------------------------------------------+
| only-count = 0 keep-deallocated-data = 0 |
| check-interval = 0 check-free-space = 0 |
| check-start = 0 file-info = 1 |
| chain-length = 0 additional-line = 1 |
| check-underwrites = 0 print-addresses = 0 |
| check-overwrites = 0 print-on-one-line = 0 |
| sort-by-wasted = 1 sort-by-size = 1 |
| # only-log-chain = 0 continue = 0 |
| # dont-log-chain = 0 statistics = 0 |
| debug = 0 library-chains = 0 |
| load-dynlibs = 0 align-8-byte = 0 |
| only-wasting-alloc= 1 |
`--------------------------------------------------------------------------'

.---------------.
|ccmalloc report|
=======================================================
| total # of| allocated | deallocated | garbage |
+-----------+-------------+-------------+-------------+
| bytes| 20 | 20 | 0 |
+-----------+-------------+-------------+-------------+
|allocations| 1 | 1 | 0 |
+-----------------------------------------------------+
| number of checks: 1 |
| number of counts: 2 |
| retrieving function names for addresses ... done. |
| reading file info from gdb ... done. |
| sorting by number of not reclaimed bytes ... done. |
| number of call chains: 0 |
| number of ignored call chains: 0 |
| number of reported call chains: 0 |
| number of internal call chains: 0 |
| number of library call chains: 0 |
`------------------------------------------------------