Multithreading and exceptions

How can one pass exceptions across threads?

Suppose you have a “black-box” function DoSomething(). The
implementation is hidden from the caller. In other words, all the
caller knows is that it’s a synchronous function that does what it’s
supposed to do and then return. Further suppose that the specification
for DoSomething() indicates it may throw various exceptions. At some
point in the future, say we decide to change the implementation of
DoSomething(). The new implementation makes use of one or more worker
threads to perform its given task. Any of these threads may throw an
exception. The problem is how to pass this exception to the thread that
called DoSomething() in the first place, without losing any exception
type information, so that all the existing calls to DoSomething()
continue working as before, thus hiding any changes in implementation
details.

What appears to be needed is a (compiler-dependent, probably low-level)
method to get at the raw exception data at catch-time, then use
synchronization to pass this raw data to the DoSomething() thread, and
have the DoSomething() function re-throw the exception based on the raw
exception data in such a way that all exception information (including
type) is preserved. Does anyone have any suggestions on how to do this?
Note, generic methodologies that work on arbitrary exception types would
be most useful. Methodologies that require a common exception base
class are less useful, but could be discussed. Finally, coding
catch/synchronize/re-throw traps for every “known” type of exception is
neither feasible nor desirable.

Thanks,

Chuck

I won’t say Structured Exception Handling is necessarily your friend here,
but it may be more helpful than C++ exception handling.

It depends on the level of the sort of stuff you want to catch and pass on.
If you are dealing with exceptions you have defined and are throwing, it
should be pretty easy. Look at the SEH stuff, there are a half dozen
function calls.

If you want to handle arbitrary check conditions, you can do at least some
of that. That is likely to get very machine dependent though, although I
suspect it could be managed.

Loren

My suggestion is that you catch all exceptions in your thread. If you catch
one, keep it aside, in a memory section accessible by the main function.
When the thread completes, your main function looks if any exception has
been caught by the thread and throws the exception again for the caller to
catch.

It won’t be the thread who directly throws to the caller but the result will
be the same.

Mat

-----Original Message-----
From: Chuck Batson [mailto:xxxxx@cbatson.com]
Sent: Monday, May 12, 2003 12:37 AM
To: NT Developers Interest List
Subject: [ntdev] Multithreading and exceptions

How can one pass exceptions across threads?

Suppose you have a “black-box” function DoSomething(). The
implementation is hidden from the caller. In other words, all the
caller knows is that it’s a synchronous function that does what it’s
supposed to do and then return. Further suppose that the specification
for DoSomething() indicates it may throw various exceptions. At some
point in the future, say we decide to change the implementation of
DoSomething(). The new implementation makes use of one or more worker
threads to perform its given task. Any of these threads may throw an
exception. The problem is how to pass this exception to the thread that
called DoSomething() in the first place, without losing any exception
type information, so that all the existing calls to DoSomething()
continue working as before, thus hiding any changes in implementation
details.

What appears to be needed is a (compiler-dependent, probably low-level)
method to get at the raw exception data at catch-time, then use
synchronization to pass this raw data to the DoSomething() thread, and
have the DoSomething() function re-throw the exception based on the raw
exception data in such a way that all exception information (including
type) is preserved. Does anyone have any suggestions on how to do this?
Note, generic methodologies that work on arbitrary exception types would
be most useful. Methodologies that require a common exception base
class are less useful, but could be discussed. Finally, coding
catch/synchronize/re-throw traps for every “known” type of exception is
neither feasible nor desirable.

Thanks,

Chuck


You are currently subscribed to ntdev as: xxxxx@guillemot.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Mat,

Thank you for your input. Either I am misunderstanding what you’re
suggesting, or it’s not feasible. What do you mean by “catch all
exceptions in your thread”? If we catch all exceptions like this:

try {
//…
}
catch (…) {
}

There’s no exception data available at all to keep aside, at least as
far as intrinsically available via standard C++. (Though I suspect
there may be a compiler-dependent way to do this, with which I am hoping
someone with prior experience can help.) Perhaps you are suggesting
something like this:

union {
ExceptionA a;
ExceptionB b;
} Exceptions;

try {
//…
}
catch (const ExceptionA & e) {
Exceptions.a = e;
}
catch (const ExceptionB & e) {
Exceptions.b = e;
}
// and so on…

This isn’t practical, as it’s error-prone (I have to remember to add a
specific handler for every new exception type). Or more difficult,
perhaps my function is using a third-party library for which I have no
knowledge (or no desire to know) about exception types it uses
internally.

Note, using a common exception base class doesn’t solve this issue.
Recall that the type of the exception object is determined statically
by the static type of the argument given to the throw keyword.

Thanks,

Chuck

----- Original Message -----
From: “Mathieu Routhier”
To: “NT Developers Interest List”
Sent: Monday, May 12, 2003 7:49 PM
Subject: [ntdev] RE: Multithreading and exceptions

> My suggestion is that you catch all exceptions in your thread. If you
catch
> one, keep it aside, in a memory section accessible by the main
function.
> When the thread completes, your main function looks if any exception
has
> been caught by the thread and throws the exception again for the
caller to
> catch.
>
> It won’t be the thread who directly throws to the caller but the
result will
> be the same.

>
> Mat
>
>
> -----Original Message-----
> From: Chuck Batson [mailto:xxxxx@cbatson.com]
> Sent: Monday, May 12, 2003 12:37 AM
> To: NT Developers Interest List
> Subject: [ntdev] Multithreading and exceptions
>
> How can one pass exceptions across threads?
>
> Suppose you have a “black-box” function DoSomething(). The
> implementation is hidden from the caller. In other words, all the
> caller knows is that it’s a synchronous function that does what it’s
> supposed to do and then return. Further suppose that the
specification
> for DoSomething() indicates it may throw various exceptions. At some
> point in the future, say we decide to change the implementation of
> DoSomething(). The new implementation makes use of one or more worker
> threads to perform its given task. Any of these threads may throw an
> exception. The problem is how to pass this exception to the thread
that
> called DoSomething() in the first place, without losing any exception
> type information, so that all the existing calls to DoSomething()
> continue working as before, thus hiding any changes in implementation
> details.
>
> What appears to be needed is a (compiler-dependent, probably
low-level)
> method to get at the raw exception data at catch-time, then use
> synchronization to pass this raw data to the DoSomething() thread, and
> have the DoSomething() function re-throw the exception based on the
raw
> exception data in such a way that all exception information (including
> type) is preserved. Does anyone have any suggestions on how to do
this?
> Note, generic methodologies that work on arbitrary exception types
would
> be most useful. Methodologies that require a common exception base
> class are less useful, but could be discussed. Finally, coding
> catch/synchronize/re-throw traps for every “known” type of exception
is
> neither feasible nor desirable.
>
> Thanks,
>
> Chuck

You’re not talking about a kernel-mode driver, are you? C++ exception
handling doesn’t even compile in kernel-mode (without going through a
great deal of pain).

Last time I checked, C++ exception handling was implemented by the
Microsoft compiler using structured (Win32) exception handling
behind-the-scenes (see the API RaiseException). You can catch Win32
exceptions by using the __try/__except keywords, which are
well-documented in the Platform SDK. In your __except block, you can
call the GetExceptionInformation() to get all the information you need
to know about the exception.

Now I haven’t taken the time to dissect exactly how Microsoft’s compiler
represents information about the current C++ exception being thrown, nor
do I know that anyone else has. Assuming you do this, you would be able
to tell from the results of GetExceptionInformation() whether this is a
C++ exception being thrown and if so, where on the stack or in the heap
the object being thrown is stored.

Since this is all heavily compiler and platform dependent, and extremely
undocumented to boot, I would highly recommend against doing this. You
may just have to resign yourself to enumerating which exceptions you can
handle, and throwing away the rest.

  • Nick Ryan

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Chuck Batson
Sent: Monday, May 12, 2003 10:04 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Multithreading and exceptions

Mat,

Thank you for your input. Either I am misunderstanding what
you’re suggesting, or it’s not feasible. What do you mean by
“catch all exceptions in your thread”? If we catch all
exceptions like this:

try {
//…
}
catch (…) {
}

There’s no exception data available at all to keep aside, at
least as far as intrinsically available via standard C++.
(Though I suspect there may be a compiler-dependent way to do
this, with which I am hoping someone with prior experience
can help.) Perhaps you are suggesting something like this:

union {
ExceptionA a;
ExceptionB b;
} Exceptions;

try {
//…
}
catch (const ExceptionA & e) {
Exceptions.a = e;
}
catch (const ExceptionB & e) {
Exceptions.b = e;
}
// and so on…

This isn’t practical, as it’s error-prone (I have to remember
to add a specific handler for every new exception type). Or
more difficult, perhaps my function is using a third-party
library for which I have no knowledge (or no desire to know)
about exception types it uses internally.

Note, using a common exception base class doesn’t solve this
issue. Recall that the type of the exception object is
determined statically by the static type of the argument
given to the throw keyword.

Thanks,

Chuck

----- Original Message -----
From: “Mathieu Routhier”
> To: “NT Developers Interest List”
> Sent: Monday, May 12, 2003 7:49 PM
> Subject: [ntdev] RE: Multithreading and exceptions
>
>
> > My suggestion is that you catch all exceptions in your
> thread. If you
> catch
> > one, keep it aside, in a memory section accessible by the main
> function.
> > When the thread completes, your main function looks if any exception
> has
> > been caught by the thread and throws the exception again for the
> caller to
> > catch.
> >
> > It won’t be the thread who directly throws to the caller but the
> result will
> > be the same.
>
> >
> > Mat
> >
> >
> > -----Original Message-----
> > From: Chuck Batson [mailto:xxxxx@cbatson.com]
> > Sent: Monday, May 12, 2003 12:37 AM
> > To: NT Developers Interest List
> > Subject: [ntdev] Multithreading and exceptions
> >
> > How can one pass exceptions across threads?
> >
> > Suppose you have a “black-box” function DoSomething(). The
> > implementation is hidden from the caller. In other words, all the
> > caller knows is that it’s a synchronous function that does
> what it’s
> > supposed to do and then return. Further suppose that the
> specification
> > for DoSomething() indicates it may throw various
> exceptions. At some
> > point in the future, say we decide to change the implementation of
> > DoSomething(). The new implementation makes use of one or
> more worker
> > threads to perform its given task. Any of these threads
> may throw an
> > exception. The problem is how to pass this exception to the thread
> that
> > called DoSomething() in the first place, without losing any
> exception
> > type information, so that all the existing calls to DoSomething()
> > continue working as before, thus hiding any changes in
> implementation
> > details.
> >
> > What appears to be needed is a (compiler-dependent, probably
> low-level)
> > method to get at the raw exception data at catch-time, then use
> > synchronization to pass this raw data to the DoSomething()
> thread, and
> > have the DoSomething() function re-throw the exception based on the
> raw
> > exception data in such a way that all exception information
> (including
> > type) is preserved. Does anyone have any suggestions on how to do
> this?
> > Note, generic methodologies that work on arbitrary exception types
> would
> > be most useful. Methodologies that require a common exception base
> > class are less useful, but could be discussed. Finally, coding
> > catch/synchronize/re-throw traps for every “known” type of exception
> is
> > neither feasible nor desirable.
> >
> > Thanks,
> >
> > Chuck
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@nryan.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>

Well, yes, what I meant is to catch all throwable exceptions separately. I
hope you don’t have too many of them. It was more like this:

try{ //…
}
catch(ExceptionA &a)
{ }
catch(ExceptionB &b)
{ }
catch(ExceptionC &c)
{ }

As you pointed out, having a base class won’t do the trick. I agree this is
somehow heavy but AFAIK this is the only way you can carry an exception from
a thread to another.

And as Nicholas Ryan pointed out, C++ exceptions in kernel mode, well I
wouldn’t use them.

Mat

-----Original Message-----
From: Chuck Batson [mailto:xxxxx@cbatson.com]
Sent: Tuesday, May 13, 2003 1:04 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Multithreading and exceptions

Mat,

Thank you for your input. Either I am misunderstanding what you’re
suggesting, or it’s not feasible. What do you mean by “catch all
exceptions in your thread”? If we catch all exceptions like this:

try {
//…
}
catch (…) {
}

There’s no exception data available at all to keep aside, at least as
far as intrinsically available via standard C++. (Though I suspect
there may be a compiler-dependent way to do this, with which I am hoping
someone with prior experience can help.) Perhaps you are suggesting
something like this:

union {
ExceptionA a;
ExceptionB b;
} Exceptions;

try {
//…
}
catch (const ExceptionA & e) {
Exceptions.a = e;
}
catch (const ExceptionB & e) {
Exceptions.b = e;
}
// and so on…

This isn’t practical, as it’s error-prone (I have to remember to add a
specific handler for every new exception type). Or more difficult,
perhaps my function is using a third-party library for which I have no
knowledge (or no desire to know) about exception types it uses
internally.

Note, using a common exception base class doesn’t solve this issue.
Recall that the type of the exception object is determined statically
by the static type of the argument given to the throw keyword.

Thanks,

Chuck

----- Original Message -----
From: “Mathieu Routhier”
To: “NT Developers Interest List”
Sent: Monday, May 12, 2003 7:49 PM
Subject: [ntdev] RE: Multithreading and exceptions

> My suggestion is that you catch all exceptions in your thread. If you
catch
> one, keep it aside, in a memory section accessible by the main
function.
> When the thread completes, your main function looks if any exception
has
> been caught by the thread and throws the exception again for the
caller to
> catch.
>
> It won’t be the thread who directly throws to the caller but the
result will
> be the same.

>
> Mat
>
>
> -----Original Message-----
> From: Chuck Batson [mailto:xxxxx@cbatson.com]
> Sent: Monday, May 12, 2003 12:37 AM
> To: NT Developers Interest List
> Subject: [ntdev] Multithreading and exceptions
>
> How can one pass exceptions across threads?
>
> Suppose you have a “black-box” function DoSomething(). The
> implementation is hidden from the caller. In other words, all the
> caller knows is that it’s a synchronous function that does what it’s
> supposed to do and then return. Further suppose that the
specification
> for DoSomething() indicates it may throw various exceptions. At some
> point in the future, say we decide to change the implementation of
> DoSomething(). The new implementation makes use of one or more worker
> threads to perform its given task. Any of these threads may throw an
> exception. The problem is how to pass this exception to the thread
that
> called DoSomething() in the first place, without losing any exception
> type information, so that all the existing calls to DoSomething()
> continue working as before, thus hiding any changes in implementation
> details.
>
> What appears to be needed is a (compiler-dependent, probably
low-level)
> method to get at the raw exception data at catch-time, then use
> synchronization to pass this raw data to the DoSomething() thread, and
> have the DoSomething() function re-throw the exception based on the
raw
> exception data in such a way that all exception information (including
> type) is preserved. Does anyone have any suggestions on how to do
this?
> Note, generic methodologies that work on arbitrary exception types
would
> be most useful. Methodologies that require a common exception base
> class are less useful, but could be discussed. Finally, coding
> catch/synchronize/re-throw traps for every “known” type of exception
is
> neither feasible nor desirable.
>
> Thanks,
>
> Chuck


You are currently subscribed to ntdev as: xxxxx@guillemot.com
To unsubscribe send a blank email to xxxxx@lists.osr.com