View mode: basic / threaded / horizontal-split · Log in · Help
August 08, 2012
thread exceptions
Hi,

using std.concurrency, is it possible to print an exception if a thread
throws (and the main thread is still running) ? It just terminates and
prints nothing. I tried to catch it and send as a message to the main
thread, but haven't succeeded so far.

-- 
mk
August 08, 2012
Re: thread exceptions
On 08/07/2012 06:25 PM, Martin Krejcirik wrote:
> Hi,
>
> using std.concurrency, is it possible to print an exception if a thread
> throws (and the main thread is still running) ? It just terminates and
> prints nothing. I tried to catch it and send as a message to the main
> thread, but haven't succeeded so far.

Here is an excerpt from a yet-unpublished change to my Concurrency chapter:

-----
The OwnerTerminated and LinkTerminated exceptions can be received as 
messages as well. The following code demonstrates this for the 
OwnerTerminated exception:



    bool isDone = false;

    while (!isDone) {
        receive(
            (int message)
            {
                writeln("Message: ", message);
            }
            ,

            (OwnerTerminated exc)
            {
                writeln("The owner has terminated; exiting.");
                isDone = true;
            }
        );
    }
-----

In order to receive LinkTerminated as a message, start the worker with 
spawnLinked() instead of spawn().

Ali

-- 
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
August 08, 2012
Re: thread exceptions
Hi Ali,

On 8.8.2012 5:36, Ali Çehreli wrote:
> The OwnerTerminated and LinkTerminated exceptions can be received as
> messages as well. The following code demonstrates this for the
> OwnerTerminated exception:

I meant how can I print the actual exception from the thread, including
it's error message, stack trace etc. Consider code like this, it just
ends without any error message:

import std.concurrency, std.stdio;

void main()
{
   writeln("main start");
   spawn(&child);
   for (int i=0; i<1_000_000_000; i++) {};
   writeln("main end");
}

void child()
{
   writeln("thread start");
   for (int i=0; i<100_000; i++) {};
   writeln("thread end");
   throw new Exception("exception from thread");
}

If I use spawnLinked, I know the thread ended, but still no original
exception. If I change main() to terminate before child(), it actually
waits until the child finishes and prints the exception, so there has to
be a way.

-- 
mk
August 08, 2012
Re: thread exceptions
I'll have to think about it. The current approach in std.concurrency is intended to be forwards-compatible with interprocess messaging, and serializing/deserializing an arbitrary exception would be tricky. See the exception thrown by receiveOnly as an example of how I addressed the issue there. 

On Aug 8, 2012, at 1:52 AM, Martin Krejcirik <mk-junk@i-line.cz> wrote:

> Hi Ali,
> 
> On 8.8.2012 5:36, Ali Çehreli wrote:
>> The OwnerTerminated and LinkTerminated exceptions can be received as
>> messages as well. The following code demonstrates this for the
>> OwnerTerminated exception:
> 
> I meant how can I print the actual exception from the thread, including
> it's error message, stack trace etc. Consider code like this, it just
> ends without any error message:
> 
> import std.concurrency, std.stdio;
> 
> void main()
> {
>    writeln("main start");
>    spawn(&child);
>    for (int i=0; i<1_000_000_000; i++) {};
>    writeln("main end");
> }
> 
> void child()
> {
>    writeln("thread start");
>    for (int i=0; i<100_000; i++) {};
>    writeln("thread end");
>    throw new Exception("exception from thread");
> }
> 
> If I use spawnLinked, I know the thread ended, but still no original
> exception. If I change main() to terminate before child(), it actually
> waits until the child finishes and prints the exception, so there has to
> be a way.
> 
> -- 
> mk
August 08, 2012
Re: thread exceptions
Oh, I should mention that if you use core.thread explicitly, any unhandled exception will be re-thrown in the context of whoever joins that thread. 

On Aug 8, 2012, at 1:52 AM, Martin Krejcirik <mk-junk@i-line.cz> wrote:

> Hi Ali,
> 
> On 8.8.2012 5:36, Ali Çehreli wrote:
>> The OwnerTerminated and LinkTerminated exceptions can be received as
>> messages as well. The following code demonstrates this for the
>> OwnerTerminated exception:
> 
> I meant how can I print the actual exception from the thread, including
> it's error message, stack trace etc. Consider code like this, it just
> ends without any error message:
> 
> import std.concurrency, std.stdio;
> 
> void main()
> {
>    writeln("main start");
>    spawn(&child);
>    for (int i=0; i<1_000_000_000; i++) {};
>    writeln("main end");
> }
> 
> void child()
> {
>    writeln("thread start");
>    for (int i=0; i<100_000; i++) {};
>    writeln("thread end");
>    throw new Exception("exception from thread");
> }
> 
> If I use spawnLinked, I know the thread ended, but still no original
> exception. If I change main() to terminate before child(), it actually
> waits until the child finishes and prints the exception, so there has to
> be a way.
> 
> -- 
> mk
August 08, 2012
Re: thread exceptions
On 08/08/2012 01:52 AM, Martin Krejcirik wrote:

> I meant how can I print the actual exception from the thread, including
> it's error message, stack trace etc.

Catching the exception explicitly and rethrowing would help a little:

// ... at the worker ...
                try {
                    // ...

                } catch (shared(Exception) exc) {
                    owner.send(exc);
                }},

// ... at the owner ...
        receive(
            // ...

            (shared(Exception) exc) {
                throw exc;
            });

Although, I've been bitten by the fact that AssertError is not an 
Exception, so exceptions thrown by assert checks will continue to 
surprise. :/

Ali
August 08, 2012
Re: thread exceptions
On 8.8.2012 18:15, Ali Çehreli wrote:
>                 } catch (shared(Exception) exc) {
>                     owner.send(exc);

Ahh shared, I've been trying immutable and such. Thanks a lot.

> 
> Although, I've been bitten by the fact that AssertError is not an
> Exception, so exceptions thrown by assert checks will continue to
> surprise. :/

Easy, just catch Throwable :-)

cya

-- 
mk
August 08, 2012
Re: thread exceptions
On 08/08/2012 12:44 PM, Martin Krejcirik wrote:

> Easy, just catch Throwable :-)

The problem is, Error (and Throwable) should not be caught. There is no 
guarantee of program behavior when an Error is thrown. At the least, an 
AssertError is by definition pointing at bad program state so no further 
action should make sense.

On the other hand, in my case catching by Throwable was the only way I 
could figure out why my concurrency program was getting stuck. So yeah, 
I guess the guideline should be don't catch Error in general. :)

Ali
Top | Discussion index | About this forum | D home