有没有C++的等价物来替代Java的
try {
...
}
catch (Throwable t) {
...
}
我正在尝试调试调用本地Windows函数的Java/jni代码,但虚拟机一直崩溃。本地代码在单元测试中看起来很好,只有通过jni调用时才会崩溃。一个通用的异常捕获机制将非常有用。
有没有C++的等价物来替代Java的
try {
...
}
catch (Throwable t) {
...
}
我正在尝试调试调用本地Windows函数的Java/jni代码,但虚拟机一直崩溃。本地代码在单元测试中看起来很好,只有通过jni调用时才会崩溃。一个通用的异常捕获机制将非常有用。
请注意
try{
// ...
} catch (...) {
// ...
}
只捕捉语言级别的异常,其他低级别的异常/错误如访问冲突
和段错误
将不会被捕捉。
catch(...)
和catch(std::exception)
有什么区别? - Mayurcatch(...)
可以捕获所有语言级别抛出的异常,而 catch(std::exception)
只能捕获类型为 std::exception
的异常。例如,如果您调用 throw 5
,只有 catch(...)
可以捕获该异常。 - muaz一种通用的异常捕获机制将非常有用。
这是值得怀疑的。因为代码会崩溃,你已经知道你的代码出了问题。吞掉异常可能会掩盖这个问题,但这可能只会导致更难以发现的错误。
你真正需要的是一个调试器...
您是否可以从控制台窗口运行使用JNI的Java应用程序(从java命令行启动),以查看在JVM崩溃之前是否有任何报告。如果直接作为Java窗口应用程序运行,可能会错过在控制台窗口中运行时出现的消息。
其次,您是否可以存根化您的JNI DLL实现,以显示来自JNI的方法正在被调用,您正在正确返回等?
以防问题是由于C++代码中某个JNI接口方法的错误使用导致的,您是否已验证一些简单的JNI示例是否与您的设置编译并正常工作?我特别考虑使用JNI接口方法将参数转换为本机C++格式并将函数结果转换为Java类型。存根这些方法很有用,以确保数据转换正常工作,并且您不会在调用JNI接口的COM样式调用中出错。
还有其他要检查的事情,但是如果不了解您的本机Java方法是什么以及它们的JNI实现试图做什么,很难建议任何内容。从C++代码级别捕获异常是否与您的问题相关尚不清楚。(您可以使用JNI接口将异常重新抛出为Java异常,但是从您提供的信息来看,这是否有所帮助还不确定。)
针对无法正确调试使用JNI的程序(或者运行时调试器中未出现错误的情况)的真正问题:
在这种情况下,经常有助于在JNI调用周围添加Java包装器(即所有本地方法都是私有的,您类中的公共方法调用它们),以执行一些基本的健全性检查(检查所有“对象”是否被释放,“对象”在释放后是否被使用)或同步(只需将一个DLL中的所有方法与单个对象实例同步)。让Java包装器方法记录错误并抛出异常。
这通常有助于更轻松地找到真正的错误(令人惊讶的是,大多数情况下是Java代码不遵守调用函数的语义,导致某些难以处理的双重释放或类似的问题)而不是尝试在本地调试器中调试大规模并行的Java程序...
如果您知道原因,请在包装器方法中保留避免出错的代码。最好由您的包装器方法抛出异常,而不是您的JNI代码崩溃VM...
__try
{
// code here may throw or make access violation
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
// after exception code here, e.g. log the error
}