Xcodeでのデバッグ時、SIGABRTで落ちる場合の対処方法


時々ハマるのでメモ。


Xcodeデバッグしているとき、SIGABRTで落ちると、スタックトレースも何も参照できずにmain関数で止まるときがある。
この場合、デバッグが非常に困難になるのだけれど、これがなかなか、割と良く起きたりする。


これの対処方法は以下の記事を見るべし。素晴らしい内容です。


アプリがクラッシュしちゃった。さて、どうしましょう- Part 1
http://www.raywenderlich.com/ja/50797/


リンク先で解説されているのは、XcodeでのExceptionブレークポイントの設定方法。
Exceptionブレークポイントを設定しておくと、例外発生時にデバッガが自動でブレークする。
このブレークポイントを設定しておくことで、実際に落ちる直接の原因となったコードが簡単に見つかる場合がある。


以下、実例。


Exceptionブレークポイント設定前(main関数で止まる)


設定後(Exception発生箇所で止まる)


この実例は、NULLポインタに*をつけて参照しようとした場合に落ちたケースである。
「設定後」の画像で確認できるinit関数の引数としてNULLが渡されると、if文の条件式内で typeid(*NULL) という不正参照が起こり、SIGABRTで落ちる模様。
Exceptionブレークポイントを設定する前は、SIGABRT発生時にmain関数で止まってしまい、ロクなエラーログも残らないので問題の起きている箇所が特定できなかった(表示されるエラーログは「libc++abi.dylib: terminate called throwing an exception」という一行のみ)。
そこでExceptionブレークポイントを設定したところ、実際に問題が起きる箇所で停止させることができた。


なお、この実例はあくまで一例で、SIGABRTで落ちるケースは他にも様々なものが存在する(ググればわかる)。


注意点として、Exceptionブレークポイントを設定すると、今まで普通に動いていた箇所(ライブラリのコード内など)でもブレークが発生したりする。
この場合、「Debug | Continue ( Command + Control + Y )」することでたいてい続行できるので(何度も止まる場合があるが我慢強く Continueし続ければ先に進める)、とりあえず続行させるか、問題発生直前でブレークポイントを有効にするなどして問題を再現させ、問題箇所を特定すると良い。