Sign in to follow this  
Rattrap

Catching an Access Violation Exception

Recommended Posts

Rattrap    3385
#include <iostream>
using namespace std;

int main(void)
{
     try
     {
          *(int *) 0 = 0;
     }
     catch(...)
     {
          cout << "Exception" << end;
     }

     return 0;
}



This code is supposed to fail. It should cause an access violation. I'm using Windows XP Pro and Visual Studio 2005 Beta 2. I believe that instead of throwing a C++ exception, it is throwing a c managed exception (or a seh windows exception). I'm looking to see if there is a portable way to actually catch this exception. I'm pretty sure in Windows I can use the _set_se_handler function to basically reroute the exception and throw my own c++ style exception, but again that doesn't seen very portable. Any ideas? [edit] It should compile successfully, but as the one real line of code is executed, it should cause an acess violation.

Share this post


Link to post
Share on other sites
Anon Mike    1098
C++ exceptions are very different things than OS exceptions like AV's. For OS exceptions you need to use __try/__except/__finally instead of try/catch.

For older version of MSVC using catch(...) to catch OS exceptions used to kinda-sorta work maybe. It doesn't work at all with newer versions.

Share this post


Link to post
Share on other sites
Zahlman    1682
Under POSIX, you can register handlers for such exceptions with signal(). A bad pointer access normally generates a "segmentation fault" exception, which carries the id (integer constant value) SIGSEGV.

Share this post


Link to post
Share on other sites
MaulingMonkey    1728
Quote:
Original post by Zahlman
Under POSIX, you can register handlers for such exceptions with signal(). A bad pointer access normally generates a "segmentation fault" exception, which carries the id (integer constant value) SIGSEGV.


My signal(2) manpage states this "conforms to" ANSI C - which I believe means it's standard to that - makes no mention of POSIX like most POSIX standard functions.

On "broken" systems (like my MinGW one) SIGSEGV dosn't appear to be defined - manually definining it as 11 gets it to work on Windows XP Home, from my signal(7) linux manpage which states the value of SIGSEGV as 11 - it also appears that SIGSEGV == 11 is a POSIX.1 standard.

Example:

#include <cassert>
#include <csignal>
#include <iostream>
using namespace std;

#define SIGSEGV 11

void sigsegv_handler( int signal )
{
assert( signal == SIGSEGV );
cout << "Oh sh**" << endl;
}

int main ( int argc , char ** argv )
{
//Setting a signal handler:
sighandler_t old_signal_handler = signal( SIGSEGV , sigsegv_handler );

//Having fun being evil:
*(int *)0 = 0;
cout << "This will never be printed, since this thread gets killed."
<< "However, \"Oh sh**\" will be, in the signal handler. Cool eh :)"
<< endl;

//Restoring a signal handler:
signal( SIGSEGV , old_signal_handler );
}



There's also a SEH patch for GCC floating around out there, 3.4 branch IIRC, although a quick google search didn't find good results on the first page (my internet is being sh**, so I'll leave further searching to the reader)

Share this post


Link to post
Share on other sites
Anon Mike    1098
Quote:
Original post by Rattrap
__try / __catch are MS specific, aren't they? From what I've been reading, it didn't sound like there was a portable way to do it.


There isn't a fully portable way of doing it no. MSVC doesn't support handling AV's via SIGSEGV. You're really getting into the guts of OS-specific issues when you start talking about handling these sorts of things.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this