iOS アプリの dSYM ファイルからアドレス、ファイル名、および行番号を解析しました。私は基本的に、アドレスをファイル名と行番号にマップするテーブルを持っています。これはデバッグに非常に役立ちます。
を取得するactual lookup address
には、クラッシュ レポートのスタック トレース アドレスを使用し、https ://stackoverflow.com/a/13576028/2758234 の回答で指定されている式を使用します。だから、このようなもの。
(actual lookup address)
= (stack trace address) + (virtual memory slide) - (image load address)
私はそのアドレスを使用して、自分のテーブルで調べます。取得したファイル名は正しいですが、行番号は常に、スタック トレースで次の関数を呼び出した実際の行ではなく、呼び出された関数またはメソッドの最後を指しています。
どこかで読んだのですが、フレーム アドレスはシステム ポインター サイズの 2 倍に調整されているため、タグを解除する必要があることを覚えていません。したがって、32 ビット システムの場合、ポインターのサイズは 4 バイトであるため、次のような式を使用して 8 バイトを使用してタグを解除します。
(de-tagged address) = (tagged address) & ~(sizeof(uintptr_t)*2 - 1)
はuintptr_t
、Objective-C でポインターに使用されるデータ型です。
これを行った後、ルックアップは機能しますが、タグが解除されたアドレス以下である最も近いアドレスを見つけるなどのことをしなければなりません。
質問 #1 :
スタック フレーム アドレスのタグを解除する必要があるのはなぜですか? スタック トレースで、アドレスがまだ正しい場所を指していないのはなぜですか?
質問 #2 :
クラッシュ レポートに、フレームが欠落しているように見えることがあります。たとえば、which がwhich を呼び出すとfunction1()
、スタック トレースに次のように表示されます。function2()
function3()
function4()
0 Exception
1 function4()
2 function3()
4 function1()
また、(フレーム 2、上記) のスタック トレース アドレスfunction3()
は、タグを外した後でも、正しい行番号を指していません (ただし、正しいファイルです)。これは、Xcode にクラッシュ レポートをシンボリックさせた場合でも見られます。
なぜこれが起こるのですか?