如何为JNI代码生成故障转储

Bai*_*ang 3 java java-native-interface dump

大家,

假设我在Windows中有一个简单的JNI程序:

int* p = NULL;
*p = 5;
Run Code Online (Sandbox Code Playgroud)

当从JVM运行它时,不像普通的C++应用程序,JVM将很好地捕获这样的硬异常并做一些清理工作.

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

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

__try
{
    thread.run()
}
__except(topLevelExceptionFilter())
{
}
Run Code Online (Sandbox Code Playgroud)

导致访问冲突的JNI代码发生在thread.run中,但是在topLevelExceptionFilter中处理,它已经在其他地方了.

你有什么建议吗?

谢谢.

eck*_*kes 6

您可以使用OnError设置启动本机调试器,如下所示:

http://download.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/clopts.html#gbmum

java -XX:OnError="gdb - %p" MyApplication
Run Code Online (Sandbox Code Playgroud)

对于Windows

JDK7 还有一个-XX:+ShowMessageBoxOnError或一个-XX:+UseOSErrorReporting选项,不确定它是否适用于Linux核心转储,它应该适用于Windows和默认的OS调试器(DrWatson).请参阅http://blogs.oracle.com/poonam/entry/more_on_windows_crash_dumps


mah*_*mah 5

A core C++崩溃转储...您没有Java提供的便利设施,使其更易于使用.如果编译本机代码以保留符号(理想情况下不进行优化),则可以使用gdb或其他调试器对其进行分析,并在失败点获取堆栈跟踪,以及读取变量等.

core dumps generated at this point is far from the crime scene thus hard to debug - 核心转储根本不是"远离犯罪现场",它们完全全面地反映了所谓的犯罪现场.你认为它们难以调试的唯一原因是它还没有学到的东西......但它们绝对是这项工作的正确工具.