IOS開発の学習を開始してから、いくつかの異なるタイプのクラッシュログを見てきました。
例外タイプ:EXC_BAD_ACCESS(SIGSEGV)は、解放されたオブジェクトにアクセスしていることを意味します。
しかし、知らない:
例外タイプ:EXC_BAD_ACCESS(SIGBUS)
例外タイプ:EXC_CRASH(SIGABRT)
例外タイプ:EXC_BREAKPOINT(SIGTRAP)
IOSクラッシュログの例外タイプの数とそれらの意味を知っていますか?
例外タイプ:EXC_BAD_ACCESS(SIGSEGV)は、リリースされたオブジェクトにアクセスしていることを意味します。
いいえ
SIGSEGVはセグメンテーションフォールトです。つまり、無効なメモリアドレスにアクセスしようとしています。
これらの例外(実際にはシグナルです)は、Objective-CではなくCに関連しています。したがって、Objective-Cオブジェクトがなくてもこのような例外を取得できます。
シグナルは例外ではないことに注意してください。つまり、@try
および@catch
ブロックでそれらをキャッチすることはできません。
signal
およびsigaction
関数を使用してシグナルハンドラを設定できます。 SIGABRTをブロックできないなど、いくつかの信号に注意してください。
さらに情報が必要な場合は、信号に関する Wikipedia ページを確認できます。
とはいえ、再開するには:
無効なメモリアドレスへのアクセス。アドレスは存在しますが、プログラムはアクセスできません。
無効なメモリアドレスへのアクセス。アドレスが存在しないか、アライメントが無効です。
算術演算が無効です。名前にもかかわらず、整数演算に関連している可能性があります。
壊れたパイプ。
不正なプロセッサ命令。
デバッガー関連
前のシグナルの1つに関係しないプログラムのクラッシュ。
SIGSEGVは、文字通り、所有していないアドレスにアクセスしていることを意味します。したがって、リリースされたオブジェクトにアクセスしているとは限りません。次のように、存在しなかったオブジェクトにアクセスできます。
UIView *view; // uninitialised, could point to anything
[view setFrame:someFrame];
または、次のようなCレベルの非オブジェクトのものでエラーを作成することもできます。
int array[100];
array[1000] = 23; // out-of-bounds access
SIGBUSはSIGSEGVと非常によく似ています。違いはハードウェアレベルにあります(通常、存在するが所有していないアドレスにアクセスしようとすることと、背後に何もないアドレスにアクセスしようとすることの違いは、これは厳密な定義ではありません)、通常は同じ種類のエラーに関連付けられていますが、SIGBUSはSIGSEGVよりも初期化されていない変数を使用する可能性がはるかに高くなります。
Objective-Cで発生した可能性のあるエラーにマッピングしようとしている場合は、おそらくSIGSEGVとSIGBUSを一緒に読み、「作成する権利のないメモリアクセス」を意味するものとします。
SIGABRTはそれ自体を中止しようとするプログラムであるため、通常、何らかの内部整合性チェックが失敗したことを意味します。たとえば、同じメモリを2回解放しようとするとSIGABRTが発生し、Cocoaレベルでraise
とキャッチされないNSException
を発生すると発生します。 SIGABRTを取得した場合は、システムソフトウェアによって検出された何か間違ったことをしました(ハードウェアで発生するSEGVとBUSとは対照的です)。
SIGTRAPは、プログラムからデバッガーへの呼び出しです。逸話的に、Appleは、ソフトウェアで検出できるが、特定のコードではなく環境に関連する何か間違ったことをするときにこれらを使用するようです。そのため、たとえば、存在するC関数を呼び出します実行中のデバイスではなくビルドしたSDKで(より低い展開ターゲットで最新のSDKに対してビルドする場合など)、またはオブジェクトで同様のことを行います。
これらのメッセージはgdbからのものであり、objective-C専用ではありません。シグナルに関する情報を取得するには、デバッガコンソールでinfo signals
と入力するだけで、 これは出力例です と入力します。ここに投稿しないで申し訳ありませんが、コンソール出力のフォーマットはひどいです。
私は最近このトピック領域を研究しました、そしてこれが私の要約です:
EXC_BAD_ACCESS (SIGSEGV)
またはEXC_BAD_ACCESS (SIGBUS)
私たちのプログラムはおそらく、不良なメモリの場所にアクセスしようとしたか、アドレスは良好でしたが、アクセスする権限がありませんでした。メモリが圧迫されたため、メモリの割り当てが解除された可能性があります。
EXC_BREAKPOINT (SIGTRAP)
これは、NSException
が(おそらく私たちの代わりにライブラリによって)発生するか、__NSLockError
_または_objc_exception_throw
_が呼び出されるためです。たとえば、これはSwift nilを強制的にアンラップするオプションなどの異常を検出する環境です。
EXC_BAD_INSTRUCTION (SIGILL)
これは、アクセスしているメモリではなく、プログラムコード自体に障害がある場合です。これはiOSデバイスではまれです。コンパイラまたはオプティマイザのバグ、または手書きのアセンブリコードの欠陥が考えられます。シミュレーターでは、定義されていないオペコードを使用することはSwiftランタイムがゾンビオブジェクト(割り当て解除されたオブジェクト)へのアクセスを停止するために使用する手法です。
_EXC_GUARD
_
これは、保護されているファイル記述子をプログラムが閉じたときです。例は、システムで使用されるSQLiteデータベースです。