ゾンビオブジェクトを検出する (Instruments編)

先日のエントリではXcode環境変数アロケーションヒストリログを使用して解放済みのオブジェクト=ゾンビオブジェクトを検出する方法を書いた。これでも十分使えるが、Xcodeではもっとスマートにこの作業を行うことが出来る。

Instruments

Xcode4.2と共にインストールされているInstrumentsは単体で使用できるプロファイリングツールであり、開発するアプリケーション、既存のアプリケーションの各種解析を行うことが出来る。

InstrumentsはXcodeと統合されており、Xcodeのプロジェクトターゲットに対してプロファイリングを実行することが出来るが、ゾンビオブジェクトの検出もすぐに実施することが出来る。

手順

対象のプロジェクトを開いた状態で、Xcodeのメニューから「Product->Profile」を選択する

Instrumentsのダイアログが起動するので、実施したいプロファイリングの種類を選択する。プロファイルのターゲットはプロジェクトの実行対象が使用される。私はiOSのシミュレータを実行するので、ここでも「iOS Simulator」で選択可能なものから選ばなくてはならない。今回はゾンビオブジェクトの検出が目的なので、「Zombies」を選択する※1

上記プロファイリングの種類を選択するとアプリケーションが起動して、同時にInstrumentsも記録モードで起動されてプロファイリングが開始されるので、適宜、アプリケーションが異常終了する操作(ここではテーブルビューの行を画面外部にスクロールする)を行えば良い。

Instrumentsはゾンビ(既に解放されているオブジェクト)を自動的に検出してプロファイルを停止してくれる。

この状態ではどこで検出されたかの情報が全く分らない。
なので、メッセージの横の矢印のアイコンをクリックすると下部ペインに検出されたゾンビオブジェクトがゾンビになった経緯が幾つかの情報と共に時系列に並ぶので、これがゾンビの原因を知る最も根本的な情報になる。
更にこの段階でビューボタンの右端のボタンを押下することで、サマリ情報の行毎に実行されたスタックトレースが表示される。

右側のスタックトレースはそのモジュールの種類によってアイコンが違うが、その中でソースコードがあるモジュールに関しては、このように対応するソースコードにジャンプすることができるので原因の特定に役立つだろう。

プロファイルの結果分ったこと

Instrumentsによりゾンビオブジェクトの発生が検知されたならば、あとはその原因を突き止めるだけである。


肝心の"EXC_BAD_ACCESS"だが、プロファイル結果サマリ情報の#1行目にある[NSString stringWithFormat]がその発端だろうと推測できる。
このメソッドは内部で生成したNSStringのインスタンスに対してAutoReleaseをマークしており、その後何らかのきっかけで呼ばれた※1[NSAutoreleasePool release]により意図せずオブジェクトが解放されてしまったと考えることが出来る。


以上、InstrumentsはEXC_BAD_ACCESSの原因の一つである"ゾンビ"を簡単に検出することができるので非常に有用であることが分るだろう。
前回のXcodeを使った方法では環境変数とBSDコマンドを使う必要があったが、InstrumentsはXcodeと統合されておりプロジェクトに対しては何のパラメタの追加も必要が無い。非常に簡単なのでどんどん利用しようと思う。


※1: AutoreleasePoolの解放は至る所で実行されており、このケースではNSRunLoopである。