c++中有类似Java的吗

try {
    ...
}
catch (Throwable t) {
    ...
}

我试图调试Java/jni代码调用本机windows函数和虚拟机不断崩溃。本机代码在单元测试中表现良好,只有在通过jni调用时才会崩溃。一个通用的异常捕获机制将被证明是非常有用的。


当前回答

你可以使用

catch(...)

但这是非常危险的。在约翰·罗宾斯的《调试Windows》一书中,他讲述了一个战争故事,一个非常严重的bug被一个catch(…)命令掩盖了。您最好捕获特定的异常。捕获您认为try块可能合理抛出的任何异常,但如果确实发生意外,则让代码抛出更高的异常。

其他回答

请注意

try{
// ...
} catch (...) {
// ...
}

仅捕获语言级异常,其他低级异常/错误,如访问违反和分割错误不会被捕获。

Can you run your JNI-using Java application from a console window (launch it from a java command line) to see if there is any report of what may have been detected before the JVM was crashed. When running directly as a Java window application, you may be missing messages that would appear if you ran from a console window instead. Secondly, can you stub your JNI DLL implementation to show that methods in your DLL are being entered from JNI, you are returning properly, etc? Just in case the problem is with an incorrect use of one of the JNI-interface methods from the C++ code, have you verified that some simple JNI examples compile and work with your setup? I'm thinking in particular of using the JNI-interface methods for converting parameters to native C++ formats and turning function results into Java types. It is useful to stub those to make sure that the data conversions are working and you are not going haywire in the COM-like calls into the JNI interface. There are other things to check, but it is hard to suggest any without knowing more about what your native Java methods are and what the JNI implementation of them is trying to do. It is not clear that catching an exception from the C++ code level is related to your problem. (You can use the JNI interface to rethrow the exception as a Java one, but it is not clear from what you provide that this is going to help.)

让我在这里提一下:Java

try 
{
...
}
catch (Exception e)
{
...
}

可能无法捕获所有异常!其实我以前也遇到过这种事,很让人抓狂;Exception派生自Throwable。因此,从字面上看,要捕获所有东西,你不希望捕获异常;你想抓住Throwable。

我知道这听起来很挑剔,但是当你花了好几天时间试图弄清楚“未捕获的异常”来自于被try包围的代码时……catch (Exception e)" block来自哪里,它会一直跟着你。

可以这样写:

try
{
  //.......
}
catch(...) // <<- catch all
{
  //.......
}

但是这里有一个非常不明显的风险:您无法找到try块中抛出的错误的确切类型,因此当您确定无论异常类型是什么,程序都必须以catch块中定义的方式持续存在时,可以使用这种catch。

对于无法正确调试使用JNI的程序的真正问题(或者在调试器下运行时不出现错误):

在这种情况下,在JNI调用(即所有本机方法都是私有的,类中的公共方法调用它们)周围添加Java包装器通常会有所帮助,这些包装器会做一些基本的完整性检查(检查所有“对象”都被释放,释放后“对象”没有被使用)或同步(将所有方法从一个DLL同步到单个对象实例)。让java包装器方法记录错误并抛出异常。

这通常有助于发现真正的错误(令人惊讶的是,这些错误主要出现在Java代码中,不遵守被调用函数的语义,导致一些讨厌的double-free或类似的情况),比尝试在本地调试器中调试大型并行Java程序更容易……

如果您知道原因,请将代码保存在可以避免该原因的包装器方法中。最好让你的包装器方法抛出异常,而不是你的JNI代码崩溃VM…