Frage

Ich bin bewegt ein Projekt die neue Android Native Development Kit (d.h.JNI) und ich würde wie zu fangen SIGSEGV, sollte es auftreten (evtl. auch SIGILL, SIGABRT, SIGFPE), um einen schönen crash-reporting-dialog, anstelle von (oder vor) dem, was derzeit geschieht:die unmittelbaren unceremonious Tod des Prozess-und möglicherweise werden einige versuchen, das Betriebssystem zu starten Sie es neu.(Edit: Die JVM/Dalvik-VM fängt das signal und meldet einen stack-trace und andere nützliche Informationen;Ich möchte nur zu bieten die Benutzer die Möglichkeit, E-Mail, die Sie info, um mich wirklich.)

Die situation ist:eine große Menge von C-code, die ich nicht geschrieben habe die meiste Arbeit macht bei dieser Anwendung (alle der Spiel-Logik), und obwohl es gut-getestet auf zahlreichen anderen Plattformen, ist es durchaus möglich, dass ich in meinem Android-port, wird es zu versorgen, Müll und einen Absturz verursachen, die in nativem code, so will ich den crash dumps (sowohl native als auch Java), die derzeit in der Android-log (ich denke, es wäre stderr in eine nicht-Android-Lage).Ich bin frei zu ändern die C-und Java-code willkürlich, obwohl die Rückrufe (beide gehen in und coming-out von JNI) Zahl um die 40 und offensichtlich, bonus-Punkte für kleine diffs.

Ich habe gehört, der das signal Verkettung Bibliothek in J2SE, libjsig.so, und wenn ich könnte sicher installieren, ein signal-handler wie auf Android, die würde lösen die fallende Teil meiner Frage, aber ich sehe keine solche Bibliothek für Android/Dalvik.

War es hilfreich?

Lösung

Edit: Von Jelly Bean onwards Sie nicht bekommen kann die stack-trace, weil READ_LOGS ging Weg. :-(

Ich habe tatsächlich ein signal-handler arbeiten, ohne etwas zu exotisch, und haben code veröffentlicht, mit es, Sie können sehen, auf github (Bearbeiten:die Verknüpfung der historischen Version;Ich entfernte die crash-handler seitdem).Hier ist, wie:

  1. Verwenden sigaction() fangen Sie die Signale und speichern Sie die alt-Handler.(android.c:570)
  2. Die Zeit vergeht, wird ein segfault passiert.
  3. In der signal-handler aufrufen, um JNI ein letztes mal, und rufen Sie dann die alte Prozedur.(android.c:528)
  4. In diesem JNI-Aufruf, loggen Sie jede nützliche debugging-Informationen, und rufen Sie startActivity() auf eine Aktivität, die entsprechend gekennzeichnet sein müssen, in seinem eigenen Prozess.(SGTPuzzles.java:962, AndroidManifest.xml:28)
  5. Wenn Sie kommen zurück von Java und rufen Sie die alt-handler, die Android-framework zu verbinden debuggerd anmelden einen schönen native trace für Sie, und dann den Prozess sterben.(debugger.c, debuggerd.c)
  6. Inzwischen, Ihre crash-handling-Aktivität gestartet.Wirklich, Sie sollte es passieren PID, so dass es warten kann, bis Schritt 5 abgeschlossen;Ich Tue das nicht.Hier können Sie sich entschuldigen, um den Benutzer und bitten Sie, wenn Sie können senden ein Protokoll.Wenn ja, sammeln Sie die Ausgabe von logcat -d -v threadtime und starten Sie eine ACTION_SEND mit Empfänger, Betreff und Nachrichtentext ausgefüllt.Die Benutzer müssen drücken Sie Senden.(CrashHandler.java, SGTPuzzles.java:462, Zeichenfolgen.xml:41
  7. Watch out für logcat scheitern oder die Einnahme von mehr als ein paar Sekunden.Ich traf ein Gerät, das T-Mobile Pulse / Huawei U8220, wo logcat geht sofort in die T (traced) Zustand und hängt sich auf.(CrashHandler.java:70, Zeichenfolgen.xml:51)

In einem nicht-Android-Lage, einige dieser würde anders sein.Sie brauchen, um zu sammeln Sie Ihre eigene native trace finden Sie unter diese andere Frage, je nach Art der libc, die Sie haben.Sie würde behandeln müssen, dumping, die Spur, das starten von separaten crash-handler-Prozess, und das senden der E-Mail in einige passende Möglichkeiten für Ihre Plattform zu erhalten, aber ich kann mir vorstellen das Allgemeine Konzept sollte immer noch funktionieren.

Andere Tipps

Ich bin ein bisschen zu spät, aber ich hatte die exakt gleichen müssen, und ich entwickelt haben, eine kleine Bibliothek, um ihm durch den Fang häufige Abstürze (SEGV, SIBGUS, etc.) innen JNI-code, und ersetzen Sie Sie durch regelmäßige java.lang.Error Ausnahmen.Bonus, wenn der client ausgeführt wird, auf Android >= 4.1.1, der stack-trace bettet das gelöst backtrace der Absturz (ein pseudo-trace mit der vollen nativen stack-trace).Sie werden nicht wieder von vicious Abstürze (ie.wenn Sie beschädigt die Zuweisung, zum Beispiel), aber zumindest sollte es ermöglicht Ihnen die Wiederherstellung von die meisten von Ihnen.(bitte melden, Erfolge und Misserfolge, den code neu)

Weitere Informationen bei https://github.com/xroche/coffeecatch (code ist BSD-2-Klauseln Lizenz)

FWIW, Google Breakpad works fine on Android.Ich habe die Portierung arbeiten, und wir Versand, die Sie als Teil von Firefox Mobile.Es erfordert ein wenig setup, da Sie nicht geben Sie die stack-traces auf der client-Seite, sendet aber Sie die raw-stack-Speicher und stellt die stack-walking-server-Seite (so dass Sie nicht haben zu Schiff debug-Symbole mit der app).

In meiner begrenzten Erfahrung (nicht-Android), SIGSEGV in JNI-code wird in der Regel zum Absturz der JVM, bevor die Steuerung wieder an Ihren Java-code.Ich vage erinnern Anhörung über einige nicht-Sun JVM können Sie fangen SIGSEGV, aber AFAICR Sie können nicht erwarten, in der Lage zu tun so.

Sie können versuchen, Sie zu fangen in C (siehe sigaction(2)), obwohl Sie können sehr wenig tun, nach einem SIGSEGV (oder SIGFPE oder SIGILL) handler des Laufenden Verhalten eines Prozesses ist offiziell nicht definiert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top