Catching SEC Exceptions as C++ Exceptions 
Author Message
 Catching SEC Exceptions as C++ Exceptions

Hi all,

I've noticed that using a standard C++ 'catch all' exception
block in VC6 will catch Structured Exceptions thrown by the
OS. I want to know if there is a way to catch these things
using a C++ catch() block and inspect the result as well.
Something like:

catch( SEC_INFO info )
{
    //...

Quote:
}

Any help would be much appreciated!


Thu, 16 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions
Bill,

Quote:

> I've noticed that using a standard C++ 'catch all' exception
> block in VC6 will catch Structured Exceptions thrown by the
> OS. I want to know if there is a way to catch these things
> using a C++ catch() block and inspect the result as well.

Alas, there is. Use _set_se_translator() to register a translation function
that can throw a C++ exception class you can catch() with whatever info you
require. In it's simplest form, the exception class could simply have the
Win32 exception code, or potentially full stack trace information or
whatever.

--
Tomas Restrepo
http://members.xoom.com/trestrep/



Thu, 16 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions

Quote:

>...you still need to use -EHa.

According to the documentation, -EHa specifies the async
exception handling model... Now, maybe it's just me, but
the text describing the differences between sync and async
wasn't all that enlightening. Look for:

  Synchronous Exception Handling

Specifically, I came away with the impression that all
things caught under async model would be caught under the
sync model as well, just that the sync model wouldn't
unwind some objects in the case of a hardware exception
if it didn't think it needed to.

Is there more to it than this? (BTW, I'm using the the
_set_se_translator method that Tomas mentioned, not the
catch all).

Thanks for the help!



Sat, 18 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions

Quote:


> >...you still need to use -EHa.
> Specifically, I came away with the impression that all things
> caught under async model would be caught under the sync model as
> well, just that the sync model wouldn't unwind some objects in
> the case of a hardware exception if it didn't think it needed to.

Under the synchronous exception model, the compiler might generate
no code for catch(...){} if it can determine that no C++ exceptions
will be thrown in the try{} block. (This depends on the optimisation
level.) Also, as you mention, it can also optimise out some cleanup
code, destructors, etc.

It was a bad idea for MS to have catch(...) catch Win32 exceptions.
It's an evil and unnecessary extension. Can anyone think of a good
reason for it?  Essentially, it forces you to use /EHa when compiling
every program containing catch(...), which can significantly increase
code size.

I'm amazed at the number of replies you've had. I asked a very
similar question a couple of weeks ago and had no concrete replies.
MAYBE I SHOULD SHOUT LOUDER.

Cheerio,
Bennett.

Sent via Deja.com http://www.deja.com/
Before you buy.



Sat, 18 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions

Quote:


>>...you still need to use -EHa.

>According to the documentation, -EHa specifies the async
>exception handling model... Now, maybe it's just me, but
>the text describing the differences between sync and async
>wasn't all that enlightening. Look for:

>  Synchronous Exception Handling

>Specifically, I came away with the impression that all
>things caught under async model would be caught under the
>sync model as well, just that the sync model wouldn't
>unwind some objects in the case of a hardware exception
>if it didn't think it needed to.

>Is there more to it than this? (BTW, I'm using the the
>_set_se_translator method that Tomas mentioned, not the
>catch all).

>Thanks for the help!

The key passage is:

"Under the asynchronous model, the compiler assumes any instruction may
generate an exception.

With the new synchronous exception model, now the default, exceptions can be
thrown only with a throw statement. Therefore, the compiler can assume that
exceptions happen only at a throw statement or at a function call."

When they say "any instruction", they mean things like this:

 char* p = 0;
 *p = 0;

The asynchronous model (/EHa) should be able to deal with that. However,
there's no throw statement, nor is there a function call, and the above
cannot throw a C++ exception, modulo non-standard things like
_set_se_translator(). The intent of the synchronous model (/EHs, /GX) is to
acknowledge this so the compiler can generate better code, and the
synchronous model should provide C++ EH the way it was meant to be. However,
there remains a bug in that catch(...) can catch non-C++ exceptions, i.e.
Win32 structured exceptions (SEs) such as access violations, under some
conditions when using /EHs and under all conditions when using /EHa. I gave
some reasons why catch(...) should never catch non-C++ exceptions in one of
the messages I referred you to. I also described why _set_se_translator()
doesn't really help and gave an alternative approach I hope will be
implemented. Here's another reason. Sometimes, a (template) library author
needs to say:

try
{
   call_a_function_I_did_not_write();

Quote:
}

catch (...)
{
   do_some_cleanup();
   throw;

Quote:
}

If an SE is raised, and it represents a bug, your program has no business
continuing to execute its normal code, including catch(...), which is
supposed to catch only C++ exceptions. If the SE doesn't represent a bug,
maybe it's resumable. If catch(...) caught the SE, nothing good is going to
happen when the tried code is resumed; the clean-up was performed, but it
wasn't needed. And if a real C++ exception is thrown following resumption,
things can get really strange. Finally, note that it's sometimes appropriate
for catch(...) not to rethrow at all.

Back to the docs, which seem to turn contradictory:

"Catching hardware exceptions is still possible with the synchronous model.
However, some of the unwindable objects in the function where the exception
occurs may not get unwound, if the compiler judges their lifetime tracking
mechanics to be unnecessary for the synchronous model."

I'm not really sure what they're thinking about here; it could be
_set_se_translator, or possibly __try/__except. But as I mentioned in those
other messages, you may not catch SEs consistently if you use /EHs in a
release build, due to some rather nice compiler optimizations. You have to
use /EHa to catch even translated SEs consistently.

--
Doug Harrison

Visual C++ MVP



Sat, 18 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions


Quote:

> I'm amazed at the number of replies you've had. I asked a very
> similar question a couple of weeks ago and had no concrete replies.
> MAYBE I SHOULD SHOUT LOUDER.

> Cheerio,
> Bennett.

Well, maybe. But it sounds as though you guys are able to at least
throw/catch C++ exceptions successfully. I don't even seem to be able to do
that. For example, here's my example from a very plain MFC program, written
specifically to see if what isn't working in the real code works at all. The
rest of the code is whatever the AppWizard spits out.

I would expect the following code to behave in the following manner. First,
OnInitialUpdate() calls Createexc(), which end up calling exc(), which
MessageBox()s, then throws. I expect that then Createexc would catch,
MessageBox, and return NULL. Then OnInitialUpdate would MessageBox and
throw.

Now the kicker. In debug mode, I get the 'construct' MessageBox, then the
top-level box about an unhandled exception. BUT, if I debug through the wole
thing in the disassembly window, step by step, I get what I expect. Any
clues?

class exc
{
public:
 exc() {MessageBox(NULL,"construct",NULL, MB_OK);
     throw;};
 ~exc();

Quote:
};

exc *Createexc()
{
 try
 {
  return new exc;
 }
 catch(...)
 {
  MessageBox(NULL,"create",NULL, MB_OK);
  return NULL;
 }

Quote:
}

void CExcView::OnInitialUpdate()
{
 CView::OnInitialUpdate();

 exc *pexc;
 if (Createexc() == NULL)
 {
  MessageBox("initial");
  throw;
 }

Quote:
}

Neil Gilmore



Mon, 20 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions


Quote:

> Now the kicker. In debug mode, I get the 'construct' MessageBox, then the
> top-level box about an unhandled exception. BUT, if I debug through the
wole
> thing in the disassembly window, step by step, I get what I expect. Any
> clues?

Well, I found that the real probmen was the throw; in the constructor.
Everything works fine if I just throw anything, rather than nothing. I
suspect that throwing nothing from the constructor resulted in another throw
somewhere, as there was no object to throw up the chain. It doesn't really
explain the de{*filter*} behavior, though.

I was really just trying to implement a failed constructor. The real code
has a create function in a dll that returns a pointer to an object whose
class is in the dll. The class in the main program is really just there to
make it easy to use the dll.

Neil Gilmore



Mon, 20 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions
Hello again Doug,

You know you refered me to a message that referred to a message
that referred to two others? :)  I read through all of your
replies and they were definitly very informative. Unfortunately
I'm still confused as to a few things. I'll understand if you
don't want to reply again, but I'll ask all the same. :) You say:

Quote:
> The problem with translating SEs into C++ exceptions is that
> you have to write a catch(...) that is intended to catch only
> "true" C++ exceptions as:

>     catch (se_t) { throw; }
>     catch (...)  { ... }

> This is tedious and error-prone. Translating SEs into C++
> exceptions with the help of _set_se_translator really isn't
> much help. It's still hard to use correctly, and it's still
> easy to catch things you really don't want in catch(...).

Why is it that you "have to write a catch(...) that is intended
to catch true c++ exceptions?" I don't see this as being needed
any more or any less than if you didn't have the cath(se_t) above.

Thanks for all your help.



Wed, 22 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions

Quote:

>Hello again Doug,

>You know you refered me to a message that referred to a message
>that referred to two others? :)  I read through all of your
>replies and they were definitly very informative. Unfortunately
>I'm still confused as to a few things. I'll understand if you
>don't want to reply again, but I'll ask all the same. :) You say:

>> The problem with translating SEs into C++ exceptions is that
>> you have to write a catch(...) that is intended to catch only
>> "true" C++ exceptions as:

>>     catch (se_t) { throw; }
>>     catch (...)  { ... }

>> This is tedious and error-prone. Translating SEs into C++
>> exceptions with the help of _set_se_translator really isn't
>> much help. It's still hard to use correctly, and it's still
>> easy to catch things you really don't want in catch(...).

>Why is it that you "have to write a catch(...) that is intended
>to catch true c++ exceptions?" I don't see this as being needed
>any more or any less than if you didn't have the cath(se_t) above.

I'm not sure what you're asking, but I was saying this. To write a
catch(...) that catches only true C++ exceptions, you have to translate SEs
into C++ exceptions and precede every catch(...) with a catch(se_t) that
rethrows, where "se_t" is your translated SE type. By "true C++ exception",
I meant one that isn't an SE, translated or not. And come to think of it,
even this may not be good enough if the SE is resumable.

--
Doug Harrison

Visual C++ MVP



Thu, 23 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions

Quote:

> Well, maybe. But it sounds as though you guys are able to at least
> throw/catch C++ exceptions successfully. I don't even seem to be able
to do
> that.

The problem with the program (see below) is the throw. Executing
"throw;" when no exception is being handled causes terminate() to be
called, because there's nothing to throw! Try "throw 0;" instead.

terminate() is supposed to end the program, so I think the de{*filter*}
does the wrong thing when you step through the code.

Bennett.

Quote:
> For example, here's my example from a very plain MFC program, written
> specifically to see if what isn't working in the real code works at
all. The
> rest of the code is whatever the AppWizard spits out.

> I would expect the following code to behave in the following manner.
First,
> OnInitialUpdate() calls Createexc(), which end up calling exc(), which
> MessageBox()s, then throws. I expect that then Createexc would catch,
> MessageBox, and return NULL. Then OnInitialUpdate would MessageBox and
> throw.

> Now the kicker. In debug mode, I get the 'construct' MessageBox, then
the
> top-level box about an unhandled exception. BUT, if I debug through
the wole
> thing in the disassembly window, step by step, I get what I expect.
Any
> clues?

> class exc
> {
> public:
>  exc() {MessageBox(NULL,"construct",NULL, MB_OK);
>      throw;};
>  ~exc();
> };

> exc *Createexc()
> {
>  try
>  {
>   return new exc;
>  }
>  catch(...)
>  {
>   MessageBox(NULL,"create",NULL, MB_OK);
>   return NULL;
>  }
> }

> void CExcView::OnInitialUpdate()
> {
>  CView::OnInitialUpdate();

>  exc *pexc;
>  if (Createexc() == NULL)
>  {
>   MessageBox("initial");
>   throw;
>  }
> }

> Neil Gilmore


--
-- Bennett McElwee
-- I reserve the right to be wrong.

Sent via Deja.com http://www.*-*-*.com/
Before you buy.



Sat, 25 May 2002 03:00:00 GMT  
 Catching SEC Exceptions as C++ Exceptions


Quote:

> > Well, maybe. But it sounds as though you guys are able to at least
> > throw/catch C++ exceptions successfully. I don't even seem to be able
> to do
> > that.

> The problem with the program (see below) is the throw. Executing
> "throw;" when no exception is being handled causes terminate() to be
> called, because there's nothing to throw! Try "throw 0;" instead.

Well, I figured that out (and posted a response to myself). But I'm not so
sure that terminate() is being called correctly, because I get the unhandled
exception box, though that probably calls terminate.

Quote:
> terminate() is supposed to end the program, so I think the de{*filter*}
> does the wrong thing when you step through the code.

So do I.

Quote:
> Bennett.

Neil Gilmore



Sat, 25 May 2002 03:00:00 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. Catching hardware exceptions using C++ exceptions

2. Catching Win32 exceptions with a C++ catch-block

3. catching Win32 API exceptions in C++

4. Howto catch Win32 exceptions in C++?

5. catching math exceptions with C++

6. Catching SEH and c++ exception

7. C++/MFC and exceptions- catch(...)=bad?

8. Catching Structure Exceptions in C++ EH

9. Q: Why try catch cannot catch the exception

10. Translate a SEH exception into a C++ exception

11. Win32 structured exceptions vs C++ exceptions

12. retrieve exception context in C++ exception handler

 

 
Powered by phpBB® Forum Software