Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to collect native stacktrace without a scary READ_LOGS permission up front?

I have an application which is mostly native code written in C: Simon Tatham's Puzzles. When I catch a crash (with a signal handler), a Java backtrace will only tell me the vague area of the problem:

W System.err: at name.boyle.chris.sgtpuzzles.SGTPuzzles.resizeEvent(Native Method)
W System.err: at name.boyle.chris.sgtpuzzles.SGTPuzzles$1.handleMessage(SGTPuzzles.java:126)
W System.err: at android.os.Handler.dispatchMessage(Handler.java:99)

What I need in order to have any hope of diagnosis is the native backtrace that the Android framework writes to the log:

I DEBUG   :          #02  pc 0003e8ae  /data/data/name.boyle.chris.sgtpuzzles/lib/libpuzzles.so
I DEBUG   :          #03  pc 0003ed62  /data/data/name.boyle.chris.sgtpuzzles/lib/libpuzzles.so
I DEBUG   :          #04  pc 00059060  /data/data/name.boyle.chris.sgtpuzzles/lib/libpuzzles.so

As far as I know, Android Market's crash reports don't include native traces... do they?

Therefore, I currently have my own crash catcher and reporter, described in this previous question, which will offer to drop you into an email compose window with your log in it. That works well enough, with one problem: users don't read (or don't believe) the explanation in the package description and are scared away by the permission request.

Permission request to read logs; comments about it from users

It's not these few comments that bother me, it's the unknown number of people who ran away without even installing it. :-(

So how do I get a native backtrace on crash without making the game require a scary-looking logs permission? Possible solutions include:

  • I'm wrong and Android Market will actually give me native traces these days?
  • Recommend when I catch a crash that people immediately install and run Log Collector? This is what I'm leaning towards currently. Anyone got a good example of this being done, with well-written explanatory text?
  • Having caught the crash with a signal handler (which I can do), any way to read my own native stacktrace? More difficult on Android/Bionic than on glibc platforms, no backtrace() available. Edit: Most things under here appear to be required: http://github.com/android/platform_system_core/tree/master/debuggerd - to include enough of it in the project would be overkill, bloaty, difficult, unsupported, brittle on ABI changes/additions. Doesn't seem like a good use of time.
like image 916
Chris Boyle Avatar asked Sep 17 '11 16:09

Chris Boyle


1 Answers

Edit: From Jelly Bean onwards, neither you nor Log Collector can read debuggerd's output, because READ_LOGS went away. :-(

But, Play Console's crash reports now include native stack traces (at least as of late 2014), which makes this all much less necessary.

Previously:

I shall give my answer in the form of a git commit:

https://github.com/chrisboyle/sgtpuzzles/commit/e9917f1ffe93f9d9963463db849e3768beafccee

This is delegation to Log Collector, as I hinted at above. I catch the crash as before (see my previous discussion of how to do that) show an "oops, I crashed" screen as before, and if the user clicks Report, then I prompt them to install Log Collector if they haven't already.

If I've sent the user off to install it, as soon as it finishes installing, I catch the PACKAGE_ADDED Intent and launch Log Collector with appropriate options (I warn that I'm going to do this). This is so that the user isn't left guessing that they should click Open, which would launch it without my destination, subject, and filters.

The filters are worth having, as they limit what is sent in the email to lines that might be relevant. This saves the user's bandwidth and my inbox capacity, and means the user can more easily check that there's nothing sensitive in the log and is therefore more likely to agree to send it.

like image 56
Chris Boyle Avatar answered Nov 15 '22 14:11

Chris Boyle