From: Andrew Gaylard <ag@computer.org>
To: guile-devel@gnu.org, Andy Wingo <wingo@pobox.com>
Subject: Re: Core dump when throwing an exception from a resumed partial continuation
Date: Thu, 21 Mar 2013 15:53:08 +0200 [thread overview]
Message-ID: <514B10C4.2030800@computer.org> (raw)
In-Reply-To: <87wqt1w0io.fsf@pobox.com>
On 03/21/13 11:43, Andy Wingo wrote:
> On Fri 15 Mar 2013 22:01, Brent Pinkney <brp@4dst.com> writes:
>
>> When I resume the continuation in another thread, all works perfectly
>> UNLESS the continued execution throws and exception.
>> Then guile exits with a core dump.
>>
>> By contrast if I resume the continuation in the same thread and then
>> throw and exception all works as expected.
> I think I know what this is.
>
> So, a delimited continuation should capture that part of the dynamic
> environment made in its extent. (See Oleg Kiselyov and Chung-Chieh
> Shan's "Delimited Dynamic Binding" paper.) That is what Guile does, for
> fluids, prompts, and dynamic-wind blocks.
>
> Our implementation of exception handling uses a fluid,
> %exception-handler (boot-9.scm:86). However that fluid references a
> stack of exception handlers on the heap. There is the problem: an
> exception in a reinstated delimited continuation continuation will walk
> the captured exception handler stack from the heap, not from its own
> dynamic environment. Therefore it could abort to a continuation that is
> not present on the new thread.
>
> The solution is to have the exception handler find the next handler from
> the dynamic environment. This will need a new primitive to walk the
> dynamic stack, I think.
>
> I can't look at this atm as I broke my arm (!) and so typing is tough.
> For now as a workaround I suggest you put a catch #t in each of your
> delimited continuations. This way all throws will be handled by catches
> established by the continuation.
>
> Regards,
>
> Andy
Andy,
Thanks for giving this some thought -- sorry to hear about your arm!
This does shed some light on things. If I change this:
(throw 'oops) ; should not crash the vm
to this:
(catch #t
(λ ()
(throw 'oops)) ; should not crash the vm
(λ ()
(display "Success!")(newline))) ; never reached
the VM still cores; "Success" is never shown. However, you've probably
spotted my mistake: the handler should be (λ (key . args) ... ).
But this core shows up differently in the stack-trace in gdb:
#0 scm_error (key=0x1001854c0, subr=0x0, message=0xffffffff7e7ef518
"Wrong number of arguments to ~A", args=0x100db95b0, rest=0x4) at
error.c:62
... which is exactly the exception one would expect. Fixing the handler
thus:
(catch #t
(λ ()
(throw 'oops)) ; should not crash the vm
(λ (key . args)
(display "Success!")(newline))) ; works!
...solves the problem, and the VM doesn't core any more.
So it seems that although we *did* have a catch around our resumption,
there must have been some (different) error in its handler, which caused a
second exception, which caused the VM to crash.
Unfortunately, the test-case we made handles this second exception fine.
It'd be great to be able to distill this problem down to a pithy test-case.
(Our app is 4500 lines and still growing, so it's not really a candidate to
send to the list.)
The same problem happens (VM cores) if I do this:
(catch 'not-oops
(λ ()
(throw 'oops)) ; should not crash the vm
(λ (key . args)
(display "Success!")(newline))); never reached
So your answer to surround the resumption with a (catch #t ...) is a
good workaround. For our code, anyway.
(I'm now off to go read
http://www.cs.indiana.edu/~sabry/papers/delim-dyn-bind.pdf :)
--
Andrew
next prev parent reply other threads:[~2013-03-21 13:53 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-15 21:01 Core dump when throwing an exception from a resumed partial continuation Brent Pinkney
2013-03-15 21:30 ` Andy Wingo
2013-03-19 8:11 ` Andrew Gaylard
2013-03-21 9:43 ` Andy Wingo
2013-03-21 13:53 ` Andrew Gaylard [this message]
2013-03-21 15:34 ` Andy Wingo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=514B10C4.2030800@computer.org \
--to=ag@computer.org \
--cc=guile-devel@gnu.org \
--cc=wingo@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).