説明が長くて申し訳ありませんが、質問はそれほど簡単ではありません...
私のプロジェクトはGCなしで書かれました。最近、見つけられないメモリ リークが見つかりました。結果なしで新しいXcode Analyzerを使用しました。コードを 1 行ずつ読み、すべての alloc/release/copy/autorelease/mutableCopy/retain と pools を確認しました... - まだ何もありません。
前文: Standard Instruments と Omni Leak Checker が何らかの理由で機能しません (Omin Tool がアプリを拒否し、Instruments.app (Leaks) がメモリと CPU を大量に消費するため、使用する機会がありません)。
だから私は自分のコードを書いて使って "all" alloc/allocWithZone:/dealloc メッセージの統計をフックして追跡し、いくつかの単純な独自のリークチェックライブラリを書きたいと思っています (主な目標は、オブジェクトのクラス名にリークの可能性をマークすることだけです)。
私が使用する主なフッキング手法:
Method originalAllocWithZone = class_getClassMethod([NSObject class],@selector(allocWithZone:));
if (originalAllocWithZone)
{
imp_azo = (t_impAZOriginal)method_getImplementation(originalAllocWithZone);
if (imp_azo)
{
Method hookedAllocWithZone = class_getClassMethod([NSObject class],@selector(hookedAllocWithZone:));
if (hookedAllocWithZone)
{
method_setImplementation(originalAllocWithZone,method_getImplementation(hookedAllocWithZone));
fprintf(stderr,"Leaks Hook: allocWithZone: ; Installed\n");
}
}
}
- このようなコードで alloc メソッドをフックし、NSObject カテゴリ メソッドとして dealloc を割り当てます。
以前のメソッドの実装のために IMP を保存し、すべての alloc/allocWithZone: 呼び出しをインクリメント (+1) stat-array NSInteger 値として登録および計算し、dealloc 呼び出しをデクリメント (-1) として呼び出します。
エンドポイントとして、以前の実装を呼び出して値を返します。
コンセプトとしては、すべて問題なく動作します。
必要に応じて、クラスがクラス クラスター (NSString、NSPathStore2、NSDate、__NSCFDate など) の一部であることを検出することもできます... 正規化関数を使用します (ただし、以下で説明する問題については問題ありません)。
ただし、この手法にはいくつかの問題があります。
- すべてのクラスをキャッチできるわけではありません。たとえば、[NSDate date] は alloc/allocWithZone でキャッチされません: まったく、しかし、GDB で alloc 呼び出しを確認できます
- 自動シングルトン検出手法 (retainCount readind に基づく) を使用して、一部のオブジェクトを最終統計から自動的に除外しようとしているため、完全な Cocoa アプリケーション (実際には、単純な Objective-C コマンド ラインでさえも) を開始すると、NSLocale の作成が初期化前の段階でフリーズしますFoundation フレームワークが含まれているユーティリティには、main()) の前にいくつかの追加の初期化があります - GDB によって allocWithZone: が次々に呼び出されます....
ここにアップロードされた完全なコンセプト プロジェクト ドラフト ソース: http://unclemif.com/external/DILeak.zip (3.5 Kb)
Terminal.appからmakeを実行してコンパイルし、 . /conceptを実行して動作を確認します。
最初の質問: alloc & allocWithZone: メソッドをフックしても、すべてのオブジェクト割り当てをキャッチできないのはなぜですか?
2 番目の質問: allocWithZone をフックする理由: 一部のクラスの CFGetRetainCount (または [inst preserveCount]) でフリーズする...