unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Evaluating (exit) in the debugger
@ 2008-11-20  0:53 Derek Peschel
  2008-11-21  0:09 ` Neil Jerram
  0 siblings, 1 reply; 6+ messages in thread
From: Derek Peschel @ 2008-11-20  0:53 UTC (permalink / raw)
  To: guile-devel

Hi a second time.  

I'm using Guile 1.8.4, a copy of (ice-9 debugging) from guile 1.8.5, and
guile-debugging 0.15.  It seems natural to type "e (exit)" at the debug>
prompt.  Unfortunately the quit exception isn't acted on.  Is there any
reasonable way to change the debugger?  Note the following:      

- The debugger must catch all exceptions created by evaluated code,
  not just a list of certain kinds, so it can isolate itself from the
  effects of the code.

- The debugger must use lazy-catch so it can save and show the details
  of the error.

- With regular catch, you can do:

    (catch #t
           ;; thunk which returns #f

           ;; handler which checks the exception type
           ;;   if 'quit, set status (known to the caller of the catch)
           ;;     and return #t
           ;;   otherwise, do the right nonlocal thing
    )

  and the caller of the catch can look at the Boolean and status.  The code
  in (ice-9 boot-9) does exactly this.  But that won't work with lazy-catch;
  if the handler returns the exception is rethrown.

- I'm not aware of any syntax for catching all exceptions excluding a
  list of types.  If that syntax existed, I could avoid invoking the lazy-
  catch handler.

The more _un_reasonable solutions I've thought of:

- Passing a continuation (which exits when invoked) to the handler.  The
  documentation hints that handlers may invoke any continuation they can
  get.

- Special-case code that lets the rethrow or series of rethrows happen,
  avoids printing any error messages, and eventually exits.  The original
  quit exception quickly becomes an "unhandled quit exception" exception
  so the code must deal with that too.

Writing a debugger command that calls (exit) was much easier.  But that
won't solve this problem AFAIK.

Thanks,

-- Derek




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Evaluating (exit) in the debugger
  2008-11-20  0:53 Evaluating (exit) in the debugger Derek Peschel
@ 2008-11-21  0:09 ` Neil Jerram
  2008-11-21  0:48   ` Derek Peschel
  0 siblings, 1 reply; 6+ messages in thread
From: Neil Jerram @ 2008-11-21  0:09 UTC (permalink / raw)
  To: Derek Peschel; +Cc: guile-devel

2008/11/20 Derek Peschel <dpeschel@eskimo.com>:
> Hi a second time.
>
> I'm using Guile 1.8.4, a copy of (ice-9 debugging) from guile 1.8.5, and
> guile-debugging 0.15.  It seems natural to type "e (exit)" at the debug>
> prompt.  Unfortunately the quit exception isn't acted on.  Is there any
> reasonable way to change the debugger?  Note the following:

I'm afraid I don't understand.  What do you want to happen when you
type "e (exit)"?

> - The debugger must catch all exceptions created by evaluated code,
>  not just a list of certain kinds, so it can isolate itself from the
>  effects of the code.

OK.

> - The debugger must use lazy-catch so it can save and show the details
>  of the error.

Agree that it does at the moment, but I'm not sure this is strictly
needed.  The debugger "e" command is mostly intended for variable
values and simple expressions - so normally there could not be a
backtrace of much interest.

> - With regular catch, you can do:
>
>    (catch #t
>           ;; thunk which returns #f
>
>           ;; handler which checks the exception type
>           ;;   if 'quit, set status (known to the caller of the catch)
>           ;;     and return #t
>           ;;   otherwise, do the right nonlocal thing
>    )
>
>  and the caller of the catch can look at the Boolean and status.  The code
>  in (ice-9 boot-9) does exactly this.  But that won't work with lazy-catch;
>  if the handler returns the exception is rethrown.

The lazy-catch handler can also set a variable (global or lexical), can't it?

> - I'm not aware of any syntax for catching all exceptions excluding a
>  list of types.  If that syntax existed, I could avoid invoking the lazy-
>  catch handler.

You're correct that this doesn't exist.

Just had a quick look at eval-handler in (ice-9 debugger commands)...
did you notice that it ends with (throw 'continue) - and hence that
the default lazy-catch rethrowing isn't actually happening?  Is it
possible that (throw 'continue) is the cause of the problem?

Regards,
     Neil




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Evaluating (exit) in the debugger
  2008-11-21  0:09 ` Neil Jerram
@ 2008-11-21  0:48   ` Derek Peschel
  2008-11-21  9:58     ` Derek Peschel
  2008-11-23 22:24     ` Neil Jerram
  0 siblings, 2 replies; 6+ messages in thread
From: Derek Peschel @ 2008-11-21  0:48 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-devel

On Fri, Nov 21, 2008 at 12:09:18AM +0000, Neil Jerram wrote:
> I'm afraid I don't understand.  What do you want to happen when you
> type "e (exit)"?

I want Guile to exit, just as normally happens when you call (exit).
Also return codes should be supported in the debugger as in the REPL,
e.g. "e (exit 5)" should return 5 to the calling UNIX process.

The principle is that the debugger should not interfere with the
actions of code it's debugging, which to me includes "e"'d code.

> Agree that it does at the moment, but I'm not sure this is strictly
> needed.  The debugger "e" command is mostly intended for variable
> values and simple expressions - so normally there could not be a
> backtrace of much interest.

Obviously I'm abusing it then. :)  Seriously, if you did evaluate a
complex expression, or were confused about environment lookup (since the
expression is evaluated in the context of the current stack frame as
chosen by the up/down/frame commands, right?) the backtrace would be
useful.

This gets into issues like recursive debugging, which is a feature I
confess I haven't used much yet, however nice it may be in theory.

> The lazy-catch handler can also set a variable (global or lexical), can't it?

It certainly should be able to.  That might lead to a workable solution.
Suppressing error messages is another necessary part of the solution
(at least IMO).

> Just had a quick look at eval-handler in (ice-9 debugger commands)...
> did you notice that it ends with (throw 'continue) - and hence that
> the default lazy-catch rethrowing isn't actually happening?  Is it
> possible that (throw 'continue) is the cause of the problem?

I will have to look at the code and my experiments later, when I've
finished the things I'm supposed to be doing.  However I know for a fact
that at least one level of handler gets the "unhandled quit exception"
I described, with nothing related to continue that I've seen.

And I need to work out how many levels of handler are running when the
evaluation happens.  I wonder if Guile can tell me that?

-- Derek




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Evaluating (exit) in the debugger
  2008-11-21  0:48   ` Derek Peschel
@ 2008-11-21  9:58     ` Derek Peschel
  2008-11-21 21:14       ` Derek Peschel
  2008-11-23 22:24     ` Neil Jerram
  1 sibling, 1 reply; 6+ messages in thread
From: Derek Peschel @ 2008-11-21  9:58 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-devel

On Thu, Nov 20, 2008 at 04:48:32PM -0800, Derek Peschel wrote:
> On Fri, Nov 21, 2008 at 12:09:18AM +0000, Neil Jerram wrote:

> > Just had a quick look at eval-handler in (ice-9 debugger commands)...
> > did you notice that it ends with (throw 'continue) - and hence that
> > the default lazy-catch rethrowing isn't actually happening?  Is it
> > possible that (throw 'continue) is the cause of the problem?

> finished the things I'm supposed to be doing.  However I know for a fact
> that at least one level of handler gets the "unhandled quit exception"
> I described, with nothing related to continue that I've seen.

You're right, eval-handler does throw 'continue as it exits.  I hadn't
taken that complication into account, or defined the problem totally clearly.
Well, I did already know that the problem is not the rethrow behavior per
se.  The problem is how to invisibly get the quit exception to a handler
that can deal with it by quitting, while allowing the debugger to catch
every other exception that can possibly be thrown by the debuggee and
ideally to give a backtrace.

Before eval-handler throws 'continue, it uses key and args to print the
backtrace.  I did two tests to demonstrate the backtrace-printing part of
eval-handler.  In test 1, I put in (display)s of key and args.  That's how
I know eval-handler gets an "unhandled quit exception" exception.

In test 2, I also added a (lazy-catch 'quit) inside the (lazy-catch #t) in
(evaluate), really just to see what would happen.  And that inner handler
gets a regular quit exception.  Then it rethrows it, because I couldn't
think of anything better to do.  And eval-handler gets the same exception
as in test 1.

I can send patches or terminal transcripts for both tests.

Clearly I'll next have to see what eval-handler can do besides throwing
'continue.  But even before that throw happens, things are uglier than I
wanted because eval-handler doesn't get a quit exception.  My solution of
special-casing the "unhandled quit exception" exception might work, it's
just not elegant.

I also have to figure out why eval-handler is not getting an ordinary quit
exception in test 1.

-- Derek




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Evaluating (exit) in the debugger
  2008-11-21  9:58     ` Derek Peschel
@ 2008-11-21 21:14       ` Derek Peschel
  0 siblings, 0 replies; 6+ messages in thread
From: Derek Peschel @ 2008-11-21 21:14 UTC (permalink / raw)
  To: Neil Jerram; +Cc: guile-devel

On Fri, Nov 21, 2008 at 01:58:51AM -0800, Derek Peschel wrote:
> I also have to figure out why eval-handler is not getting an ordinary quit
> exception in test 1.

Sorry if this series of follow-ups is bad style -- I'm thinking this out
in public.  Maybe the documentation will be useful in some way.

My question was a useful clue that something was wrong.  Intuitively,
if the code being evaluated throws a quit exception, you'd expect eval-
handler to get the quit exception.  It does, _at the beginning_ before
its internal catch runs, whereas test 1 was looking inside the catch.

The correct change to eval-handler is quite minor:  just rethrow any quit
exceptins it gets, and do the rethrow before any of the error-anlysis code
takes over.  Then debug-handler gets the quit.  My last patch dealt with
that part of the sequence of events.  So the problem is fully solved and
I'll send out a new patch soon.

And thanks for your help.  The comment about 'continue got me to look more
closely at eval-handler.

-- Derek




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Evaluating (exit) in the debugger
  2008-11-21  0:48   ` Derek Peschel
  2008-11-21  9:58     ` Derek Peschel
@ 2008-11-23 22:24     ` Neil Jerram
  1 sibling, 0 replies; 6+ messages in thread
From: Neil Jerram @ 2008-11-23 22:24 UTC (permalink / raw)
  To: Derek Peschel; +Cc: guile-devel

Hi Derek,

I'm sorry that my followups to you are so slow, and hope that this
hasn't resulted in unnecessary work...

2008/11/21 Derek Peschel <dpeschel@eskimo.com>:
> On Fri, Nov 21, 2008 at 12:09:18AM +0000, Neil Jerram wrote:
>> I'm afraid I don't understand.  What do you want to happen when you
>> type "e (exit)"?
>
> I want Guile to exit, just as normally happens when you call (exit).
>
> Also return codes should be supported in the debugger as in the REPL,
> e.g. "e (exit 5)" should return 5 to the calling UNIX process.

(primitive-exit RETURN-CODE) will do both of those.

I'm afraid I can't remember why (exit ...) in Guile is actually just
(throw 'quit ...), but it's been that way for a long time now, so
might be difficult to change.

> The principle is that the debugger should not interfere with the
> actions of code it's debugging, which to me includes "e"'d code.

Interesting.  But on the other hand, we don't want unintended errors
in "e"'d code to propagate back into the actual program!  Is there any
nice general way of distinguishing between intentional exceptions
(which should not be caught by eval-handler) and unintended ones
(which should be)?

> And I need to work out how many levels of handler are running when the
> evaluation happens.  I wonder if Guile can tell me that?

It's possible in principle, but I don't believe we currently have a
primitive to expose this (i.e. the value of scm_i_dynwinds ()) to the
Scheme level.  If we did expose this, I think we should do so in a way
that still allows us to change the internal representation of the wind
list, without any back-compatibility problems.

Regards,
       Neil




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-11-23 22:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-20  0:53 Evaluating (exit) in the debugger Derek Peschel
2008-11-21  0:09 ` Neil Jerram
2008-11-21  0:48   ` Derek Peschel
2008-11-21  9:58     ` Derek Peschel
2008-11-21 21:14       ` Derek Peschel
2008-11-23 22:24     ` Neil Jerram

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).