Get meaningful information from SEH exception via catch(...)? - c++

Good Morning!
Edit: This is not a duplicate as it specifically pertains to SEH, not code-level thrown exceptions.
I'm using SEH to catch hardware errors thrown by some unreliable libraries. I'd like to get more information from the catchall exception. The following code simulates what I'm doing. As you can see, I'm using boost's current_exception_diagnostic_information, but it just spits out "No diagnostic information available." - not terribly helpful.
Is it possible to, at a minimum, get the termination code that would have been returned had the exception not have been caught? (In this case 0xC0000005, Access Violation)
#include "stdafx.h"
#include <future>
#include <iostream>
#include <boost/exception/diagnostic_information.hpp>
int slowTask()
{
//simulates a dodgy bit of code
int* a = new int[5]();
a[9000009] = 3;
std::cout << a[9000009];
return 0;
}
int main()
{
{
try
{
std::future<int> result(std::async(slowTask));
std::cout<< result.get();
}
catch(...)
{
std::cout << "Something has gone dreadfully wrong:"
<< boost::current_exception_diagnostic_information()
<< ":That's all I know."
<< std::endl;
}
}
return 0;
}

Using catch (...) you get no information at all, whether about C++ exceptions or SEH. So global handlers are not the solution.
However, you can get SEH information through a C++ exception handler (catch), as long as you also use set_se_translator(). The type of the catch should match the C++ exception built and thrown inside your translator.
The function that you write must be a native-compiled function (not compiled with /clr). It must take an unsigned integer and a pointer to a Win32 _EXCEPTION_POINTERS structure as arguments. The arguments are the return values of calls to the Win32 API GetExceptionCode and GetExceptionInformation functions, respectively.
Or you can use __try/__except, which are specific to SEH. They can be used inside C++ just fine, including in programs where C++ exceptions are used, as long as you don't have SEH __try and C++ try in the same function (to trap both types of exceptions in the same block, use a helper function).

Related

NIFs raise Segmentation Fault while loading function has try catch block to handle the exception [duplicate]

Here is a simple piece of code where a division by zero occurs. I'm trying to catch it :
#include <iostream>
int main(int argc, char *argv[]) {
int Dividend = 10;
int Divisor = 0;
try {
std::cout << Dividend / Divisor;
} catch(...) {
std::cout << "Error.";
}
return 0;
}
But the application crashes anyway (even though I put the option -fexceptions of MinGW).
Is it possible to catch such an exception (which I understand is not a C++ exception, but a FPU exception) ?
I'm aware that I could check for the divisor before dividing, but I made the assumption that, because a division by zero is rare (at least in my app), it would be more efficient to try dividing (and catching the error if it occurs) than testing each time the divisor before dividing.
I'm doing these tests on a WindowsXP computer, but would like to make it cross platform.
It's not an exception. It's an error which is determined at hardware level and is returned back to the operating system, which then notifies your program in some OS-specific way about it (like, by killing the process).
I believe that in such case what happens is not an exception but a signal. If it's the case: The operating system interrupts your program's main control flow and calls a signal handler, which - in turn - terminates the operation of your program.
It's the same type of error which appears when you dereference a null pointer (then your program crashes by SIGSEGV signal, segmentation fault).
You could try to use the functions from <csignal> header to try to provide a custom handler for the SIGFPE signal (it's for floating point exceptions, but it might be the case that it's also raised for integer division by zero - I'm really unsure here). You should however note that the signal handling is OS-dependent and MinGW somehow "emulates" the POSIX signals under Windows environment.
Here's the test on MinGW 4.5, Windows 7:
#include <csignal>
#include <iostream>
using namespace std;
void handler(int a) {
cout << "Signal " << a << " here!" << endl;
}
int main() {
signal(SIGFPE, handler);
int a = 1/0;
}
Output:
Signal 8 here!
And right after executing the signal handler, the system kills the process and displays an error message.
Using this, you can close any resources or log an error after a division by zero or a null pointer dereference... but unlike exceptions that's NOT a way to control your program's flow even in exceptional cases. A valid program shouldn't do that. Catching those signals is only useful for debugging/diagnosing purposes.
(There are some useful signals which are very useful in general in low-level programming and don't cause your program to be killed right after the handler, but that's a deep topic).
Dividing by zero is a logical error, a bug by the programmer. You shouldn't try to cope with it, you should debug and eliminate it. In addition, catching exceptions is extremely expensive- way more than divisor checking will be.
You can use Structured Exception Handling to catch the divide by zero error. How that's achieved depends on your compiler. MSVC offers a function to catch Structured Exceptions as catch(...) and also provides a function to translate Structured Exceptions into regular exceptions, as well as offering __try/__except/__finally. However I'm not familiar enough with MinGW to tell you how to do it in that compiler.
There's isn't a
language-standard way of catching
the divide-by-zero from the CPU.
Don't prematurely "optimize" away a
branch. Is your application
really CPU-bound in this context? I doubt it, and it isn't really an
optimization if you break your code.
Otherwise, I could make your code
even faster:
int main(int argc, char *argv[]) { /* Fastest program ever! */ }
Divide by zero is not an exception in C++, see https://web.archive.org/web/20121227152410/http://www.jdl.co.uk/briefings/divByZeroInCpp.html
Somehow the real explanation is still missing.
Is it possible to catch such an exception (which I understand is not a C++ exception, but a FPU exception) ?
Yes, your catch block should work on some compilers. But the problem is that your exception is not an FPU exception. You are doing integer division. I don’t know whether that’s also a catchable error but it’s not an FPU exception, which uses a feature of the IEEE representation of floating point numbers.
On Windows (with Visual C++), try this:
BOOL SafeDiv(INT32 dividend, INT32 divisor, INT32 *pResult)
{
__try
{
*pResult = dividend / divisor;
}
__except(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
return FALSE;
}
return TRUE;
}
MSDN: http://msdn.microsoft.com/en-us/library/ms681409(v=vs.85).aspx
Well, if there was an exception handling about this, some component actually needed to do the check. Therefore you don't lose anything if you check it yourself. And there's not much that's faster than a simple comparison statement (one single CPU instruction "jump if equal zero" or something like that, don't remember the name)
To avoid infinite "Signal 8 here!" messages, just add 'exit' to Kos nice code:
#include <csignal>
#include <iostream>
#include <cstdlib> // exit
using namespace std;
void handler(int a) {
cout << "Signal " << a << " here!" << endl;
exit(1);
}
int main() {
signal(SIGFPE, handler);
int a = 1/0;
}
As others said, it's not an exception, it just generates a NaN or Inf.
Zero-divide is only one way to do that. If you do much math, there are lots of ways, like
log(not_positive_number), exp(big_number), etc.
If you can check for valid arguments before doing the calculation, then do so, but sometimes that's hard to do, so you may need to generate and handle an exception.
In MSVC there is a header file #include <float.h> containing a function _finite(x) that tells if a number is finite.
I'm pretty sure MinGW has something similar.
You can test that after a calculation and throw/catch your own exception or whatever.

How can some code be run each time an exception is thrown in a Visual C++ program?

If an exception is thrown in a C++ program control is either transferred to the exception handler or terminate() is called.
Even if the program emits some diagnostics from inside the handler (or from terminate() handler) that can be too late - the most value is in the call stack at the point where the exception is thrown, not in the handler.
On Windows a call stack can be obtained using [StackWalk64()]1 function. The key is how to call that function at the right moment.
Is there a way to make a Visual C++ program execute some user code each time an exception (or an exception for which no handler is set) is thrown?
If you want to do stuff when an SEH exception is thrown, such as when an access violation occurs, then you can simply catch the SEH exception (either with a __finally, or with a conversion to a C++ exception (see here)) and access the context within the exception which is the context at the time the exception was thrown. You can then generate either a callstack using StackWalker or a mini dump. IMHO it's better to produce a mini dump.
If you want to catch C++ exceptions at the point they're thrown and you don't have access to the source to the C++ exception classes then you need to get a bit craftier. I deal with this problem by running the target process under a custom debugger - use the Debug API (see here) which gets notifications of when an exception is thrown. At that point you can create a mini dump or call stack of the target process.
On Windows I'm using SetUnhandledExceptionFilter and MiniDumpWriteDump to produce a minidump.
__try, __except are very helpful.
Is there a way to make a Visual C++ program execute some user code each time an exception (or an exception for which no handler is set) is thrown?
Put that code into the constructor of your exception base class.
When the language doesn't support it, and you can't live without it, hack... :-/
#include <iostream>
#include <stdexcept>
namespace Throw_From
{
struct Line
{
Line& set(int x) { x_ = x; return *this; }
int x_;
template <typename T>
void operator=(const T& t) const
{
throw t;
}
};
Line line;
}
#define throw Throw_From::line.set(__LINE__) =
void fn2()
{
throw std::runtime_error("abc");
}
void fn1()
{
fn2();
}
int main()
{
try
{
fn1();
}
catch (const std::runtime_error& x)
{
std::cout << Throw_From::line.x_ << '\n';
}
}
This is a great article on how to catch all different types of exceptions in Visual C++.
It also provides you with a crash dump that comes useful for debugging.

C++ unhandled exceptions

Does C++ offer a way to 'show' something visual if an unhandled exception occurs?
What I want to do is to make something like assert(unhandled exception.msg()) if it actually happens (like in the following sample):
#include <stdexcept>
void foo() {
throw std::runtime_error("Message!");
}
int main() {
foo();
}
I expect this kind of code not to terminate immediately (because exception was unhandled), rather show custom assertion message (Message! actually).
Is that possible?
There's no way specified by the standard to actually display the message of the uncaught exception. However, on many platforms, it is possible anyway. On Windows, you can use SetUnhandledExceptionFilter and pull out the C++ exception information. With g++ (appropriate versions of anyway), the terminate handler can access the uncaught exception with code like:
void terminate_handler()
{
try { throw; }
catch(const std::exception& e) { log(e.what()); }
catch(...) {}
}
and indeed g++'s default terminate handler does something similar to this. You can set the terminate handler with set_terminate.
IN short, no there's no generic C++ way, but there are ways depending on your platform.
Microsoft Visual C++ allows you to hook unhandled C++ exceptions like this. This is standard STL behaviour.
You set a handler via a call to set_terminate. It's recommended that your handler do not very much work, and then terminate the program, but I don't see why you could not signal something via an assert - though you don't have access to the exception that caused the problem.
I think you would benefit from a catch-all statement as follows:
int main() {
try {
foo();
catch (...) {
// Do something with the unhandled exception.
}
}
If you are using Windows, a good library for handling unhandled exceptions and crashes is CrashRpt. If you want to do it manually you can also use the following I wrote in this answer.
If I'm reading your question correctly, you're asking if you can overload throw (changing its default behavior) so it does something user-defined. No, you can't.
Edit: since you're insistent :), here's a bad idea™:
#include <iostream>
#include <stdlib.h>
#include <windows.h>
void monkey() {
throw std::exception("poop!");
}
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS *lpTopLevelExceptionFilter) {
std::cout << "poop was thrown!" << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
int main() {
SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter);
monkey();
return 1;
}
Again, this is a very bad idea, and it's obviously platform-dependent, but it works.
Yes, its possible. Here you go:
#include <iostream>
#include <exception>
void foo()
{
throw std::exception("Message!");
}
int main()
{
try
{
foo();
}
catch (std::exception& e)
{
std::cout << "Got exception: " << e.what() << std::endl;
}
return 0;
}
The c++ standard is the terminate handler - as other have said
If you are after better traceablility for throws then this is what we do
We have a macro Throw that logs the file name and line number and message and then throws. It takes a printf style varargs message.
Throw(proj::FooException, "Fingle %s unable to process bar %d", fingle.c_str(), barNo);
I get a nice log message
Throw FooException from nargle.cpp:42 Fingle barf is unable to process bar 99
If you're really interested in what happened to cause your program to fail, you might benefit from examining the process image in a post-mortem debugger. The precise technique varies a bit from OS to OS, but the basic train is to first enable core dumping, and compile your program with debug symbols on. Once the program crashes, the operating system will copy its memory to disk, and you can then examine the state of the program at the time it crashed.

Help with Try Catch

I'm using the GLUTesselator and every once in a while EndContour() fails so I did this:
try
{
PolygonTesselator.End_Contour();
}
catch (int e)
{
renderShape = false;
return;
}
Why would it still crash, it should perform the catch code right?
How could I fix this?
Thanks
Does PolygonTesselator.End_Contour(); crash or throws it an exception?
Note that a real "crash" (segfault, illegal instruction etc.) does not throw an exception in the sense of C++.
In these cases, the CPU triggers an interrupt - this is also sometimes called exception, but has nothing to do with an C++ exception.
In C++ you are running on a real CPU - and not in a virtual machine like in Java where every memory violation results in language execption like NullPointerException or ArrayOutOfBoundsException.
In C/C++ a CPU exception / interrupt / trap is handled by the operating system and forwarded to the process as "signal". You can trap the signal but usually this does not help for crashes (SIGSEG, SIGILL, SIGFPU, etcc.).
You're getting SEH exception, or Structured Exception Handling. These exceptions are thrown by Windows under an entirely different system since SEH predates C++, and can't be caught by a standard C++ catch block (MSVC does however provide SEH catching).
Alternatively, if you're on Unix, the kernel doesn't use C++ exceptions either. It uses signals. I don't pretend to understand signals, since I don't develop for Unix, but I'm very sure they're not C++ exceptions.
You've violated a hardware rule that you can't de-reference a NULL pointer. You'll get an OS-level error, by exception or signal. You can't catch these things in a C++ catch block just like that.
Edit: If you're using MSVC on Windows and have a recent compiler, you CAN enable /EHa, which allows you to catch Structured Exceptions as well as C++ exceptions. I wrote this code that functions as shown:
int main() {
std::string string = "lolcakes";
try {
Something s;
int i, j;
i = 0; j = 1;
std::string input;
std::cin >> input;
if (input == "Structured")
int x = j / i;
else
throw std::runtime_error("Amagad hai!");
}
catch(std::runtime_error& error) {
std::cout << "Caught a C++ exception!" << std::endl;
}
catch(...) {
std::cout << "Caught a structured exception!" << std::endl;
}
return main();
}
Structured Exceptions include Access Violations, your particular error.
Two things :
If you are under VC 6 or more recent, use __try{}__except(EXCEPTION_EXECUTE_HANDLER){} instead. It will catch the SE. try/catch only catches C++ exceptions
I've had a hard time with GLU, so I can tell you this : if you can set the normal, SET IT. But otherwise, it's true that it's quite solid.
Since all you want to do when the exception arrives is set 'renderShape' to false I'd recomment the following code:
try
{
PolygonTesselator.End_Contour();
}
catch (...) // takes any type of exception
{
renderShape = false;
return;
}
That said of course if you really can't fix the source to the exception itself!!
Why would it still crash, it should
perform the catch code right? How
could I fix this?
Most likely because you are not actually catching what is being thrown. Are you sure that PolygonTesselator.End_Contour(); throws an int?
If your program fails with the message error reading from location 0x000000000, then it is not failing because of an exception, but because of a segfault. You can use the segvcatch utility to convert segfaults into catchable exceptions. Check out their examples.
As mentioned, this is an SEH Exception.
If you are using Visual Studio, you can configure your project to catch SEH exceptions in your try/catch block.
Project Properties > C/C++ > Code
Generation > Enable C++ Exceptions >
Yes with SEH Exceptions

Will C++ exceptions safely propagate through C code?

I have a C++ application that calls SQLite's (SQLite is in C) sqlite3_exec() which in turn can call my callback function implemented in C++. SQLite is compiled into a static library.
If an exception escapes my callback will it propagate safely through the C code of SQLite to the C++ code calling sqlite3_exec()?
My guess is that this is compiler dependent. However, throwing an exception in the callback would be a very bad idea. Either it will flat-out not work, or the C code in the SQLite library will be unable to handle it. Consider if this is some code in SQLite:
{
char * p = malloc( 1000 );
...
call_the_callback(); // might throw an exception
...
free( p );
}
If the exception "works", the C code has no possible way of catching it, and p will never be freed. The same goes for any other resources the library may have allocated, of course.
There is already a protocol for the callback to abort the API call. From the docs:
If an sqlite3_exec() callback returns
non-zero, the sqlite3_exec() routine
returns SQLITE_ABORT without invoking
the callback again and without running
any subsequent SQL statements.
I'd strongly recommend you use this instead of an exception.
SQLite is expecting you to return a SQLITE_ABORT on error and a 0 return code for no error. So you ought to wrap all your C++ callback in a try catch. Then in the catch return a SQLite SQLITE_ABORT error code, otherwise a zero.
Problems will occur if you bypass returning through SQLite as it will not free up/complete whatever code it does after you return back from your callback. This will cause untold problems potentially some of which maybe very obscure.
That was a really interesting question and I tested it out myself out of curiosity. On my OS X w/ gcc 4.2.1 the answer was YES. It works perfectly. I think a real test would be using gcc for the C++ and some other (MSVC?, LLVM?) for the C part and see if it still works.
My code:
callb.h:
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*t_callb)();
void cfun(t_callb fn);
#ifdef __cplusplus
}
#endif
callb.c:
#include "callb.h"
void cfun(t_callb fn) {
fn();
}
main.cpp:
#include <iostream>
#include <string>
#include "callb.h"
void myfn() {
std::string s( "My Callb Except" );
throw s;
}
int main() {
try {
cfun(myfn);
}
catch(std::string s) {
std::cout << "Caught: " << s << std::endl;
}
return 0;
}
If your callback called from sqlite is from the same thread from which you called sqlite3_exec() a throw somewhere in the callstack should be caught by a higher level catch.
Testing this yourself should be straightforward, no?
[edit]
After digging a little more myself I found out that the C++ standard is somewhat vague on what the behavior a c++ function called from c should have when throwing an exception.
You should definitely use the error handling mechanism the API expects. Otherwise you'll mostly the API itself in an undefined state and any further calls could potentially fail/crash.
Not a single answer mentioning building your C library with -fexceptions? Throw in a -fno-omit-framepointer and you are good to go. This works even across a shared library (written in C), as long as you throw from your main program, and catch in your main program again.