[android-devel] Runtime crashes on Android

Bernhard Urban beurba at microsoft.com
Tue Dec 13 17:52:10 UTC 2016

Reply inline ->

On Dec 13, 2016, at 6:37 PM, Jonathan Pryor <jonpryor at vt.edu<mailto:jonpryor at vt.edu>> wrote:

Let me go back one step. In general the signal chain looks like this on Android:

(1) SIGSEGV happens, the ART handler catches it and does some stuff (e.g. "is it caused by my managed code"?).
(2) if ART doesn't know what to do, it will chain into remaining handlers.
(3) now it's the mono runtimes handler turn, we do our business, figure out it's a native crash, etc.
(4) (in case we do *NOT* crash) we return to the ART handler
(5) the ART handler now chains into the next SIGSEGV handler, which was setup by the linker of bionic.
(6) the libc/bionic handler communicates with debuggerd which ptraces our process and delivers further information (e.g. register dump, native stack trace)
Looking at this, I have this conclusion: How about we do not even attempt to do a native stack trace in mono, but just let debuggerd do its business?

What do we want? The managed callstack. Yes, a SIGSEGV happened in native code, but mono is the only one that can produce a *managed* callstack leading up to the SIGSEGV, and Android certainly isn’t going to print out the managed stack frames…

Of course we still have to print the managed stack trace ourselves.

My recollection is that we *don’t* reliably print the managed stack trace during native SIGSEGV. (Am I wrong?)

Yes. There was an issue with exceeding the altstack limit: This was especially a problem on ARM32 because we used a pretty large struct in our unwinding code. It’s fixed by this PR: https://github.com/mono/mono/pull/4106

However, this is only a workaround.  Zoltan is experimenting with something similar what we are doing for exception handling already: get out of the signal handler via overriding the PC in the sigctx structure and then do the heavy lifting later (that is, on a normal stack).

So long as the managed callstack is *reliably* dumped, I don’t really care what code prints the native callstack, just that we get reliable managed and native callstacks *somewhere*, preferably in some form that will make it back to Google and developers…

However, that raises an added wrinkle: IIRC, debuggerd only attaches and dumps the stack traces for *debuggable* applications (`AndroidManifest.xml` has `//application/@android:debuggable=‘true’`). This *is not true* for Release apps, meaning we might not be able to rely on debuggerd to provide native stack traces in Release apps.

Is that a problem? (Maybe?) Are native stack dumps when Release crashes something desirable? (I’d think so…?)

That’s indeed correct, and setting it in the manifest for release builds isn’t something you should do due to security reasons. Hence this PR: https://github.com/mono/mono/pull/4131

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dot.net/pipermail/android-devel/attachments/20161213/1f12d2a8/attachment-0001.html>

More information about the android-devel mailing list