我正在将一个项目转移到新的Android本机开发工具包(即JNI)中,我想捕获sigsegv,如果它发生(也可能是sigill、sigabrt、sigfpe),以便呈现一个很好的崩溃报告对话框,而不是(或之前)当前发生的事情:进程立即不确定地死亡,操作系统可能试图重新开始吧。(编辑:jvm/dalvik-vm捕获信号并记录堆栈跟踪和其他有用信息;我只想为用户提供将该信息通过电子邮件发送给我的选项。)

情况是:一个很大的C代码,我没有编写,在这个应用程序(大部分游戏逻辑)做大部分的工作,尽管它在许多其他平台上被很好的测试,但是在我的Android端口中,我完全有可能为它提供垃圾并导致本地代码崩溃,所以我希望CurrE的崩溃转储(本地和Java)tly出现在android日志中(我想在非android情况下是stderr)。我可以随意地修改C和Java代码,尽管回调(JNI的输入和输出)都是40左右,很明显是小差别的加分。

我听说过j2se,libjsig.so中的信号链库,如果我能在android上安全地安装这样的信号处理器,这就解决了我的问题,但是我没有看到android/dalvik这样的库。

如果您可以通过包装脚本启动Java虚拟机,您可以检查应用程序是否异常退出,并执行错误报告。这将使您能够清楚地捕捉到各种异常出口,无论它们是sigsegv、sigkill还是其他什么。不过,我不认为这是可能的股票Android应用程序,所以张贴这个评论(从答案转换)。

还可以看到:不能用Valgrind运行Java Android程序,如何用包装脚本启动Android应用程序(在ADB shell中)。

答案需要更新。接受答案中提供的源代码将导致由于调用非异步信号安全函数而导致未定义的行为。请参见:stackoverflow.com/questions/34547199/…

编辑:从JellyBean开始,你就不能得到堆栈跟踪,因为READ_LOGS消失了。:

实际上,我有一个信号处理程序在工作时没有做任何太奇怪的事情,并且使用它发布了代码,您可以在GitHub上看到(编辑:链接到历史版本;从那时起我就删除了崩溃处理程序)。以下是如何:

使用sigaction()捕捉信号并存储旧的处理程序。(安卓C:570)

时间过了,就会发生一个分段故障。

在信号处理程序中,最后一次调用JNI,然后调用旧的处理程序。(安卓C:528)

在该JNI调用中,记录任何有用的调试信息,并对标记为需要处于其自身进程中的活动调用startActivity()。(SjtSimuls.java:962,ANDROIDMANDS.XML:28)

当您从Java返回并调用旧的处理程序时,Android框架将连接到EDCOX1 OR 3,以便为您记录一个好的本地跟踪,然后该进程将死亡。(debugger.c、debuggerd.c)

同时,您的碰撞处理活动正在启动。实际上,您应该将PID传递给它,以便它可以等待第5步完成;我不这样做。在这里,您向用户道歉并询问是否可以发送日志。如果是这样的话,收集logcat -d -v threadtime的输出并发射一个ACTION_SEND,填写接收者、主题和主体。用户必须按"发送"。(CRASHANTHLLR.java,SGTSimple):Java:462,StR.xml:41

当心logcat失败或需要几秒钟以上。我遇到过一个设备,T-Mobile Pulse/Huawei U8220,logcat立即进入T状态并挂起。(CRASHANTHANDL.java:70,SCOR.XML: 51)

在非Android环境中,有些情况会有所不同。你需要收集你自己的本地跟踪,看看另一个问题,这取决于你有什么类型的libc。您需要处理转储跟踪、启动单独的崩溃处理程序进程,并以适合您的平台的某些适当方式发送电子邮件,但我认为一般的方法仍然有效。

理想情况下,你应该检查一下图书馆是否发生了车祸。如果它发生在其他地方(比如说,在虚拟机内部),来自信号处理程序的JNI调用可能会严重混淆事情。这并不是世界末日,因为无论如何,你都处于崩溃的中期,但它可能会使诊断虚拟机崩溃更加困难(或者导致一个奇怪的虚拟机崩溃,最终出现在一个Android错误报告中,并迷惑了所有人)。

你很高兴@chris分享你的研究项目!

谢谢,这对找到我的JNI疯了的地方很有用。还有,来自华盛顿校友的问候!

@法登是真的,但我不知道怎么弄清楚。因为在Debuggerd记录任何东西之前,我需要自己做一些堆栈展开(在Android上看起来非常重要),或者经常设置一个in/out标志或者分离/附加处理程序,在这种情况下,我肯定会错过某个位置。

从服务启动新流程中的活动还需要以下代码:newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);。

是的,活动新任务很重要,如果你不使用它,新活动就不会开始。

这个解决方案在果冻豆下仍然有效吗?步骤6是否会记录任何debuggerd输出?

我创建了一个小库,它使用这些步骤为JNI代码启用ACRA崩溃报告。你的帖子很有帮助,非常感谢!

我有点晚了,但我有同样的需求,我开发了一个小库来解决这个问题,通过捕获JNI代码中的常见崩溃(SEGV、SIBGUS等),并用常规java.lang.Error异常替换它们。另外,如果客户机在android上运行>=4.1.1,那么堆栈跟踪将嵌入崩溃的解析后跟踪(包含完整本机堆栈跟踪的伪跟踪)。您将无法从恶性崩溃中恢复(例如,如果您损坏了分配器),但至少它应该允许您从大多数崩溃中恢复。(请报告成功和失败,代码是全新的)

更多信息请访问https://github.com/xroche/coffeeecatch(代码为BSD 2条款许可证)

fwiw,谷歌BreakPad在Android上运行良好。我做了移植工作,我们将把它作为Firefox移动的一部分进行运送。它需要一些设置,因为它不提供客户端的堆栈跟踪,而是向您发送原始堆栈内存,并执行堆栈遍历服务器端操作(因此您不必在应用程序中附带调试符号)。

考虑到绝对丢失的文档,几乎不可能配置breakpad。

这真的不难,而且项目wiki上有很多文档。事实上,对于Android来说,现在有了一个ndk构建makefile,它应该非常容易使用:code.google.com/p/google breakpad/source/browse/trunk/…

您还需要编译为Android预处理调试符号文件的模块,并且只能在Linux上编译该模块。在Mac上编译时,它只构建Mac/IOS DSYM预处理器。

在我有限的经验(非Android)中,JNI代码中的SIGSEGV通常会在控制返回到Java代码之前崩溃JVM。我隐约记得听说过一些非Sun的JVM可以让你抓到Sigsegv,但在很小的范围内,你不能指望它能做到。

您可以尝试在C语言中捕获它们(参见sigaction(2)),尽管在sigsegv(或sigfpe或sigill)处理程序之后可以做很少的事情,因为进程的持续行为是官方定义的。

好吧,在"忽略不是由kill(2)或raise(3)产生的sigfpe、sigill或sigsegv信号"之后,行为是未定义的,但在捕获这样的信号时不一定如此。当前的计划是尝试调用回Java的C信号处理程序,不知何故,在不终止进程的情况下终止线程。这可能或不可能。-)

C回溯指令:stackoverflow.com/questions/76822/…

…但我不能使用backtrace(),因为Android不使用glibc,它使用仿生。:—(需要从unwind.h得到的与_Unwind_Backtrace有关的东西。

android 获取堆栈地址,关于java native interface:如何捕获SIGSEGV(分段错误)并在Android下的JNI下获取堆栈跟踪?...相关推荐

  1. Android JNI(Java Native Interface)技术介绍

    Android平台上的JNI技术介绍 JUL 15TH, 2013 | COMMENTS NDK简介 Android是由Google领导开发的操作系统,Android依靠其开放性,迅速普及,成为目前最 ...

  2. 【转】JNI(Java Native Interface)的简介

    因为刚刚接触android和java平台,对JNI到底是什么,还不是很了解,所以从CSDN转载了一篇文章,以便自己对JNI有一个认识,也跟大家分享一下. JNI是Java Native Interfa ...

  3. 转】JNI(Java Native Interface)的简介

    JNI 是Java Native Interface 的 缩写.从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言 ...

  4. Java Native Interface 二 JNI中对Java基本类型和引用类型的处理

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 Java编程里会使用到两种类型:基本类型(如 ...

  5. JNI (Java Native Interface)是什么

    JNI是Java Native Interface的缩写.从Java 1.1开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许Java代码和其他语言写的代 ...

  6. Atitit onvif协议获取rtsp地址播放java语言 attilx总结

    Atitit onvif协议获取rtsp地址播放java语言 attilx总结 1.1. 获取rtsp地址的算法与流程1 1.2. Onvif摄像头的发现,ws的发现机制,使用xcf类库1 2. 调用 ...

  7. Java Native Interface 六JNI中的异常

    本文是<The Java Native Interface Programmer's Guide and Specification>读书笔记 在这里只讨论调用JNI方法可能会出现的异常, ...

  8. java native 接口_Java本地接口--Java Native Interface (JNI)

    一.方法介绍 java native方法是指本地方法,当在方法中调用一些不是由java语言写的代码或者在方法中用java语言直接操纵计算机硬件时要声明为native方法. java中,通过JNI(Ja ...

  9. java获取运行时对象,java 面向对象(四十一):反射(五)反射应用二:获取运行时类的完整结构...

    我们可以通过反射,获取对应的运行时类中所有的属性.方法.构造器.父类.接口.父类的泛型.包.注解.异常等.... 典型代码: @Test public void test1(){ Class claz ...

最新文章

  1. Mysql数据库按照varchar字符串类型排序和按照int整型类型排序的区别和注意点及解决方案...
  2. Struts2之ModelDriven
  3. java通过使用ffmpeg获取视频的码率
  4. vue操作,显示数据
  5. (十五)深入浅出TCPIP之Hello CDN
  6. command对象的ExecuteScalar方法
  7. 南大cssci期刊目录_最新版CSSCI来源期刊目录(2019-2020)及增减变化!【南大核心】...
  8. java 多线程callable_java 多线程-实现Callable接口
  9. Docker学习总结(69)—— 不用 Docker 如何构建容器
  10. 列举计算机组装所需的各个硬件,计算机组装和维修期中考试.doc
  11. 易语言_酷Q机器人插件_01
  12. Java 代码实现pdf转word文件 | 无损转换完整代码教程
  13. 硬改intel网卡MAC地址
  14. win7连接sftp_WinSCP官方版下载_WinSCP(SFTP客户端) v5.17.1中文版 - Win7旗舰版
  15. 大不列颠百科全书Encyclopaedia Britannica Ultimate 2014光盘镜像
  16. moia调度mysql到hive_必看:数据平台的搭建教程及软件工具
  17. [Outlook] outlook如何实现自动CC和BCC邮件发送
  18. 儒略历--Java代码(附带发现了一些问题)
  19. Android背光灯控制实现
  20. API接口管理平台解决方案

热门文章

  1. 计算机编程怎样打符号,在CAD中如何输入一些特殊符号?比如乘除、符号.
  2. 赛事直播软件搭建中解说+连麦的技术架构难点解读
  3. 访问服务器网站出现 HTTP ERROR 500 该网页无法正常运作
  4. 屏幕保护程序Aerial 安装教程
  5. mysql 分库查询_mysql分库后怎么查询
  6. 作为程序员未来发展的规划
  7. clion调整字体打下奥_Clion、IEDA、pycharm的一些简单设置步骤(设置中文菜单、输出中文、字体大小、背景颜色主题)...
  8. 上海华为的一次面试经历
  9. 在顺序表中第五个位置插入一个元素9,实现顺序表插入的基本操作,输出顺序表中所有元素
  10. MySQL自动备份脚本和ftp上传脚本