大家,
假设我在Windows中有一个简单的JNI程序:
int* p = NULL;
*p = 5;
当从JVM运行它时,不像普通的C ++应用程序,JVM将很好地捕获这样的硬异常并做一些清理工作。
这里的问题是它也阻止我在那里生成崩溃转储,尽管有一个JVM选项:-XX:OnError,但此时生成的核心转储远离犯罪现场,因此难以调试。
JVM使用SEH包装每个Java线程:
__try
{
thread.run()
}
__except(topLevelExceptionFilter())
{
}
导致访问冲突的JNI代码发生在thread.run中,但是在topLevelExceptionFilter中处理,该事件已经在其他地方了。
你有什么建议吗?
感谢。
答案 0 :(得分:6)
您可以使用OnError设置启动本机调试器,如下所示:
http://download.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/clopts.html#gbmum
java -XX:OnError="gdb - %p" MyApplication
适用于Windows
JDK7还有一个-XX:+ShowMessageBoxOnError
或-XX:+UseOSErrorReporting
选项,不确定它是否适用于Linux核心转储,它应该适用于Windows和默认的OS调试器(DrWatson)。见http://blogs.oracle.com/poonam/entry/more_on_windows_crash_dumps
答案 1 :(得分:5)
core
是一个C ++崩溃转储...您没有Java提供的便利设施,以便更容易使用。如果编译本机代码以保留符号(理想情况下不进行优化),则可以使用gdb或其他调试器对其进行分析,并在失败点获取堆栈跟踪,以及读取变量等。
core dumps generated at this point is far from the crime scene thus hard to debug
- 核心转储根本不是“远离犯罪现场”,它们对所谓的犯罪现场完全全面。你认为它们难以调试的唯一原因是它还没有学到的东西......但它们绝对是这项工作的正确工具。
答案 2 :(得分:0)
在linux中使用ulimit -c unlimited来生成核心转储 然后使用gdb用java进程调试核心文件。