Ich verschiebe ein Projekt auf das neue Android Native Development Kit (dh JNI) und möchte SIGSEGV abfangen, falls es auftreten sollte (möglicherweise auch SIGILL, SIGABRT, SIGFPE), um stattdessen einen schönen Dialog zur Absturzberichterstattung zu präsentieren (oder vorher) was aktuell passiert: der sofortige, zügellose Tod des Prozesses und möglicherweise ein Versuch des Betriebssystems, ihn neu zu starten. ( Bearbeiten: Die JVM / Dalvik-VM fängt das Signal ab und protokolliert einen Stack-Trace und andere nützliche Informationen. Ich möchte dem Benutzer nur die Möglichkeit bieten, diese Informationen wirklich per E-Mail an mich zu senden.)
Die Situation ist: Ein großer Teil des C-Codes, den ich nicht geschrieben habe, erledigt den größten Teil der Arbeit in dieser Anwendung (die gesamte Spielelogik), und obwohl er auf zahlreichen anderen Plattformen gut getestet wurde, ist es durchaus möglich, dass ich in meinem Android Port, wird es Müll füttern und einen Absturz im nativen Code verursachen, daher möchte ich die Absturz-Dumps (sowohl native als auch Java), die derzeit im Android-Protokoll angezeigt werden (ich denke, es wäre stderr in einer Nicht-Android-Situation). Es steht mir frei, sowohl C- als auch Java-Code willkürlich zu ändern, obwohl die Rückrufe (sowohl beim Ein- als auch beim Verlassen von JNI) etwa 40 betragen und natürlich Bonuspunkte für kleine Unterschiede.
Ich habe von der Signalverkettungsbibliothek in J2SE, libjsig.so, gehört, und wenn ich einen solchen Signalhandler sicher auf Android installieren könnte, würde dies den auffälligen Teil meiner Frage lösen, aber ich sehe keine solche Bibliothek für Android / Dalvik .
Antworten:
Edit: Von Jelly Bean ab können Sie den Stack - Trace erhalten, weil
READ_LOGS
weg ging . :-(Ich habe tatsächlich einen Signal-Handler zum Laufen gebracht , ohne etwas zu Exotisches zu tun, und habe damit Code veröffentlicht, den Sie auf github sehen können (bearbeiten: Verknüpfung mit historischer Version; ich habe den Crash-Handler seitdem entfernt). Hier ist wie:
sigaction()
diese Option , um die Signale abzufangen und die alten Handler zu speichern. ( android.c: 570 )startActivity()
eine Aktivität auf, die als in ihrem eigenen Prozess vorhanden markiert ist. ( SGTPuzzles.java:962 , AndroidManifest.xml: 28 )debuggerd
um eine nette native Ablaufverfolgung für Sie zu protokollieren, und der Vorgang wird dann beendet. ( debugger.c , debuggerd.c )logcat -d -v threadtime
und starten Sie eineACTION_SEND
mit Empfänger, Betreff und Text ausgefüllt. Der Benutzer muss Senden drücken. ( CrashHandler.java , SGTPuzzles.java:462 , strings.xml : 41logcat
versagen oder länger als ein paar Sekunden dauern. Ich bin auf ein Gerät gestoßen, das T-Mobile Pulse / Huawei U8220, bei dem logcat sofort in denT
(verfolgten) Zustand wechselt und hängt. ( CrashHandler.java:70 , strings.xml : 51 )In einer Situation ohne Android wäre dies teilweise anders. Sie müssten Ihre eigene native Spur sammeln und diese andere Frage sehen , je nachdem, welche Art von Bibliothek Sie haben. Sie müssten das Speichern dieser Ablaufverfolgung, das Starten Ihres separaten Crash-Handler-Prozesses und das Senden der E-Mail auf eine für Ihre Plattform geeignete Weise durchführen, aber ich denke, der allgemeine Ansatz sollte weiterhin funktionieren.
quelle
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
debuggerd
Ausgaben zu protokollieren ?Ich bin ein wenig spät, aber ich hatte genau das gleiche Bedürfnis, und ich habe eine kleine Bibliothek entwickelt , diese auszuräumen, durch gemeinsame Abstürze zu kontrollieren (
SEGV
,SIBGUS
usw.) innerhalb JNI Code , und ersetzen Sie sie durch regelmäßigejava.lang.Error
Ausnahmen . Bonus, wenn der Client unter Android> = ausgeführt wird4.1.1
, bettet der Stack-Trace den aufgelösten Backtrace des Absturzes ein (ein Pseudo-Trace, der den vollständigen nativen Stack-Trace enthält). Sie werden sich nicht von bösartigen Abstürzen erholen (z. B. wenn Sie beispielsweise den Allokator beschädigen), aber zumindest sollten Sie sich von den meisten davon erholen können. (Bitte melden Sie Erfolge und Misserfolge, der Code ist brandneu)Weitere Informationen unter https://github.com/xroche/coffeecatch (Code ist BSD 2-Klauseln-Lizenz )
quelle
FWIW, Google Breakpad funktioniert gut auf Android. Ich habe die Portierungsarbeit erledigt und wir versenden sie als Teil von Firefox Mobile. Es erfordert ein wenig Setup, da es Ihnen keine Stack-Traces auf der Clientseite gibt, sondern Ihnen den Raw-Stack-Speicher sendet und den Stack-Walking-Server ausführt (sodass Sie keine Debug-Symbole mit Ihrer App versenden müssen ).
quelle
Nach meiner begrenzten Erfahrung (nicht mit Android) stürzt SIGSEGV im JNI-Code im Allgemeinen die JVM ab, bevor die Steuerung an Ihren Java-Code zurückgegeben wird. Ich erinnere mich vage, dass ich von einer Nicht-Sun-JVM gehört habe, mit der Sie SIGSEGV fangen können, aber AFAICR können Sie nicht erwarten, dass Sie dazu in der Lage sind.
Sie können versuchen, sie in C abzufangen (siehe Sigaction (2)), obwohl Sie nach einem SIGSEGV- (oder SIGFPE- oder SIGILL-) Handler nur sehr wenig tun können, da das laufende Verhalten eines Prozesses offiziell undefiniert ist.
quelle
_Unwind_Backtrace
vonunwind.h
stattdessen benötigt.