結構前に調べたことですが、メモしておきます。
solarisでメモリ検査する方法が中々見つからなくて、結構探した覚えがあります。
手順
- 環境変数の設定
- プロセスの実行
- mdbの起動
- メモリリーク検査
- プロセスを開放
- c++の名前を複合
環境変数の設定
$ LD_PRELOAD=libumem.so
$ UMEM_DEBUG=default
$ export LD_PRELOAD
$ export UMEM_DEBUG
プロセスの実行
検査対象のプロセスを実行します。
mdbの起動
$mdb -p [pid]
ここでプロセスの動作は一時停止します。
メモリリーク検査
>::findleaks -d
結果が表示されます。
- findleaksがエラーになるときは
pargs -e [pid]
で環境変数の確認をしてみるといいです。 - libumemがロードできていない場合
>::load libumem
で手動でロードできます。
ex. リークあり
CACHE LEAKED BUFCTL CALLER
00162008 81 001ac168 libCrun.so.1`__1c2n6FI_pv_+0x2c
----------------------------------------------------------------------
Total 81 buffers, 3888 bytes
umem_alloc_48 leak: 81 buffers, 48 bytes each, 3888 bytes total
ADDR BUFADDR TIMESTAMP THREAD
CACHE LASTLOG CONTENTS
1ac168 1abcc0 a2c68a13d8570 1
162008 0 0
libumem.so.1`umem_cache_alloc+0x13c
libumem.so.1`umem_alloc+0x60
libumem.so.1`malloc+0x28
(中略)
main+0x1ec
_start+0x108
ex. リークなし
CACHE LEAKED BUFCTL CALLER
----------------------------------------------------------------------
Total 0 buffers, 0 bytes
プロセスを解放
>:R
プロセスは動作を再開します。
再びプロセスにアクセスするには
>:A [pid]
で行けます。(そもそもプロセスを止めずに、gcoreでcoreファイルを作成してそれをmdbで検査しても良いようです。)
c++の名前を復号
$ dem [名前]
c++関数の名前が復号できます。
参考にした主な情報ソース
簡単な例は下記Q&Aが参照している"Adam のブログ"記事に載っています。
・BigAdmin (DTraceのQ&A)
http://otn.oracle.co.jp/technology/global/jp/sdn/solaris/solaris10/dtrace/private/questions1.html#9
抜粋
Q: DTrace は、ユーザーアプリケーションのメモリ破壊やメモリリークの検出に使用できますか。 もし使用できるのであれば、
Purify のライセンスを破棄しても構わないのですか。A: これらの作業には、Purify よりも libumem(3LIB) の方が適しています。 libumem は、Solaris 10 の新しいメモリアロケータです。
詳細については、umem_debug(3MALLOC) のマニュアルページや、この件についての Adam のブログ
(http://blogs.sun.com/roller/page/ahl/?anchor=solaris_10_top_11_20) を参照してください。
・作者によるlibumemの説明
Jonathan Adams's Weblog