问题背景
java通过jni去集成c++sdk时线上发现会有偶现崩溃,为了方便定位native(c++)的崩溃,sdk采用了google breakpad崩溃转储方案(Google跨平台的崩溃转储和分析框架和工具集合,breakpad支持windows、linux、macos、android、ios等。目前已有Google Chrome, Firefox, Google Picasa, Camino, Google Earth等项目使用。),更新sdk后,发现java启动后必现崩溃。
根因分析
最终定位出原因如下:
- jvm注册了信号处理函数,针对比如StackoverflowError 和NPE(NullPointerException)都会收到SIGSEGV,然后针对这两种异常虚拟机不选择退出,而是自己内部作了额外的处理,其实是恢复了线程的执行,仅仅向应用层抛出异常(因为这两种错误在jvm里太常见了),jvm不会崩溃;
- sdk breakpad捕获到了该信号,写完minidump完后直接退出进程;
解决方法
只要sdk捕获到信号后写完minidump后不直接结束进程即可,继续抛出异常,让jvm去捕获处理,该方案有一个缺点就是可能运行过程中会生成大量minidump文件,最后排查问题时用最后一个minidump即可。

实际操作:MinidumpCallback回调返回false代替返回succeeded。
参考:线程崩溃为什么不会导致 JVM 崩溃(https://www.cnblogs.com/xiekun/p/16378063.html)
当Java通过JNI集成C++SDK时,线上出现偶发崩溃。使用GoogleBreakpad进行崩溃转储,但更新SDK后Java启动必崩。原因是JVM对StackoverflowError和NPE异常不直接崩溃,而Breakpad捕获SIGSEGV信号后结束进程。解决方法是让Breakpad写完minidump后不立即结束进程,允许JVM处理异常,但可能导致生成大量minidump文件。
1106

被折叠的 条评论
为什么被折叠?



