我有一个主要是用 C 编写的本机代码的应用程序:Simon Tatham's Puzzles。当我遇到崩溃(使用信号处理程序)时,Java 回溯只会告诉我问题的模糊区域:
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)
为了获得诊断的希望,我需要的是本机回溯 Android 框架写入日志:
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
据我所知,Android Market 的崩溃报告不包括本机跟踪...是吗?
因此,我目前有自己的崩溃捕获器和报告器,如下所示<一href="https://stackoverflow.com/questions/1083154/how-can-i-catch-sigsegv-segmentation-fault-and-get-a-stack-trace-under-jni-on-a/1789879#1789879 ">上一个问题,它将让您进入一个电子邮件撰写窗口并登录。这种方法效果很好,但有一个问题:用户不阅读(或不相信)包描述中的解释,并被权限请求吓跑。
困扰我的不是这几条评论,而是未知数量的人谁甚至没有安装它就逃跑了。 :-(
那么如何在崩溃时获得本机回溯而不使游戏需要看起来可怕的日志权限?可能的解决方案包括:
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.
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.
发布评论
评论(2)
编辑:从 Jelly Bean 开始,您和日志收集器都无法读取
debuggerd
的输出,因为READ_LOGS 消失。 :-(但是,Play Console 的崩溃报告现在包括本机堆栈跟踪(至少截至 2014 年末),这使得这一切不再那么必要。
以前:
我将以git 提交:
https://github.com/chrisboyle/sgtpuzzles/commit/e9917f1ffe93f9d9963463db849e3768beafccee
这是对日志收集器的委托,正如我在上面暗示的那样。我像以前一样捕获了崩溃(参见 我之前关于如何做到这一点的讨论)像以前一样显示“哎呀,我崩溃了”屏幕,如果用户单击“报告”,那么我会提示他们 如果还没有安装日志收集器,如果
我已经让用户去安装它,那么一旦安装完成,我就会捕获
PACKAGE_ADDED
意图并使用适当的选项启动日志收集器(我警告我要这样做)。这样用户就不会猜测他们应该单击“打开”,这将在没有我的目的地、主题和过滤器的情况下启动它。过滤器值得拥有,因为它们将电子邮件中发送的内容限制为可能相关的行。这节省了用户的带宽和收件箱容量,并且意味着用户可以更轻松地检查日志中是否没有敏感内容,因此更有可能同意发送日志。
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.
还有另一种方法可以访问所有日志,无需任何特殊权限,但需要在手机上启用远程调试。查看开源无根 Logcat 应用。
There is another way to access all logs without any special permissions, but it requires enabling remote debugging on the phone. Take a look at the open source rootless Logcat app.