unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* reporting 'system-error informatively
@ 2002-10-19 21:18 Paul Jarc
  2002-10-20 21:38 ` Marius Vollmer
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Jarc @ 2002-10-19 21:18 UTC (permalink / raw)


If I catch 'system-error and display an error message, I'd like to
include the arguments of the procedure that failed along with the
procedure name and errno string.  Is there a way to get the arguments
programmatically, other than by parsing the output of (backtrace)?


paul


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

* Re: reporting 'system-error informatively
  2002-10-19 21:18 reporting 'system-error informatively Paul Jarc
@ 2002-10-20 21:38 ` Marius Vollmer
  2002-10-20 23:02   ` Daniel Skarda
  2002-10-21  6:13   ` Paul Jarc
  0 siblings, 2 replies; 8+ messages in thread
From: Marius Vollmer @ 2002-10-20 21:38 UTC (permalink / raw)


prj@po.cwru.edu (Paul Jarc) writes:

> If I catch 'system-error and display an error message, I'd like to
> include the arguments of the procedure that failed along with the
> procedure name and errno string.  Is there a way to get the arguments
> programmatically, other than by parsing the output of (backtrace)?

The arguments are passed among the arguments received by the handler.
You can do something like

    (define (call-with-error-catching thunk)
      (let ((the-last-stack #f)
            (stack-saved? #f))

        (define (handle-error key args)
          (let ((text (call-with-output-string
                       (lambda (cep)
                         (if the-last-stack
                             (display-backtrace the-last-stack cep)
                             (display "no backtrace available.\n" cep))
                         (apply display-error the-last-stack cep args)))))
            ;;; you probably need to do something else with the text.
            (gtk-show-error text)
            #f))

        (define (save-stack)
          (cond (stack-saved?)
                ((not (memq 'debug (debug-options-interface)))
                 (set! the-last-stack #f)
                 (set! stack-saved? #t))
                (else
                 (set! the-last-stack (make-stack #t lazy-dispatch 4))
                 (set! stack-saved? #t))))

        (define (lazy-dispatch key . args)
          (save-stack)
          (apply throw key args))

        (start-stack #t
                     (catch #t
                            (lambda ()
                              (lazy-catch #t
                                          thunk
                                          lazy-dispatch))
                            (lambda (key . args)
                              (if (= (length args) 4)
                                  (handle-error key args)
                                  (apply throw key args)))))))

which is probably way too complicated.  This is a weak spot of Guile,
I'm afraid.

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


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

* Re: reporting 'system-error informatively
  2002-10-20 21:38 ` Marius Vollmer
@ 2002-10-20 23:02   ` Daniel Skarda
  2002-10-21 14:46     ` Marius Vollmer
  2002-10-21  6:13   ` Paul Jarc
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Skarda @ 2002-10-20 23:02 UTC (permalink / raw)
  Cc: guile-user


Marius Vollmer <mvo@zagadka.ping.de> writes:
> prj@po.cwru.edu (Paul Jarc) writes:
> > If I catch 'system-error and display an error message, I'd like to
> > include the arguments of the procedure that failed along with the
> > procedure name and errno string.  Is there a way to get the arguments
> > programmatically, other than by parsing the output of (backtrace)?
> 
> The arguments are passed among the arguments received by the handler.
> You can do something like

[call-with-error-catching code]

> which is probably way too complicated.  This is a weak spot of Guile,
> I'm afraid.

  I noticed that there is similar code in module (ice-9 stack-catch). What is
the difference between your code and stack-catch module? 

0.


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

* Re: reporting 'system-error informatively
  2002-10-20 21:38 ` Marius Vollmer
  2002-10-20 23:02   ` Daniel Skarda
@ 2002-10-21  6:13   ` Paul Jarc
  2002-10-21 14:45     ` Marius Vollmer
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Jarc @ 2002-10-21  6:13 UTC (permalink / raw)


Marius Vollmer <mvo@zagadka.ping.de> wrote:
>         (define (handle-error key args)
>           (let ((text (call-with-output-string
>                        (lambda (cep)
>                          (if the-last-stack
>                              (display-backtrace the-last-stack cep)
>                              (display "no backtrace available.\n" cep))

It seems this would still require parsing.  Is there any way to get
the arguments themselves, as plain Scheme values instead of text?
frame-arguments sounds promising; I'm just not sure how to use it.  I
tried this:
(make-stack (call-with-current-continuation identity))
But got a segfault.  Dunno if that was supposed to do anything useful;
I was just messing around.


paul


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

* Re: reporting 'system-error informatively
  2002-10-21  6:13   ` Paul Jarc
@ 2002-10-21 14:45     ` Marius Vollmer
  2002-10-21 18:36       ` Paul Jarc
  2002-10-21 18:55       ` Neil Jerram
  0 siblings, 2 replies; 8+ messages in thread
From: Marius Vollmer @ 2002-10-21 14:45 UTC (permalink / raw)


prj@po.cwru.edu (Paul Jarc) writes:

> It seems this would still require parsing.

Yes, I wasn't reading your problem carefully enough.  I thought you
meant the arguments of the error, not the arguments of the function
that signalled the error.

> Is there any way to get the arguments themselves, as plain Scheme
> values instead of text?

Probably.  Messing around with the 'stack' data structure is probably
the right thing.  Sorry, I can't say more.  (But others might.)

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


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

* Re: reporting 'system-error informatively
  2002-10-20 23:02   ` Daniel Skarda
@ 2002-10-21 14:46     ` Marius Vollmer
  0 siblings, 0 replies; 8+ messages in thread
From: Marius Vollmer @ 2002-10-21 14:46 UTC (permalink / raw)
  Cc: guile-user

Daniel Skarda <0rfelyus@ucw.cz> writes:

>   I noticed that there is similar code in module (ice-9 stack-catch). What is
> the difference between your code and stack-catch module? 

Uhh, I can't say.  I'm afraid you have to dive in yourself...

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


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

* Re: reporting 'system-error informatively
  2002-10-21 14:45     ` Marius Vollmer
@ 2002-10-21 18:36       ` Paul Jarc
  2002-10-21 18:55       ` Neil Jerram
  1 sibling, 0 replies; 8+ messages in thread
From: Paul Jarc @ 2002-10-21 18:36 UTC (permalink / raw)


Thanks for the hints.  The following seems to do what I want; comments
welcome.

(debug-enable 'debug)

(define display-system-error
  (let ()
    (define (handler . args)
      (let ((proc-args
             (if (memq 'debug (debug-options-interface))
               (frame-arguments (stack-ref (make-stack #t handler) 0))
               '(unknown-arguments))))
        (display (cadr args))
        (write proc-args)
        (display ": ")
        (display (strerror (system-error-errno args)))
        (newline)
        (exit 100)))
    (lambda (thunk)
      (lazy-catch 'system-error
                  thunk
                  handler))))

(display-system-error
 (lambda ()
   (let ((path "doesnotexist"))
     (readlink path))))


paul


_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

* Re: reporting 'system-error informatively
  2002-10-21 14:45     ` Marius Vollmer
  2002-10-21 18:36       ` Paul Jarc
@ 2002-10-21 18:55       ` Neil Jerram
  1 sibling, 0 replies; 8+ messages in thread
From: Neil Jerram @ 2002-10-21 18:55 UTC (permalink / raw)
  Cc: guile-user

>>>>> "Marius" == Marius Vollmer <mvo@zagadka.ping.de> writes:

    >> Is there any way to get the arguments themselves, as plain Scheme
    >> values instead of text?

    Marius> Probably.  Messing around with the 'stack' data structure is probably
    Marius> the right thing.  Sorry, I can't say more.  (But others might.)

Assuming that `the-last-stack' has caught the error that you want to
look at, you can get the stack object by

(define s (fluid-ref the-last-stack))

and then the innermost stack frame by

(define f (stack-ref s 0))

Now, a frame can be either an application or an evaluation, and you'll
often find that the innermost frame is an application, with the one
just higher being an evaluation, e.g.

innermost: [string-length 4]
1 outer: (string-length 4)

(frame-procedure? f) tells you whether the frame is an application.
If it is, (frame-procedure f) returns the procedure and
(frame-arguments f) returns the already evaluated args.  If it isn't,
(frame-source f) -- i.e. the frame is an evaluation -- returns the
expression that was being evaluated, which is all you can get.

So (untested as usual) ...

(define (last-error->proc+args)
  (let* ((stack (fluid-ref the-last-stack))
         (stacklen (stack-length stack)))
    (let loop ((index 0))
      (if (< index stacklen)
          (let ((frame (stack-ref stack index)))
            (if (frame-procedure? frame)
                (values (frame-procedure frame)
                        (frame-arguments frame))
                (loop (+ index 1))))
          #f))))

If `the-last-stack' hasn't captured the error that you want, you can
capture it for yourself using `lazy-catch' and `make-stack':

(define my-stack #f)

(define (saving-error-to-my-stack proc)
  (define (lazy-handler key . args)
    (set! my-stack (make-stack #t lazy-handler))
    (apply throw key args))
  (lazy-catch #t
    proc
    lazy-handler))

Notes - (i) the `lazy-handler' in the `make-stack' call tells
make-stack to return a stack object whose innermost frame is just
outside the call into lazy-handler; (ii) the `#t' in the make-stack
call means "here"; (iii) you must always rethrow from a lazy handler,
hence the `(apply throw ...)' line.

This should of course be in the manual.  If anyone feels like working
this into an appropriate patch, I'd appreciate it.

        Neil



_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user


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

end of thread, other threads:[~2002-10-21 18:55 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-10-19 21:18 reporting 'system-error informatively Paul Jarc
2002-10-20 21:38 ` Marius Vollmer
2002-10-20 23:02   ` Daniel Skarda
2002-10-21 14:46     ` Marius Vollmer
2002-10-21  6:13   ` Paul Jarc
2002-10-21 14:45     ` Marius Vollmer
2002-10-21 18:36       ` Paul Jarc
2002-10-21 18:55       ` 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).