私のMacアプリは、実行ループでexc_bad_accessを使用してクラッシュしています。そこでNSZombiesを有効にしましたが、期待どおりのエラーは表示されません(オブジェクトの割り当てが解除されていないため)。
しかし、コンソールに有用なNSZombieログが見つかりません。問題を特定する方法はありますか?
私のMacアプリは、実行ループでexc_bad_accessを使用してクラッシュしています。そこでNSZombiesを有効にしましたが、期待どおりのエラーは表示されません(オブジェクトの割り当てが解除されていないため)。
しかし、コンソールに有用なNSZombieログが見つかりません。問題を特定する方法はありますか?
それは挑戦的です。Cocoaでのこのエラーの最も一般的な原因は、アクセサーを使用するのではなく、ivarに直接アクセスすることです。アクセサは、メモリクラッシュの大部分を解消します。
とはいえ、メモリエラーの原因はこれらだけではありません。他の方法でメモリにアクセスしている可能性があります。NSZombie
1つの特定のことを行います。オブジェクトの割り当てを解除するとき、NSZombie
「実際にはオブジェクトの割り当てを解除しないでください」と言います。代わりに、オブジェクトをゾンビオブジェクトに変換し、メッセージを送信するとエラーを出力します。ただし、これは、割り当てが解除されたインスタンスにメッセージを送信したことがクラッシュの原因である場合にのみ役立ちます。それは他にもたくさんあるかもしれません。
まず、クラッシュスタック自体から始める必要があります。スタックを調べて、それがどのような種類のオブジェクトであるか、または誰がそれを呼び出しているかを確認します。
TN2124 、特にBSDメモリアロケータのセクション、およびメモリ使用パフォーマンスガイドラインのMallocデバッグ機能の有効化のセクションをお読みください。NSZombie
使用できるツールよりも低レベルのツールがあります。MallocScribble
多くの場合、最も便利です。割り当て解除されたメモリを0x55で上書きするため、クラッシュが早く発生する可能性が高くなり、デバッガーで割り当て解除されたメモリを簡単に検出できるようになります。MallocPreScribble
初期化されていないメモリを見つけるのに役立ちますが、これは実際には生のmalloc
呼び出しを行う場合にのみ役立ちます。ObjCオブジェクトは常に事前に初期化されています。
そしてもちろん、あなたはあなたの探偵の帽子をかぶらなければなりません。プログラムのどの部分が最も疑わしいですか?マルチスレッド作業を行っていますか(正しくロックしないとメモリがクラッシュする可能性があります)。
それが簡単に再現されるなら、あなたはそれを理解するでしょう。それがたまにしか起こらないのなら、まあ...私はそのようなバグを何ヶ月も時々探してきました。時々それはただ難しいです。
そのためにはメモリプロファイラーを使用する必要があります。プロファイルオプションを使用してビルドし、リークを選択するだけです。