views:

2193

answers:

7

Example

int *ptr;
*ptr = 1000;

can I catch memory access violation exception using standard C++ without using any microsoft specific.

+7  A: 

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.

unwind
I know it is HW exceptions, but there are microsoft specific keywords handle this(__try __except)?
Ahmed Said
@Ahmed: yes, but if you use them, 'impossible' things may happen. For instance, some of the statements *after* the AV line of code may have already executed, or statements before the AV have not executed.
Aaron
+5  A: 

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.

JaredPar
So your advice is to know what is the cause of AV exception,is not it?
Ahmed Said
Absolutely. AV's are representative of a bug in your code and catching the exception will just hide the problem.
JaredPar
To clarify, the C++ standard makes a distinction between undefined, unspecified, and implementation defined. Implementation defined means that the implementation must specify what takes place. The code in the question is undefined, which means that anything can happen, and be different each time.
KeithB
+1  A: 

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

Damien
I see that using a Microsoft compiler is treated the same as an illegal instruction or access violation. Interesting.
David Thornley
A: 

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.

David Thornley
A: 

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

Martin York
+3  A: 
// Read it and weep!
//I figured it out. If you dont throw from the handler. 
//The hanlder 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");

}
wow didn't know _that_!
Here Be Wolves
A: 

True David, and thats a good warning for anyone trying to patch bad code. But what if that code is Microsoft ATL. Although you can, you would need to matain you own version. Not fun. Mine was an attemp to catch access violations in ATL because that code itself did not handle these valid situations. Better do this and to try a manual reconnection rather than crash. Dont you think.