Naveen
Naveen

Reputation: 73473

Unlocking the critical section in case of non-C++ exceptions

I have a object of CCriticalSection in my class to synchronize the exceptions to a method. I use it with CSingleLock object like this:

void f()
{
  try
   {
     CSingleLock lock(&m_synchronizer, TRUE);
     .....
     .....

   }

  catch(SomeException )
  {
  }

  catch(...)
  {
  }

}

The critical section object is properly unlocked if any of the statement throws a C++ exception, however if I get any other type of exception (something like a access violation) is there any way I can unlock my critical section? I don't think RAII will help here as the stack unwinding doesn't happen. Is there any thing I can do to prevent the critical section being in locked state after exiting the function f?

Upvotes: 0

Views: 1785

Answers (5)

Ryan
Ryan

Reputation: 467

AFAIK, you NEVER should use CCriticalSection nor any MFC synchronization object.

Upvotes: 0

Doug T.
Doug T.

Reputation: 65639

RAII does help here. The most important thing to not here is "going out of scope" is not necessarily just stack unwinding. When the try block is exited, either normally or through an exception, the destructor will be called. Anytime your variable goes out of scope its destructor is invoked.

Edit

Hmm it appears the question has been edited to focus on SEH (non C++ exceptions). In this case the destructor code might not be fired. However, as others have pointed out, most of the non-C++ exceptions are equivalent to application crashes. It may not be reasonable to react to these exceptions in any sane way other than to crash. In this case your app is exited and your critical section will be destroyed anyway.

See @JaredPar's answer for a good solution for translating C SEH exceptions to C++ exceptions for Windows.

Upvotes: 1

James Hopkin
James Hopkin

Reputation: 13973

If you really need your application to survive when a particular area of code performs an access violation, you should consider having that code in a separate process.

If code is trying to read or write to places it's not allowed, what's to stop it writing into other parts of your application's memory, causing all sorts of nasty problems?

Upvotes: 0

Michael Burr
Michael Burr

Reputation: 340316

Assuming you're using MSVC try compiling with the /EHa command line option which maps Windows' structured exceptions to C++ exceptions (the C++ docs sometimes call them 'asynchronous' exceptions).

You should read up on the implications of this - I don't use the option myself, and I'm not sure what the drawbacks might be.

You could also try using the __try, __except, __finally keywords to handle SEH yourself.

Upvotes: 2

JaredPar
JaredPar

Reputation: 755141

EDIT Update

The destructor of CSingleLock will indeed unlock the underlying critical section. Access violations and the like are called SEH exceptions. As to whether or not the destructor will run in the face of an SEH exception is very environment specific. There are tricks you can do to make this type of scenario work.

For instance, one option is to translate all SEH exceptions into a corresponding C++ exception. I blogged recently on the technique to accomplish this. Once they're all C++ exceptions then the destructor being called is guaranteed.

But another question is why bother doing this? Once you're faced with at access violation the only thing your program can reliably do is crash.

Upvotes: 3

Related Questions