私は プロジェクト を新しいAndroid Native Development Kit(すなわちJNI)に移動しているので、SIGSEGVが発生した場合はそれをキャッチしたい(おそらくSIGILL、 SIGABRT、SIGFPE)現在発生していることの代わりに(またはその前に)Niceクラッシュレポートダイアログを表示するために:プロセスの即時の不意の死、および場合によってはOSによる再起動の試み。編集: JVM/Dalvik VMはシグナルをキャッチし、スタックトレースおよびその他の有用な情報を記録します。ユーザーにその情報を実際にメールで送信するオプションを提供したいだけです。)
状況は次のとおりです。私が作成しなかったCコードの大部分は、このアプリケーション(すべてのゲームロジック)のほとんどの作業を行い、他の多くのプラットフォームで十分にテストされていますが、 Android port、それをガベージフィードし、ネイティブコードでクラッシュを引き起こすので、Androidに現在表示されるクラッシュダンプ(ネイティブとJavaの両方)が欲しい= log(Android以外の状況ではstderrになると思います。)CとJavaコードを自由に変更できます。ただし、コールバック( JNI)約40の数、そして明らかに、小さな差分のボーナスポイント。
J2SEのシグナルチェーンライブラリlibjsig.soを聞いたことがあり、Androidにそのようなシグナルハンドラを安全にインストールできれば、質問のキャッチ部分を解決できますが、Android/Dalvikのライブラリはありません。
Edit:_READ_LOGS
_がなくなったため、Jelly Bean以降ではスタックトレースを取得できません。 。 :-(
私は実際に、あまりにもエキゾチックなことを何もせずに機能するシグナルハンドラを取得し、それを使用してコードをリリースしました。 ongithub それ以降のクラッシュハンドラ)。方法は次のとおりです。
sigaction()
を使用して、シグナルをキャッチし、古いハンドラーを保存します。 ( Android.c:570 )startActivity()
を呼び出します( SGTPuzzles.Java:962 、 AndroidManifest.xml:28 )debuggerd
に接続して、素敵なネイティブトレースを記録します、そしてプロセスは死にます( debugger.c 、 debuggerd.c )logcat -d -v threadtime
_の出力を収集し、受信者、件名、本文を入力して_ACTION_SEND
_を起動します。ユーザーは[送信]を押す必要があります。 ( CrashHandler.Java 、 SGTPuzzles.Java:462 、 strings。 xml:41logcat
が失敗するか、数秒以上かかることに注意してください。 T-Mobile Pulse/Huawei U8220というデバイスに遭遇しました。logcatはすぐにT
(トレース)状態になり、ハングします。 ( CrashHandler.Java:70 、 strings.xml:51 )Android以外の状況では、これの一部は異なります。独自のネイティブトレースを収集する必要があります。使用しているlibcの種類に応じて、 this other question を参照してください。そのトレースをダンプし、個別のクラッシュハンドラープロセスを起動し、プラットフォームに適した方法で電子メールを送信する必要がありますが、一般的なアプローチは引き続き機能するはずです。
少し遅れましたが、まったく同じニーズがあり、一般的なクラッシュ(SEGV
、SIBGUS
など)をキャッチすることで、それに対処する小さなライブラリを開発しました。内部JNIコード、およびそれらを通常のJava.lang.Error
exceptions。ボーナス、クライアントがAndroid> = 4.1.1
、スタックトレースは、クラッシュ(完全なネイティブスタックトレースを含む擬似トレース)の解決済みbacktraceを埋め込みます。悪質なクラッシュ(たとえば、アロケータを破損した場合)からは回復しませんが、少なくともmostから回復できるはずです。 (成功と失敗を報告してください、コードは新しいです)
詳細は https://github.com/xroche/coffeecatch (code isBSD 2-Clauses license)
FWIW、 Google Breakpad Androidで正常に動作します。移植作業を行い、Firefox Mobileの一部として出荷しています。クライアント側でスタックトレースを提供しないため、少しセットアップが必要です)。
私の限られた経験(Android以外)で、JNIコードのSIGSEGVは通常、Javaコードに制御が戻る前にJVMをクラッシュさせます。Sun以外のJVMについて聞いたことを漠然と思い出しますSIGSEGVをキャッチしますが、AFAICRを使用すると期待できません。
プロセスの進行中の動作は公式に定義されていないため、SIGSEGV(またはSIGFPEまたはSIGILL)ハンドラーの後ではほとんど実行できませんが、Cでそれらをキャッチしようとすることができます(sigaction(2)を参照)。