我如何能赶上SIGSEGV(分段错误),并得到JNI下的堆栈跟踪在Android? [英] How can I catch SIGSEGV (segmentation fault) and get a stack trace under JNI on Android?

查看:698
本文介绍了我如何能赶上SIGSEGV(分段错误),并得到JNI下的堆栈跟踪在Android?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我感动项目以全新的Andr​​oid原生开发套件(即JNI)和我会像捕获SIGSEGV,是否应当发生的,而不是(或前)(也可能SIGILL,SIGABRT,SIGFPE)以present一个很好的崩溃报告对话框,什么目前发生的情况:在处理和可能的一些立即粗鲁死亡试图通过操作系统重新启动它。 (编辑:的JVM / Dalvik虚拟机捕获信号并记录堆栈跟踪和其他有用的信息,我只是想为用户提供真正通过电子邮件发送这些信息给我的选项)

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. ( 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.)

的情况为:C code进行庞大的身躯,我没有写完成大部分工作,在此应用程序(所有的游戏逻辑),虽然它在许多其他平台经过严格测试的,这是完全有可能我,在我的Andr​​oid端口,将喂它垃圾,导致当地code崩溃,所以我要崩溃转储(包括本地和Java),目前出现在Android日志(我想这将是标准错误在一个非Android情况)。我可以自由地修改这两个C和Java code随意,虽然回调(包括进入和出来的JNI)数目约40,显然,奖励积分小diff文件。

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.

我听说过链接库在J2SE,libjsig.so的信号,如果我能安全地安装一个信号处理程序一样,在Android上,这将解决我的问题的捕获一部分,但我没有看到这样的库安卓/ Dalvik的。

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.

推荐答案

编辑:从果冻豆开始你不能得到堆栈跟踪,因为的 READ_LOGS 走了。 : - (

From Jelly Bean onwards you can't get the stack trace, because READ_LOGS went away. :-(

其实,我得到了一个信号处理程序的工作没有做任何事情太奇特,并使用它,你可以看到的在github (编辑:链接到历史版本,我删除了崩溃的处理器从那时起)。具体方法如下:

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:

  1. 使用的sigaction()捕捉的信号并​​存储旧的处理程序。 ( android.c:570
  2. 在时间的推移,段错误发生。
  3. 在信号处理程序,调用到JNI的最后一次,然后调用旧的处理程序。 ( android.c:528
  4. 在JNI调用,记录任何有用的调试信息,并调用<一href="http://developer.android.com/reference/android/app/Activity.html#startActivity(android.content.Intent)"相对=nofollow> startActivity() 上被标记为需要在自己的进程,一个活动。 (<一href="http://github.com/chrisboyle/sgtpuzzles/blob/8750.5/android/src/name/boyle/chris/sgtpuzzles/SGTPuzzles.java#L962"相对=nofollow> SGTPuzzles.java:962 ,的 AndroidManifest.xml中:28
  5. 当你从Java回来,并调用旧的处理程序,Android框架将连接到 debuggerd 来记录一个很好的天然跟踪你,然后这个过程会死。 ( debugger.c debuggerd .C
  6. 同时,你的崩溃装卸活动正在启动。真的,你应该通过它的PID,因此可以等待第5步完成;我不这样做。在这里,您道歉给用户,并询问是否可以将一个日志。如果是这样,收集 logcat的-d -v threadtime 的输出,并发动 ACTION_SEND 与收件人,主题和正文填充研究。用户将不得不preSS发送。 (<一href="http://github.com/chrisboyle/sgtpuzzles/blob/8750.5/android/src/name/boyle/chris/sgtpuzzles/CrashHandler.java"相对=nofollow> CrashHandler.java ,<一个href="http://github.com/chrisboyle/sgtpuzzles/blob/8750.5/android/src/name/boyle/chris/sgtpuzzles/SGTPuzzles.java#L462"相对=nofollow> SGTPuzzles.java:462 ,的 strings.xml中:41
  7. 当心的logcat 失败或服用超过几秒钟。我曾经遇到过一个设备,T-Mobile的脉冲/华为U8220,其中的logcat立即进入 T (跟踪)状态和挂起。 (<一href="http://github.com/chrisboyle/sgtpuzzles/blob/8750.5/android/src/name/boyle/chris/sgtpuzzles/CrashHandler.java#L70"相对=nofollow> CrashHandler.java:70 ,的 strings.xml中:51
  1. Use sigaction() to catch the signals and store the old handlers. (android.c:570)
  2. Time passes, a segfault happens.
  3. In the signal handler, call up to JNI one last time and then call the old handler. (android.c:528)
  4. In that JNI call, log any useful debugging info, and call startActivity() on an activity that is flagged as needing to be in its own process. (SGTPuzzles.java:962, AndroidManifest.xml:28)
  5. When you come back from Java and call that old handler, the Android framework will connect to debuggerd to log a nice native trace for you, and then the process will die. (debugger.c, debuggerd.c)
  6. Meanwhile, your crash-handling activity is starting up. Really you should pass it the PID so it can wait for step 5 to complete; I don't do this. Here you apologise to the user and ask if you can send a log. If so, gather the output of 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
  7. Watch out for 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)

在一个非Android情况,一些这将是不同的。你需要收集你自己的母语的痕迹,看<一href="http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes">this另一个问题,这取决于什么样的libc中你有。你需要处理反倾销的跟踪,发动你的独立碰撞处理过程,并在一些适当的方式为您的平台发送的电子邮件,但我想一般的做法应该仍然工作。

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.

这篇关于我如何能赶上SIGSEGV(分段错误),并得到JNI下的堆栈跟踪在Android?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆