I'm moving a project to the new Android Native Development Kit (i.e. JNI) and I'd like to catch SIGSEGV, should it occur (possibly also SIGILL, SIGABRT, SIGFPE) in order to present a nice crash reporting dialog, instead of (or before) what currently happens: the immediate unceremonious death of the process and possibly some attempt by the OS to restart it. (Edit: The JVM/Dalvik VM catches the signal and logs a stack trace and other useful information; I just want to offer the user the option to email that info to me really.)
The situation is: a large body of C code which I didn't write does most of the work in this application (all the game logic) and although it's well-tested on numerous other platforms, it's entirely possible that I, in my Android port, will feed it garbage and cause a crash in native code, so I want the crash dumps (both native and Java) that currently show up in the Android log (I guess it would be stderr in a non-Android situation). I'm free to modify both C and Java code arbitrarily, although the callbacks (both going in and coming out of JNI) number about 40 and obviously, bonus points for small diffs.
I've heard of the signal chaining library in J2SE, libjsig.so, and if I could safely install a signal handler like that on Android, that would solve the catching part of my question, but I see no such library for Android/Dalvik.
A. A SIGSEGV is an error(signal) caused by an invalid memory reference or a segmentation fault. You are probably trying to access an array element out of bounds or trying to use too much memory.
Trying to ignore or handle a SIGSEGV is the wrong approach. A SIGSEGV triggered by your program always indicates a bug. Either in your code or code you delegate to. Once you have a bug triggered, anything could happen.
The SIGSEGV signal is raised when you attempt to illegally access or modify memory. SIGSEGV is usually caused by using uninitialized or NULL pointer values or by memory overlays.
Edit: From Jelly Bean onwards you can't get the stack trace, because READ_LOGS
went away. :-(
I actually got a signal handler working without doing anything too exotic, and have released code using it, which you can see on github (edit: linking to historical release; I removed the crash handler since then). Here's how:
sigaction()
to catch the signals and store the old handlers. (android.c:570)startActivity()
on an activity that is flagged as needing to be in its own process. (SGTPuzzles.java:962, AndroidManifest.xml:28)debuggerd
to log a nice native trace for you, and then the process will die. (debugger.c, debuggerd.c)logcat -d -v threadtime
and launch an ACTION_SEND
with recipient, subject and body filled in. The user will have to press Send. (CrashHandler.java, SGTPuzzles.java:462, strings.xml:41 logcat
failing or taking more than a few seconds. I have encountered one device, the T-Mobile Pulse / Huawei U8220, where logcat immediately goes into the T
(traced) state and hangs. (CrashHandler.java:70, strings.xml:51)In a non-Android situation, some of this would be different. You'd need to gather your own native trace, see this other question, depending on what sort of libc you have. You'd need to handle dumping that trace, launching your separate crash-handler process, and sending the email in some appropriate ways for your platform, but I imagine the general approach should still work.
I'm a little bit late, but I had the exact same need, and I've developed a small library to address it, by catching common crashes (SEGV
, SIBGUS
, etc.) inside JNI code, and replace them by regular java.lang.Error
exceptions. Bonus, if the client is running on Android >= 4.1.1
, the stack trace embeds the resolved backtrace of the crash (a pseudo-trace containing the full native stack trace). You will not recover from vicious crashes (ie. if you corrupt the allocator, for example), but at least it should allows you to recover from most of them. (please report successes and failures, the code is brand new)
More info at https://github.com/xroche/coffeecatch (code is BSD 2-Clauses license)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With