digitalmars.D - Coroutines and exceptions
- Daniel Keep (48/48) Apr 28 2006 Hi.
- Daniel Keep (9/66) Apr 28 2006 Oops, forgot I was playing around with the gdc-compiled binary, not the
- Lars Ivar Igesund (34/77) Apr 29 2006 I have been working on getting Mikola Lysenko's StackThread working on
- mclysenk mtu.edu (12/89) May 01 2006 That is because on windows you need to save the stack top & bottom when ...
- Daniel Keep (7/110) May 02 2006 Cool; thanks for that. Guess I'll have some reading to do when I get
Hi. I've been playing around with an implementation of coroutines in D the last day or two, and I've got it to the point where it works pretty well under gdc, and under dmd with a few bugs to track down. But I've hit a brick will with exceptions. See, I was kinda hoping that D found exception handlers by going back up the stack frames... although after pouring over the disassembly in gdb, it looks like D registers the exception handlers as it meets them. The problem with this is that the coroutine library allows you to jump from one part of the code to another, which ends up screwing up the order of exception handlers. For example (simplified, mind you): void coro_a() { try { co_call(main); // Jump back into main just after co_call } except( Exception e ) { writefln("Exception in coro_a: %s", e.toString()); } } void main() { try { co_call(coro_a); // Jump into coro_a throw new Exception("Oh noes!"); } catch( Exception e ) { writefln("Exception in main: %s", e.toString()); } } If you run that, you end up getting "Exception in coro_a: Oh noes!" instead of "Exception in main: Oh noes!" as you would expect. This is pretty much a show-stopper for coroutines; if exceptions don't work with them, then the library won't be much good. SO, the question is: assuming that you register exception handlers on to some kind of internal stack of addresses to jump to in the event of an exception, is there any possibility of being able to, say... swap out that stack for a different one at runtime? The CPU doesn't seem to mind when I do that to the program stack :P Please and thankyou, -- Daniel Keep -- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Apr 28 2006
Oops, forgot I was playing around with the gdc-compiled binary, not the dmd one :P Had a poke around a dmd-generated executable in windbg, but couldn't actually find anything relating to exception handlers. In any case, the question still stands :) -- Daniel Daniel Keep wrote:Hi. I've been playing around with an implementation of coroutines in D the last day or two, and I've got it to the point where it works pretty well under gdc, and under dmd with a few bugs to track down. But I've hit a brick will with exceptions. See, I was kinda hoping that D found exception handlers by going back up the stack frames... although after pouring over the disassembly in gdb, it looks like D registers the exception handlers as it meets them. The problem with this is that the coroutine library allows you to jump from one part of the code to another, which ends up screwing up the order of exception handlers. For example (simplified, mind you): void coro_a() { try { co_call(main); // Jump back into main just after co_call } except( Exception e ) { writefln("Exception in coro_a: %s", e.toString()); } } void main() { try { co_call(coro_a); // Jump into coro_a throw new Exception("Oh noes!"); } catch( Exception e ) { writefln("Exception in main: %s", e.toString()); } } If you run that, you end up getting "Exception in coro_a: Oh noes!" instead of "Exception in main: Oh noes!" as you would expect. This is pretty much a show-stopper for coroutines; if exceptions don't work with them, then the library won't be much good. SO, the question is: assuming that you register exception handlers on to some kind of internal stack of addresses to jump to in the event of an exception, is there any possibility of being able to, say... swap out that stack for a different one at runtime? The CPU doesn't seem to mind when I do that to the program stack :P Please and thankyou, -- Daniel Keep-- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
Apr 28 2006
Daniel Keep wrote:Hi. I've been playing around with an implementation of coroutines in D the last day or two, and I've got it to the point where it works pretty well under gdc, and under dmd with a few bugs to track down. But I've hit a brick will with exceptions. See, I was kinda hoping that D found exception handlers by going back up the stack frames... although after pouring over the disassembly in gdb, it looks like D registers the exception handlers as it meets them. The problem with this is that the coroutine library allows you to jump from one part of the code to another, which ends up screwing up the order of exception handlers. For example (simplified, mind you): void coro_a() { try { co_call(main); // Jump back into main just after co_call } except( Exception e ) { writefln("Exception in coro_a: %s", e.toString()); } } void main() { try { co_call(coro_a); // Jump into coro_a throw new Exception("Oh noes!"); } catch( Exception e ) { writefln("Exception in main: %s", e.toString()); } } If you run that, you end up getting "Exception in coro_a: Oh noes!" instead of "Exception in main: Oh noes!" as you would expect.I have been working on getting Mikola Lysenko's StackThread working on Linux, and I just tested the exception handling (which I did not have to do anything with, it just worked the way he had implemented it. Unless this way is not what you want, and your couroutines might not be altogether the same thing as this StackThread (I tried to send you a mail, but don't know if it will reach you...). Anyway, the test code goes like this (in the unittest): try { void exceptions() { writefln("Testing exception handling..."); throw new Exception(std.string.format("Test exception, line %s", __LINE__)); StackThread.yield(); } StackThread t = new StackThread(&exceptions); t.resume(); StackThread.run(); assert(false); } catch(Exception e) { writefln(e); } And the result is this: Testing exception handling... Test exception, line 412 The assert is not triggered. I do agree that your result seems somewhat strange, though... -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
Apr 29 2006
In article <e2vh64$2vhe$1 digitaldaemon.com>, Lars Ivar Igesund says...Daniel Keep wrote:That is because on windows you need to save the stack top & bottom when you change contexts. They are stored at FS[4] and FS[8]. Also it would be a good idea to relink the SEH chain when you create a new coroutine, so the top level is tied to the SEH that originally called the coroutine. As far as I can tell, this behaviour is not very well documented, but for more info on structured exception handling, you can check out http://www.microsoft.com/msj/0197/exception/exception.aspx . I'm currently working on extending the StackThread system to support priority based scheduling and Linux. At the moment, I have a specification drawn up, along with a basic architecture/implementation. -Mikola LysenkoHi. I've been playing around with an implementation of coroutines in D the last day or two, and I've got it to the point where it works pretty well under gdc, and under dmd with a few bugs to track down. But I've hit a brick will with exceptions. See, I was kinda hoping that D found exception handlers by going back up the stack frames... although after pouring over the disassembly in gdb, it looks like D registers the exception handlers as it meets them. The problem with this is that the coroutine library allows you to jump from one part of the code to another, which ends up screwing up the order of exception handlers. For example (simplified, mind you): void coro_a() { try { co_call(main); // Jump back into main just after co_call } except( Exception e ) { writefln("Exception in coro_a: %s", e.toString()); } } void main() { try { co_call(coro_a); // Jump into coro_a throw new Exception("Oh noes!"); } catch( Exception e ) { writefln("Exception in main: %s", e.toString()); } } If you run that, you end up getting "Exception in coro_a: Oh noes!" instead of "Exception in main: Oh noes!" as you would expect.I have been working on getting Mikola Lysenko's StackThread working on Linux, and I just tested the exception handling (which I did not have to do anything with, it just worked the way he had implemented it. Unless this way is not what you want, and your couroutines might not be altogether the same thing as this StackThread (I tried to send you a mail, but don't know if it will reach you...). Anyway, the test code goes like this (in the unittest): try { void exceptions() { writefln("Testing exception handling..."); throw new Exception(std.string.format("Test exception, line %s", __LINE__)); StackThread.yield(); } StackThread t = new StackThread(&exceptions); t.resume(); StackThread.run(); assert(false); } catch(Exception e) { writefln(e); } And the result is this: Testing exception handling... Test exception, line 412 The assert is not triggered. I do agree that your result seems somewhat strange, though... -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
May 01 2006
Cool; thanks for that. Guess I'll have some reading to do when I get home :) -- Daniel mclysenk mtu.edu wrote:In article <e2vh64$2vhe$1 digitaldaemon.com>, Lars Ivar Igesund says...-- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/Daniel Keep wrote:That is because on windows you need to save the stack top & bottom when you change contexts. They are stored at FS[4] and FS[8]. Also it would be a good idea to relink the SEH chain when you create a new coroutine, so the top level is tied to the SEH that originally called the coroutine. As far as I can tell, this behaviour is not very well documented, but for more info on structured exception handling, you can check out http://www.microsoft.com/msj/0197/exception/exception.aspx . I'm currently working on extending the StackThread system to support priority based scheduling and Linux. At the moment, I have a specification drawn up, along with a basic architecture/implementation. -Mikola LysenkoHi. I've been playing around with an implementation of coroutines in D the last day or two, and I've got it to the point where it works pretty well under gdc, and under dmd with a few bugs to track down. But I've hit a brick will with exceptions. See, I was kinda hoping that D found exception handlers by going back up the stack frames... although after pouring over the disassembly in gdb, it looks like D registers the exception handlers as it meets them. The problem with this is that the coroutine library allows you to jump from one part of the code to another, which ends up screwing up the order of exception handlers. For example (simplified, mind you): void coro_a() { try { co_call(main); // Jump back into main just after co_call } except( Exception e ) { writefln("Exception in coro_a: %s", e.toString()); } } void main() { try { co_call(coro_a); // Jump into coro_a throw new Exception("Oh noes!"); } catch( Exception e ) { writefln("Exception in main: %s", e.toString()); } } If you run that, you end up getting "Exception in coro_a: Oh noes!" instead of "Exception in main: Oh noes!" as you would expect.I have been working on getting Mikola Lysenko's StackThread working on Linux, and I just tested the exception handling (which I did not have to do anything with, it just worked the way he had implemented it. Unless this way is not what you want, and your couroutines might not be altogether the same thing as this StackThread (I tried to send you a mail, but don't know if it will reach you...). Anyway, the test code goes like this (in the unittest): try { void exceptions() { writefln("Testing exception handling..."); throw new Exception(std.string.format("Test exception, line %s", __LINE__)); StackThread.yield(); } StackThread t = new StackThread(&exceptions); t.resume(); StackThread.run(); assert(false); } catch(Exception e) { writefln(e); } And the result is this: Testing exception handling... Test exception, line 412 The assert is not triggered. I do agree that your result seems somewhat strange, though... -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
May 02 2006