Top | Wiki | Blog | Github  

LeakTracer

C/C++ のメモリリークのチェックモジュール.比較的簡単に導入でき,ミスを防止できるのでお薦め.

頒布されているサンプルプログラム(test.cc)から適当にラッパクラスを作成し,main() の先頭においてオブジェクトを置くだけで,プログラム全体のリークを監視できる.

LeakTracer

(注意)このトピックで紹介するのは,Michael Gopshtein氏が頒布している LeakTracer-mg です.上記リンク先でAvailabilityのパラグラフをよく読んでください.頒布されているtar.gzには,test.cc や parse_leaktracer_out.pl が含まれており,それを参考にしています.

リークの発見

次のサンプルクラスを利用する場合,プログラム実行後,leaks.out なる解析ファイルが出力される.これを,parse_leaktracer_out.pl にかませば,リークしているかが分かる.

./parse_leaktracer_out.pl hoge leaks.out

めでたくリークが無かった場合,

Processing "leaks.out" log for "hoge"
Matching addresses to "hoge"
found 0 leak(s)

などと表示される.

サンプルクラス

LeakTrace クラスを定義する.クラスを記述するヘッダファイルとの位置関係は,カレントディレクトリの下に MemoryTrace.hpp がある状態.

このクラスをmain(){ LeakTrace lt; } のように,インスタンス生成すれば,そこからプログラムが終了し,LeakTrace のデストラクタが呼ばれるまでのメモリリークを観測することができる.

#ifndef INC_MEMORYTRACE_H
#include "./LeakTrace/MemoryTrace.hpp"
#endif
class LeakTrace{
public:
	LeakTrace(){
		// インスタンス生成と同時に観測開始.
		leaktracer::MemoryTrace::GetInstance().startMonitoringAllThreads();
	};
	~IcpLeakTrace(){
		// デストラクタが呼ばれるとき,観測をやめる
		leaktracer::MemoryTrace::GetInstance().stopAllMonitoring();
		std::ofstream oleaks;
		oleaks.open("./leaks.out", std::ios_base::out);
		ASSERT((oleaks.is_open()),"Failed to write data to leaks.out\n");
		leaktracer::MemoryTrace::GetInstance().writeLeaks(oleaks);
	};
	inline void stopTrace() const {
		leaktracer::MemoryTrace::GetInstance().stopMonitoringAllocations();
	};
};

コンパイル&リンク

LeakTrace ディレクトリ内部で Make をすれば,libleaktrace.a が作成される.LeakTrace クラスを利用するプログラムにおいて,このライブラリへのリンクを含めればよい(-Lにて).フラグには,-lleaktrace を利用する.

parse_leaktracer_out.plの解析結果が変な時

Mac の場合,該当スクリプトが利用する addr2line コマンドが存在しない.これは,gaddr2line として binutils に含まれ頒布されている.

$sudo port install binutils

/opt/local/bin/gaddr2line としてインストールされるので,パスを通した上で parse_leaktracer_out.pl の add2line を gadd2line とすればよい.