Disabling Exceptions for MSVC - c++

I'm trying to disable exceptions completely in Visual Studio 2010, and to ensure that exception handling is disabled I have the following test:
class CompilerFlagsTestExceptionConstructor
{
public:
CompilerFlagsTestExceptionConstructor() { throw std::exception("Exceptions Enabled"); }
~CompilerFlagsTestExceptionConstructor() { }
};
class CompilerFlagsTests : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE( CompilerFlagsTests );
CPPUNIT_TEST( Test_NoExceptions );
CPPUNIT_TEST_SUITE_END();
public:
void Test_NoExceptions()
{
try
{
CompilerFlagsTestExceptionConstructor object;
}
catch(std::exception)
{
assert(!"Exceptions are enabled");
}
}
};
I have checked in the property pages that exception handling is disabled, and I've also disabled RTTI in all my projects. I have tried setting /EH to negative as well as omitting it from the command line.
Every time I run this test, it fails and it properly throws an exception
The reason I want to disable exception handling is because the target software is written for a target architecture that doesn't natively support exception handling and causes massive code bloat to accommodate the stack unwinding. The target architecture also has a maximum size of executable, so disabling exceptions shrinks code and also has a performance benefit. I want to disable exception handling on the windows version to ensure that the error handling to the target is working.
Am I doing something wrong? Is this test ever going to work? Is there some other way of forcing and testing that exceptions are disabled?
Thanks!

That's not what /EH does, it merely controls what unwind handlers are emitted. /EHsc ensures that destructors are called when C++ exceptions might be raised, /EHa ensures that they're called for any exceptions, including SEH. Omitting /EH is what you want to cut down on handler overhead, the compiler omits the exception filters that get the destructors called on stack-allocated objects. Change the destructor to this:
~CompilerFlagsTestExceptionConstructor() {
assert(!"Something is wrong with /EH");
}
If you want the look for unwanted try/catch code then you'll need to pay attention to
warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc

I'm not sure your test makes sense. What should the behavior be if exceptions are disabled? throw just becomes a no op? That's what the test suggests the behavior is.
I would expect for usefully disabling exceptions throw should be a compile error, or alternatively throwing with exceptions disabled should immediately terminate the process.
But this is a digression. MSVC will emit a call to _CxxThrowException for the throw syntax. If we define our own version of this we can make it dance to our song:
#include <windows.h>
#include <stdio.h>
extern "C"
void __stdcall _CxxThrowException(void * pObject,
_s__ThrowInfo const * pObjectInfo)
{
printf("Nope\n");
}
struct a
{ };
int main()
{
try {
throw a();
} catch(const a&) {
printf("Caught an exception\n");
}
}
This program prints out
Nope
Of course this information is provided for purely entertainment purposes and with the context that you're doing this to match up with the error handling logic. I hope for example, that you don't intend to ship the windows version of the program to anyone like this.

/EHsc- should do the trick (at least it does with msvc 14)

Related

object is not destroyed after catching exception in mixed C and C++ code programming

I am writing a program using mixing c and c++, and I meet a problem about object destruction in c++ exception handler. I wrote a simple case to reproduce the problem.
main.cpp
#include <iostream>
extern "C" void test(void(*f)(void));
struct foo {
~foo() {
std::cout << "foo destruction" << std::endl;
}
};
void error_handler(void) {
throw 1;
}
int main() {
try {
foo f;
test(error_handler);
} catch (...) {
}
}
test.c
void test(void(*handler)(void)) {
handler();
}
When I build this in Visual Studio 2015 and Visual Studio 2017, the foo's destructor was not called. But when I test it using gcc 5.4, the foo's destructor works fine.
Is it possible to throw C++ exception in C code through calling function pointer (which pointer to the function implemented in cpp code)? Is the code above illegal or it's just an msvc bug?
The Windows Exception mechanism is explicitly designed to be able to run destructors and perform finally type cleanup even in the presence of exceptions and similar from other languages.
So what you're asking should work fine on windows - its what its designed to do.
However, you need to explicitly enable this in Visual Studio. By default, visual studio sets up C++ code with /EHsc exception model which explicitly assume that extern "C" functions do not throw or pass through exceptions. This is an optimisation, and generally a good one.
However, if you need to assume that extern "C" functions do throw or pass through exceptions then you need to change your exception model. You probably want /EHs.
However, I'd recommend reading up on the ramifications of this before you change it here.
Edit: Whether to use this functionality or not is debatable. Generally with exceptions (and other similar mechanisms) all code on the stack between the thrower and caller need to be exception safe. If you own the code then this is fine, if there's things like windows callbacks or other libraries on the stack then you need to find a guarantee that this is ok. And in general for windows internal code its not.
Throwing exceptions across language boundaries always leaves program in inconsistent state. Stack unwinding performed in case of C++ exception thrown is guaranteed to work only on (binary compatible) C++ stack frames. C language does not even have a concept of exceptions. Even if stack unwinding manages to unwind C stack frames it will not perform any cleanup for them. So any callback function passed to C code should be declared as noexcept and handle error in some manner that does not involve throwing of exception across language boundary:
void error_handler(void) noexcept {
try
{
throw 1;
}
catch(…)
{
// TODO convert to error code or store for later using exception_ptr
}
}

Exception 0xC0000005 not being caught [duplicate]

Example
int *ptr;
*ptr = 1000;
can I catch memory access violation exception using standard C++ without using any microsoft specific.
Read it and weep!
I figured it out. If you don't throw from the handler, the handler will just continue and so will the exception.
The magic happens when you throw you own exception and handle that.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
printf("Signal %d",signal);
throw "!Access Violation!";
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGSEGV , SignalHandler);
try{
*(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place.
}
catch(char *e)
{
printf("Exception Caught: %s\n",e);
}
printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n");
printf("But please kids, DONT TRY THIS AT HOME ;)\n");
}
There is a very easy way to catch any kind of exception (division by zero, access violation, etc.) in Visual Studio using try -> catch (...) block. A minor project settings tweaking is enough. Just enable /EHa option in the project settings. See Project Properties -> C/C++ -> Code Generation -> Modify the Enable C++ Exceptions to "Yes With SEH Exceptions". That's it!
See details here:
https://learn.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-160
Nope. C++ does not throw an exception when you do something bad, that would incur a performance hit. Things like access violations or division by zero errors are more like "machine" exceptions, rather than language-level things that you can catch.
At least for me, the signal(SIGSEGV ...) approach mentioned in another answer did not work on Win32 with Visual C++ 2015. What did work for me was to use _set_se_translator() found in eh.h. It works like this:
Step 1) Make sure you enable Yes with SEH Exceptions (/EHa) in Project Properties / C++ / Code Generation / Enable C++ Exceptions, as mentioned in the answer by Volodymyr Frytskyy.
Step 2) Call _set_se_translator(), passing in a function pointer (or lambda) for the new exception translator. It is called a translator because it basically just takes the low-level exception and re-throws it as something easier to catch, such as std::exception:
#include <string>
#include <eh.h>
// Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation;
_set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) {
std::string error = "SE Exception: ";
switch (u) {
case 0xC0000005:
error += "Access Violation";
break;
default:
char result[11];
sprintf_s(result, 11, "0x%08X", u);
error += result;
};
throw std::exception(error.c_str());
});
Step 3) Catch the exception like you normally would:
try{
MakeAnException();
}
catch(std::exception ex){
HandleIt();
};
This type of situation is implementation dependent and consequently it will require a vendor specific mechanism in order to trap. With Microsoft this will involve SEH, and *nix will involve a signal
In general though catching an Access Violation exception is a very bad idea. There is almost no way to recover from an AV exception and attempting to do so will just lead to harder to find bugs in your program.
As stated, there is no non Microsoft / compiler vendor way to do this on the windows platform. However, it is obviously useful to catch these types of exceptions in the normal try { } catch (exception ex) { } way for error reporting and more a graceful exit of your app (as JaredPar says, the app is now probably in trouble). We use _se_translator_function in a simple class wrapper that allows us to catch the following exceptions in a a try handler:
DECLARE_EXCEPTION_CLASS(datatype_misalignment)
DECLARE_EXCEPTION_CLASS(breakpoint)
DECLARE_EXCEPTION_CLASS(single_step)
DECLARE_EXCEPTION_CLASS(array_bounds_exceeded)
DECLARE_EXCEPTION_CLASS(flt_denormal_operand)
DECLARE_EXCEPTION_CLASS(flt_divide_by_zero)
DECLARE_EXCEPTION_CLASS(flt_inexact_result)
DECLARE_EXCEPTION_CLASS(flt_invalid_operation)
DECLARE_EXCEPTION_CLASS(flt_overflow)
DECLARE_EXCEPTION_CLASS(flt_stack_check)
DECLARE_EXCEPTION_CLASS(flt_underflow)
DECLARE_EXCEPTION_CLASS(int_divide_by_zero)
DECLARE_EXCEPTION_CLASS(int_overflow)
DECLARE_EXCEPTION_CLASS(priv_instruction)
DECLARE_EXCEPTION_CLASS(in_page_error)
DECLARE_EXCEPTION_CLASS(illegal_instruction)
DECLARE_EXCEPTION_CLASS(noncontinuable_exception)
DECLARE_EXCEPTION_CLASS(stack_overflow)
DECLARE_EXCEPTION_CLASS(invalid_disposition)
DECLARE_EXCEPTION_CLASS(guard_page)
DECLARE_EXCEPTION_CLASS(invalid_handle)
DECLARE_EXCEPTION_CLASS(microsoft_cpp)
The original class came from this very useful article:
http://www.codeproject.com/KB/cpp/exception.aspx
Not the exception handling mechanism,
But you can use the signal() mechanism that is provided by the C.
> man signal
11 SIGSEGV create core image segmentation violation
Writing to a NULL pointer is probably going to cause a SIGSEGV signal
A violation like that means that there's something seriously wrong with the code, and it's unreliable. I can see that a program might want to try to save the user's data in a way that one hopes won't write over previous data, in the hope that the user's data isn't already corrupted, but there is by definition no standard method of dealing with undefined behavior.

How to report a stack buffer overrun on Windows?

In the code shown below I have used all documented ways to detect an exception and produce a diagnostic. It uses the C++ try/catch keywords, catches an SEH exception with the __try/__catch extension keywords, uses the Windows' AddVectoredExceptionHandler() and SetUnhandledExceptionFilter() winapi functions to install VEH/SEH filters.
Running this with Visual C++ 2003:
/GS: outputs "hello,world!" and terminates with exit code 0.
/GS-: outputs "hello,world!" and terminates with exit code 0.
Running this with Visual C++ 2013:
/GS: no output, terminates with exit code -1073740791
/GS-: outputs "hello,world!" and terminates with exit with 0.
How do I produce a diagnostic in a VS2013 compiled program with /GS in effect?
#include "stdafx.h"
#include <Windows.h>
#define CALL_FIRST 1
#define CALL_LAST 0
LONG WINAPI MyVectoredHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
UNREFERENCED_PARAMETER(ExceptionInfo);
printf("MyVectoredHandler\n");
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI MyUnhandledExceptionFilter(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo)
{
printf("SetUnhandledExceptionFilter\n");
return EXCEPTION_CONTINUE_SEARCH;
}
void f()
{
__try
{
char p[20] = "hello,world!";
p[24] = '!';
printf("%s\n", p);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("f() exception\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
AddVectoredExceptionHandler(CALL_FIRST, MyVectoredHandler);
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
try{
f();
}
catch (...){
printf("catched f exception\n");
}
return 0;
}
The CRT function that handles stack buffer overruns detection, __report_gsfailure(), assumes that the stack frame corruption was induced by a malware attack. Such malware traditionally messed with the fs:[0] SEH exception filters (stored on the stack frame) to get an exception handler to trigger the malware payload. One of the ways to get data to turn into executable code.
So that CRT function cannot assume that throwing an exception is safe to do. And no longer does in the CRT included with VS2013, goes back to ~VS2005. It will failfast if the OS supports it and, if not, ensures that a registered VEH/SEH exception handler cannot see the exception either. Kaboom, crash to the desktop with no diagnostic unless you have a debugger attached.
The /SAFESEH option defeats this kind of malware attack so it isn't as serious as it once was. If you are still at the stage where your code suffers from stack corruption bugs and your app is not popular enough to become the target of malware then replacing the CRT function is something you could consider.
Do talk this over with your supervisor, you never want to be personally responsible for this given the enormous liability to your client. History rarely tells the tale of what happened to the one programmer whose code put an entire corporation out of business for a month. But surely wasn't anything pretty.
Paste this code somewhere close to your main() function:
__declspec(noreturn) extern "C"
void __cdecl __report_gsfailure() {
RaiseException(STATUS_STACK_BUFFER_OVERRUN, EXCEPTION_NONCONTINUABLE, 0, nullptr);
}
And plan to remove it again soon.
There is no solution for the question as asked.
Overrunning an array causes undefined behaviour in standard C++, so no particular result is guaranteed. Failure to give a reliable result is not a problem with the compiler - it is permitted behaviour.
I'm aware of no implementation that guarantees any specific behaviour in response to an overrun - VS certainly doesn't. Which is hardly surprising as compilers are not required to do that (that is, essentially, the meaning of undefined behaviour). The reason that is the case is that it is often difficult to reliably or consistently detect such occurrences.
This means the only consistent way to detect an array overrun is to check that array indices are valid BEFORE using them to access an array element and take appropriate actions (e.g. throw an exception which can be caught instead of doing the bad operation). The downside is that it does not provide a simple or reliable way to catch errors in arbitrary code - short of modifying all code to do the required checks.
I would have liked to comment on the accepted answer, but I just joined and don't have enough reputation to do that yet.
I tried the solution with Visual Studio 2017 and had to make a couple of changes to get the solution to compile.
First I had to change the signature of __report_gsfailure to match one of Microsoft's header files to fix a compilation error.
__declspec(noreturn) extern "C" void __cdecl __report_gsfailure(_In_ uintptr_t _StackCookie)
{
RaiseException(STATUS_STACK_BUFFER_OVERRUN, EXCEPTION_NONCONTINUABLE, 0, nullptr);
}
Next I encountered a LNK2005 error, which I was able to correct by adding /FORCE:MULTIPLE to the Linker->Command Line for my project's properties.

Catching access violation exceptions?

Example
int *ptr;
*ptr = 1000;
can I catch memory access violation exception using standard C++ without using any microsoft specific.
Read it and weep!
I figured it out. If you don't throw from the handler, the handler will just continue and so will the exception.
The magic happens when you throw you own exception and handle that.
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
printf("Signal %d",signal);
throw "!Access Violation!";
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGSEGV , SignalHandler);
try{
*(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place.
}
catch(char *e)
{
printf("Exception Caught: %s\n",e);
}
printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n");
printf("But please kids, DONT TRY THIS AT HOME ;)\n");
}
There is a very easy way to catch any kind of exception (division by zero, access violation, etc.) in Visual Studio using try -> catch (...) block. A minor project settings tweaking is enough. Just enable /EHa option in the project settings. See Project Properties -> C/C++ -> Code Generation -> Modify the Enable C++ Exceptions to "Yes With SEH Exceptions". That's it!
See details here:
https://learn.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp?view=msvc-160
Nope. C++ does not throw an exception when you do something bad, that would incur a performance hit. Things like access violations or division by zero errors are more like "machine" exceptions, rather than language-level things that you can catch.
At least for me, the signal(SIGSEGV ...) approach mentioned in another answer did not work on Win32 with Visual C++ 2015. What did work for me was to use _set_se_translator() found in eh.h. It works like this:
Step 1) Make sure you enable Yes with SEH Exceptions (/EHa) in Project Properties / C++ / Code Generation / Enable C++ Exceptions, as mentioned in the answer by Volodymyr Frytskyy.
Step 2) Call _set_se_translator(), passing in a function pointer (or lambda) for the new exception translator. It is called a translator because it basically just takes the low-level exception and re-throws it as something easier to catch, such as std::exception:
#include <string>
#include <eh.h>
// Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation;
_set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) {
std::string error = "SE Exception: ";
switch (u) {
case 0xC0000005:
error += "Access Violation";
break;
default:
char result[11];
sprintf_s(result, 11, "0x%08X", u);
error += result;
};
throw std::exception(error.c_str());
});
Step 3) Catch the exception like you normally would:
try{
MakeAnException();
}
catch(std::exception ex){
HandleIt();
};
This type of situation is implementation dependent and consequently it will require a vendor specific mechanism in order to trap. With Microsoft this will involve SEH, and *nix will involve a signal
In general though catching an Access Violation exception is a very bad idea. There is almost no way to recover from an AV exception and attempting to do so will just lead to harder to find bugs in your program.
As stated, there is no non Microsoft / compiler vendor way to do this on the windows platform. However, it is obviously useful to catch these types of exceptions in the normal try { } catch (exception ex) { } way for error reporting and more a graceful exit of your app (as JaredPar says, the app is now probably in trouble). We use _se_translator_function in a simple class wrapper that allows us to catch the following exceptions in a a try handler:
DECLARE_EXCEPTION_CLASS(datatype_misalignment)
DECLARE_EXCEPTION_CLASS(breakpoint)
DECLARE_EXCEPTION_CLASS(single_step)
DECLARE_EXCEPTION_CLASS(array_bounds_exceeded)
DECLARE_EXCEPTION_CLASS(flt_denormal_operand)
DECLARE_EXCEPTION_CLASS(flt_divide_by_zero)
DECLARE_EXCEPTION_CLASS(flt_inexact_result)
DECLARE_EXCEPTION_CLASS(flt_invalid_operation)
DECLARE_EXCEPTION_CLASS(flt_overflow)
DECLARE_EXCEPTION_CLASS(flt_stack_check)
DECLARE_EXCEPTION_CLASS(flt_underflow)
DECLARE_EXCEPTION_CLASS(int_divide_by_zero)
DECLARE_EXCEPTION_CLASS(int_overflow)
DECLARE_EXCEPTION_CLASS(priv_instruction)
DECLARE_EXCEPTION_CLASS(in_page_error)
DECLARE_EXCEPTION_CLASS(illegal_instruction)
DECLARE_EXCEPTION_CLASS(noncontinuable_exception)
DECLARE_EXCEPTION_CLASS(stack_overflow)
DECLARE_EXCEPTION_CLASS(invalid_disposition)
DECLARE_EXCEPTION_CLASS(guard_page)
DECLARE_EXCEPTION_CLASS(invalid_handle)
DECLARE_EXCEPTION_CLASS(microsoft_cpp)
The original class came from this very useful article:
http://www.codeproject.com/KB/cpp/exception.aspx
Not the exception handling mechanism,
But you can use the signal() mechanism that is provided by the C.
> man signal
11 SIGSEGV create core image segmentation violation
Writing to a NULL pointer is probably going to cause a SIGSEGV signal
A violation like that means that there's something seriously wrong with the code, and it's unreliable. I can see that a program might want to try to save the user's data in a way that one hopes won't write over previous data, in the hope that the user's data isn't already corrupted, but there is by definition no standard method of dealing with undefined behavior.

C++ catching all exceptions

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.
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 (...) {
// ...
}
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.
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;
}
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.
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.
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(...).
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.
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.
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.
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)
Be aware
try{
// ...
} catch (...) {
// ...
}
catches only language-level exceptions, other low-level exceptions/errors like Access Violation and Segmentation Fault wont be caught.
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...
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.)
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...
If you are looking for Windows-specific solution then there is structured exception handling:
https://learn.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.
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.