如何为JNI代码生成崩溃转储文件

3

大家好,

假设我在Windows环境下有一个简单的JNI程序:

int* p = NULL;
*p = 5;

当从JVM运行时,与普通的C++应用程序不同,JVM会很好地捕获这样的异常并进行一些清理工作。

这里的问题是它也阻止我在那里生成崩溃转储,尽管有一个JVM选项:-XX:OnError,但在此处生成的核心转储距离犯罪现场远,因此难以调试。

JVM使用SEH包装每个Java线程:

__try
{
    thread.run()
}
__except(topLevelExceptionFilter())
{
}

JNI代码引发的访问冲突发生在线程运行时,但已经在另一个地方处理了topLevelExceptionFilter。

你有什么建议吗?

谢谢。

3个回答

6

谢谢,是的,在Windows中UseOSErrorReporting起作用;在Linux中,默认生成coredump,无需额外选项。 - Baiyan Huang

5
一个core是C++崩溃转储...你没有Java提供的方便设施来使它更容易使用。如果您编译本机代码以保留符号(最好不要优化),则可以使用gdb或另一个调试器对其进行分析并在失败点获取堆栈跟踪,以及读取变量等。
生成的核心转储远离“犯罪现场”因此难以调试--核心转储完全涵盖所谓的犯罪现场,因此并非“远离犯罪现场”。您认为它们难以调试的唯一原因是您尚未学习,但它们绝对是此工作的正确工具。

重点是JVM将捕获这种严重异常(访问冲突),因此您没有机会在真正出错的时候生成核心转储。异常处理机制使代码执行跳转到JVM的异常处理程序,那就是您获取核心转储的地方。 - Baiyan Huang
"这是你还没有学习过的东西吗?- 你能提供更多信息吗?谢谢。" - Baiyan Huang
实际上导致核心转储的问题不应该到达JVM的异常处理程序——如果是这样,您可以尝试捕获它。当操作系统检测到应用程序存在严重问题时,会发生核心转储,并将其信号发送给进程的默认信号处理程序,而不是自定义信号处理程序……自定义处理程序可以在不进行核心转储的情况下终止进程,或者在某些情况下通过事先规划和使用setjmp()和longjmp()来从中恢复。 - mah
http://www.ffnn.nl/pages/articles/linux/gdb-gnu-debugger-intro.php有一个教程,可以帮助你开始进行核心转储分析。请注意,如果您的本地库没有使用-g编译和链接,您的分析结果将会受到影响。 - mah

0
在Linux中使用ulimit -c unlimited生成核心转储文件,然后使用gdb调试Java进程的核心文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接