2010年3月20日土曜日

addr2line(相当)のshared library対応版

メモリリークを検出するためにmalloc/freeの呼び出しをログに残すようにしました。あとはログを解析して、対応するfreeが無いmallocを見つけ、そのmallocのコールスタックを表示してやればOKです。

ログには、コールスタック中の各関数のアドレスが記録されているので、これを関数名に変換したいです。「addr2lineでできるだろう」と思っていたら、addr2lineはshared libraryには対応していないことがわかりました。つまり、動的にロードされたライブラリ中の関数名は、addr2lineでは分からないのです。

既存のツールがあると思うのですが、見つからなかったので自作しました。
方針は以下のとおり。
  1. 解析したいプロセスのmapsファイル (/proc/[PID]/maps)をコピーしておく。
  2. 問題のアドレスとmapsファイルから、どのshared library(のtext region)に含まれているかを調べる
  3. 該当のshared libraryのsymbol tableを参照して、どの関数かを調べる
  4. 表示する

これでうまくいかないケースとして、
  • dlopenを使ってdynamic linkしていて、取得したmapsファイルにmemory map情報が残っていない。
  • トランポリンコード
が考えられますが、かなり稀な状況なので現実的には問題にならないでしょう。
コードはgithubに置いてあるaddr2sym.rbです。

0 件のコメント:

コメントを投稿