さて、ブレークポイントがobjc_exception_throw
トリガーされたと想像してください。デバッガー プロンプトの前に座って、例外オブジェクトに関する詳細情報を取得したいと考えています。どこで見つけられるでしょうか?
ベストアンサー1
例外オブジェクトは の最初の引数として渡されますobjc_exception_throw
。LLDB は、正しい呼び出し規約で引数を参照するための$arg1
..変数を提供するため、例外の詳細を簡単に出力できます。$argn
(lldb) po $arg1
(lldb) po [$arg1 name]
(lldb) po [$arg1 reason]
これらのコマンドを実行する前に、コール スタック内のフレームを必ず選択してくださいobjc_exception_throw
。ステージ上でこれが実行される様子を見るには、WWDC15 セッション ビデオの「高度なデバッグとアドレス サニタイザー」を参照してください。
古い情報
GDB を使用している場合、最初の引数を参照する構文は、実行しているアーキテクチャの呼び出し規則によって異なります。実際の iOS デバイスでデバッグしている場合、オブジェクトへのポインターはレジスタにありますr0
。これを印刷したり、メッセージを送信したりするには、次の簡単な構文を使用します。
(gdb) po $r0
(gdb) po [$r0 name]
(gdb) po [$r0 reason]
iPhone シミュレータでは、すべての関数引数がスタックに渡されるため、構文はかなりひどいものになります。これに到達できる最短の式は です*(id *)($ebp + 8)
。手間を省くために、便利な変数を使用することをお勧めします。
(gdb) set $exception = *(id *)($ebp + 8)
(gdb) po $exception
(gdb) po [$exception name]
(gdb) po [$exception reason]
$exception
ブレークポイントにコマンド リストを追加することで、ブレークポイントがトリガーされるたびに自動的に設定することもできますobjc_exception_throw
。
(私がテストしたすべてのケースで、ブレークポイントに到達した時点で例外オブジェクトがeax
およびedx
レジスタにも存在していたことに注意してください。ただし、常にそうなるかどうかはわかりません。)
以下のコメントから追加:
でlldbのスタック フレームを選択しobjc_exception_throw
、次のコマンドを入力します。
(lldb) po *(id *)($esp + 4)