285
votes

Is there a c++ equivalent of Java's

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

I am trying to debug Java/jni code that calls native windows functions and the virtual machine keeps crashing. The native code appears fine in unit testing and only seems to crash when called through jni. A generic exception catching mechanism would prove extremely useful.

16
Note that most crashes are not caused by exceptions in C++. You can catch all exceptions, but that won't prevent many crashes.Mooing Duck

16 Answers

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

will catch all C++ exceptions, but it should be considered bad design. You can use c++11's new current_exception mechanism, but if you don't have the ability to use c++11 (legacy code systems requiring a rewrite), then you have no named exception pointer to use to get a message or name. You may want to add separate catch clauses for the various exceptions you can catch, and only catch everything at the bottom to record an unexpected exception. E.g.:

try{
    // ...
} catch (const std::exception& ex) {
    // ...
} catch (const std::string& ex) {
    // ...
} catch (...) {
    // ...
}
159
votes

Someone should add that one cannot catch "crashes" in C++ code. Those don't throw exceptions, but do anything they like. When you see a program crashing because of say a null-pointer dereference, it's doing undefined behavior. There is no std::null_pointer_exception. Trying to catch exceptions won't help there.

Just for the case someone is reading this thread and thinks he can get the cause of the program crashes. A Debugger like gdb should be used instead.

84
votes

This is how you can reverse-engineer the exception type from within catch(...) should you need to (may be useful when catching unknown from a third party library) with GCC:

#include <iostream>

#include <exception>
#include <typeinfo>
#include <stdexcept>

int main()
{
    try {
        throw ...; // throw something
    }
    catch(...)
    {
        std::exception_ptr p = std::current_exception();
        std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
    }
    return 1;
}

and if you can afford using Boost you can make your catch section even simpler (on the outside) and potentially cross-platform

catch (...)
{
    std::clog << boost::current_exception_diagnostic_information() << std::endl;
}
63
votes
try {
   // ...
} catch (...) {
   // ...
}

Note that the ... inside the catch is a real ellipsis, ie. three dots.

However, because C++ exceptions are not necessarily subclasses of a base Exception class, there isn't any way to actually see the exception variable that is thrown when using this construct.

52
votes

it is not possible (in C++) to catch all exceptions in a portable manner. This is because some exceptions are not exceptions in a C++ context. This includes things like division by zero errors and others. It is possible to hack about and thus get the ability to throw exceptions when these errors happen, but it's not easy to do and certainly not easy to get right in a portable manner.

If you want to catch all STL exceptions, you can do

try { ... } catch( const std::exception &e) { ... }

Which will allow you do use e.what(), which will return a const char*, which can tell you more about the exception itself. This is the construct that resembles the Java construct, you asked about, the most.

This will not help you if someone is stupid enough to throw an exception that does not inherit from std::exception.

34
votes

In short, use catch(...). However, note that catch(...) is meant to be used in conjunction with throw; basically:

try{
    foo = new Foo;
    bar = new Bar;
}
catch(...)       // will catch all possible errors thrown. 
{ 
    delete foo;
    delete bar;
    throw;       // throw the same error again to be handled somewhere else
}

This is the proper way to use catch(...).

22
votes

it is possible to do this by writing:

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

But there is a very not noticeable risk here: you can not find the exact type of error that has been thrown in the try block, so use this kind of catch when you are sure that no matter what the type of exception is, the program must persist in the way defined in the catch block.

18
votes

You can use

catch(...)

but that is very dangerous. In his book Debugging Windows, John Robbins tells a war story about a really nasty bug that was masked by a catch(...) command. You're much better off catching specific exceptions. Catch whatever you think your try block might reasonably throw, but let the code throw an exception higher up if something really unexpected happens.

15
votes

Let me just mention this here: the Java

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

may NOT catch all exceptions! I've actually had this sort of thing happen before, and it's insantiy-provoking; Exception derives from Throwable. So literally, to catch everything, you DON'T want to catch Exceptions; you want to catch Throwable.

I know it sounds nitpicky, but when you've spent several days trying to figure out where the "uncaught exception" came from in code that was surrounded by a try ... catch (Exception e)" block comes from, it sticks with you.

10
votes

Well, if you would like to catch all exception to create a minidump for example...

Somebody did the work on Windows.

See http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus In the article, he explains how he found out how to catch all kind of exceptions and he provides code that works.

Here is the list you can catch:

 SEH exception
 terminate
 unexpected
 pure virtual method call
 invalid parameter
 new operator fault 
 SIGABR
 SIGFPE
 SIGILL
 SIGINT
 SIGSEGV
 SIGTERM
 Raised exception
C++ typed exception

And the usage: CCrashHandler ch; ch.SetProcessExceptionHandlers(); // do this for one thread ch.SetThreadExceptionHandlers(); // for each thred


By default, this creates a minidump in the current directory (crashdump.dmp)

5
votes

A generic exception catching mechanism would prove extremely useful.

Doubtful. You already know your code is broken, because it's crashing. Eating exceptions may mask this, but that'll probably just result in even nastier, more subtle bugs.

What you really want is a debugger...

5
votes

Be aware

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

catches only language-level exceptions, other low-level exceptions/errors like Access Violation and Segmentation Fault wont be caught.

3
votes
  1. 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.

  2. 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?

  3. 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.

  4. 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.)

2
votes

For the real problem about being unable to properly debug a program that uses JNI (or the bug does not appear when running it under a debugger):

In this case it often helps to add Java wrappers around your JNI calls (i.e. all native methods are private and your public methods in the class call them) that do some basic sanity checking (check that all "objects" are freed and "objects" are not used after freeing) or synchronization (just synchronize all methods from one DLL to a single object instance). Let the java wrapper methods log the mistake and throw an exception.

This will often help to find the real error (which surprisingly is mostly in the Java code that does not obey the semantics of the called functions causing some nasty double-frees or similar) more easily than trying to debug a massively parallel Java program in a native debugger...

If you know the cause, keep the code in your wrapper methods that avoids it. Better have your wrapper methods throw exceptions than your JNI code crash the VM...

1
votes

Well this really depends on the compiler environment. gcc does not catch these. Visual Studio and the last Borland that I used did.

So the conclusion about crashes is that it depends on the quality of your development environment.

The C++ specification says that catch(...) must catch any exceptions, but it doesn't in all cases.

At least from what I tried.

1
votes

If you are looking for Windows-specific solution then there is structured exception handling: https://docs.microsoft.com/en-us/cpp/cpp/try-except-statement

The code looks as follows

__try
{
   // code here may throw or make access violation
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
    // after exception code here, e.g. log the error
}

It will catch not only C++ exceptions but also access violations or other system exceptions.