guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Stack unwinding for C code


From: Marius Vollmer
Subject: Re: Stack unwinding for C code
Date: Sat, 27 Dec 2003 18:37:37 +0100
User-agent: Gnus/5.1002 (Gnus v5.10.2) Emacs/21.3 (gnu/linux)

Neil Jerram <address@hidden> writes:

> This looks nice - I'll take your word for it that we need this, and
> the API looks clean as you say.

Don't you think we need it?  Maybe I'm overlooking some obvious
alternative that would work just as well...

The example shows what I want to achieve: during a sequence of
conversions from SCM objects to C data structures, we will frequently
have the case that an earlier conversion has allocated some resources
that need to be freed later on.  However a later conversion might want
to throw an error and the cleanup needs to happen then.

First, we (on #guile) tried some approaches that would prevent the
throwing of errors.  For example, we could separate type checking and
conversion, ala

    scm_check_string (s1);
    scm_check_string (s2);

    /* Now the conversion functions are guaranteed not to throw. */

    c_s1 = scm_to_string (s1);
    c_s2 = scm_to_string (s2);

But this leads to problems in a multi-threaded program: when you have
composite SCM types such as a list, you must make absolutely sure that
the object doesn't change from checking to conversion.  You need to
stop all other guile threads during the conversion sequence, which is
at least as costly as having this unwind machinery, I think.

> A few comments and typo corrections,
> though ...

Thanks, hopefully the poor form didn't distract from the content...

>     Marius> These frames also inhibit continuations (as explained
>     Marius> below). [...]
>
> In API terms, this feels to me like the same area as issues like
> SCM_DEFER_INTS, control of signal delivery, inhibiting thread
> switching, etc.  I realize that these are quite different mechanisms
> really, but it would be lovely if the API that you are proposing here
> could also cope with and document all those other areas once and for
> all.

Hmm.  I had to change the continuation stuff already: just disallowing
all construction and invocation of continuations is too restricitve:
continuations that are only used below the frame cause no harm.  Only
continuations that cause the frame to be rewound need to be prevented.
This is too restrictive as well, in a sense, since continuations that
are only used in a suspend/resume way (for threads or coroutines, say)
are OK as well.  But the general continuations are too general to know
how they are going to be used, so throwing an error when such a frame
is rewound is all we can do.

>     Marius>     scm_begin_frame ("foo");
>     Marius>       {
>
> Is this block necessary? - it looks a little ugly to me.

No, scm_begin_frame is a normal function, nothing special about it.

>     Marius>   Starts a new frame and makes it the 'current' one.
>     Marius>   The frame will be 'non-continueable', see below.
>
> typo - "continuable"

Yeah, thanks. :-) I knew it was wrong, but I couldn't figure out what
was right.  Ispell doesn't know about "continuable"...

> Also differs - perhaps confusingly - from my use of "continuable" for
> a stack in (ice-9 debugger).  (My use of "continuable" is to describe
> a stack at a breakpoint, where execution can continue, as opposed to
> the-last-stack after an error, where execution cannot continue.

Yes, the term isn't very good for what I use it for.

> Perhaps "continuation-proof" or "continuation-protected"?

What about "rewindable"?

>     Marius>   The given LABEL will appear in backtraces and error messages.
>
> How (out of interest)?

Don't know yet! :-) Also, I'm no longer sure that it is a good idea to
combine the backtrace stuff with the frame stuff.  I think I'll remove
the label.

(I think that ultimately, we should have a different way of reporting
error from C code: we should not include the subr name in the call to
the error reporting function but rather rely on a more general
mechanism for providing a backtrace for C code.  I found it attractive
to just combine it with the frame stuff, but it probably is too
early...)

>
>     Marius>   The frame is ended either implicitely when a non-local
>     Marius>   exit happens, or explicitely with scm_end_frame.
>
> typos - "implicitly", "explicitly"

Oops, I do that all the time...

>     Marius>   Arranges for FUNC to be called with DATA as its
>     Marius>   arguments when the current frame ends implicitely.
>     Marius>   When EXPLICITElY is non-zero, FUNC is also called when
>     Marius>   the frame ends explicitely.
>
> "If" sounds better than "When" here, I'd say.

Ok.

>     Marius> - C Function: void scm_c_define_proc (const char *name,
>     Marius>                                       int req, int opt,
>     Marius>                                       int restp,
>     Marius>                                       SCM (*proc) (...))
>
> This is not a good name: it is not helpful to suggest that "proc" =
> "framed gsubr".  How about scm_c_define_framed_gsubr ?

Hmm.  That is so technical.  I wanted to imply that scm_c_define_proc
is the usual way to export C procedures to Scheme.  Even if you don't
explicitly ;) ask for a frame, you still get it since it is good for
you....

But, yeah, I'm removing this together with the label stuff.

>     Marius> Also, the frames stored by the debugging evaluator could
>     Marius> be combined with this.
>
> Interesting.  Do you propose to do this as part of your initial work?

Well, no.  They are too different after all.  It is very nice how
efficient the debugging frames currently are, and I wouldn't want to
destroy that.

-- 
GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3  331E FAF8 226A D5D4 E405




reply via email to

[Prev in Thread] Current Thread [Next in Thread]