From: david@allouche.net
Subject: Trace, backtrace, exceptions and TeXmacs
Date: Tue, 4 Feb 2003 14:00:10 +0100 [thread overview]
Message-ID: <20030204130010.GL26640@joe.xlii.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 445 bytes --]
Hello,
sorry to annoy people with one more stupid question related to
debugging and error handling in applications embedding guile, but I
could not solve my problem by merely searching the mailing list
archive.
My problem
============
I have a problem combining backtrace display as previously described here:
http://mail.gnu.org/archive/html/guile-user/2001-01/msg00126.html
and a home-made tracing system (attached) used in TeXmacs.
[-- Attachment #2: debug-part.scm --]
[-- Type: text/plain, Size: 2628 bytes --]
;;;;;;;;;;;;;;;;;;;;;;;;; Display backtraces ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define tm-last-backtrace #f)
(define (backtrace-dumper key . args)
;; Internal function for backtrack
(let ((stack (make-stack #t backtrace-dumper)))
(set! tm-last-backtrace stack)
(display-backtrace stack (current-error-port))
(apply display-error stack (current-error-port) args)
(apply throw (cons key args))))
(define-macro (backtrack . body)
;; Evaluate body and print a full stack backtrace if an error occurs.
;; Copied from:
;; http://mail.gnu.org/archive/html/guile-user/2001-01/msg00126.html
;; For this to work, the user init file should start with:
;; (debug-enable 'backtrace 'debug)
;; NOTE: this is a hack, the whole error reporting system of TeXmacs should
;; be redesigned (well... not to say "designed to start with").
;; WARNING: has a problem coexisting with wrap-trace-level
`(lazy-catch #t (lambda () ,@body) backtrace-dumper))
;;;;;;;;;;;;;;;;;;;;;;;;;;; Tracing calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Trace levels
;; Display parameters and return value of a function.
;; Increase the trace indentation to show the call hierarchy.
;; Do not preserve tail recursion.
(define trace-level 0)
(define (trace-indent)
;; Produce the string to be used to indent trace output.
(let rec ((n trace-level) (s '()))
(if (equal? 0 n) (apply string-append s)
(rec (1- n) (cons "| " s)))))
(define (trace-display . args)
;; As display but also print trace indentation.
(display (trace-indent))
(for-each (lambda (a)
(display a)
(display " "))
args)
(newline))
(define (wrap-trace name lam)
(lambda args
(trace-display
(if (null? args)
(string-append "[" name "]")
(apply string-append
`("[" ,name
,@(map (lambda (x) (string-append " " (object->string x)))
args) "]"))))
(set! trace-level (1+ trace-level))
(catch #t
(lambda ()
(let ((res (apply lam args)))
(set! trace-level (1- trace-level))
(trace-display (object->string res))
res))
(lambda err
(set! trace-level (1- trace-level))
(apply throw err)))))
(define-macro (set-trace-level! . names)
;; Make each function a trace-level. Functions can be set multiple
;; times, only the first application is effective.
;; Parameters are function names
`(begin
,@(map (lambda (name)
`(if (not (procedure-property ,name 'trace-wrapped))
(begin
(set! ,name (wrap-trace ,(symbol->string name) ,name))
(set-procedure-property! ,name 'trace-wrapped #t))))
names)))
[-- Attachment #3: msg --]
[-- Type: text/plain, Size: 4377 bytes --]
When I do
(define (foo) (/ 1 0))
(set-trace-level! foo) ; these forms are defined in the attached
(backtrack foo) ; snipped of texmacs' debug.scm
I get the following output on the console (the first line is the
output of the home-made trace).
[foo]
1 [catch #t #<procedure ()> #<procedure TeXmacs-guile-error-handler args>]
2* [#<procedure ()>]
3* [object->string ...
4* [eval-string "(make-return)"]
5* [#<procedure ()>]
6 (if (string-null? (get-env "return action")) (pass) ...)
...
7 [process-input]
8* [TeXmacs-guile-eval-any "(backtrack (foo))"]
9 [catch #t #<procedure ()> #<procedure TeXmacs-guile-error-handler
args>]
10* [#<procedure ()>]
11* [object->string ...
12* [eval-string "(backtrack (foo))"]
13* (backtrack (foo))
14 [lazy-catch #t #<procedure ()> #<procedure backtrace-dumper (key .
args)>]
15* [#<procedure ()>]
16* [#<procedure args>]
17 [catch #t #<procedure ()> #<procedure err>]
18* [#<procedure err> numerical-overflow "/" "Numerical overflow" #f
#f]
19* [apply #<primitive-procedure throw> #]
20 [apply #<primitive-procedure throw> #]
ERROR: In procedure apply in expression (apply throw err):
ERROR: Numerical overflow
It seems that the apply in wrap-trace-level is executed twice, and the
second time it has invalid arguments.
I could not find any way of preventing that strang behaviour, and that
is very annoying. I tried wrapping the lazy catch in a (catch
'ignore-this ...) as in the provided example, but it did not help (and
prevented the error going all the way up to the texmacs).
Also I was unable to reproduce the problem in a simple guile
interpreter because the built-in backtrace feature seems to get in the
way of exception handling.
Actually I would rather like to find a way to use the built-in trace
feature, any idea?
I am using guile-1.4.1. I know I should use a more recent release but
we have a policy of supporting all guile versions from 1.3.4 (esp. the
main developer of TeXmacs uses this version) so I rather not use
guile-1.6 for development.
Why it is all so dirty
=========================
I know I should rather use the built-in tracing capability defined by
(use-modules (ice-9 debug))
but (trace foo), where foo is some buggy function, does not seem to
enable any tracing from within TeXmacs. I have tried enabling
debugging as described there:
http://www.masanjin.net/wiki/Wiki.jsp?page=IncorporatingGuileIntoYourCProgram
by including the following snippet early in the application
initialization:
SCM_DEVAL_P = 1;
SCM_BACKTRACE_P = 1;
SCM_RECORD_POSITIONS_P = 1;
SCM_RESET_DEBUG_MODE;
But it does not seem to have any effect. Specifically it does not
enable lazy-catch based backtrace display. On the other hand,
including that statement:
(debug-enable 'backtrace 'debug)
early in the scheme environment initialization did activate backtraces
inside lazy-catch, but did not allow me to use the built-in trace
form.
More context
==============
For information, TeXmacs evaluates scheme commands using the following
code (I admit it is pretty dumb):
[this is part of the VERY early environment init]
"(define (TeXmacs-guile-error-handler . args)\n"
" (object->string args))\n"
"\n"
"(define (object->string obj)\n"
" (call-with-output-string\n"
" (lambda (port) (write obj port))))\n"
"\n"
"(define (TeXmacs-guile-eval-any s)\n"
" (catch\n"
" #t\n"
" (lambda ()\n"
" (object->string (eval-string s)))\n"
" TeXmacs-guile-error-handler))\n"
[this is the corresponding C++ code]
bool
eval_scheme_any (string s, string& r) {
// cout << "Eval any] " << start (s) << "\n";
string prg= "(TeXmacs-guile-eval-any \"" * back_slash (s) * "\")";
char* _s= as_charp (prg);
SCM result= gh_eval_str (_s);
delete[] _s;
int len_r;
char* _r= scm2newstr (result, &len_r);
r= _r;
free (_r);
if (r == "#<unspecified>") r= "";
// cout << "Yields] " << start (r) << "\n";
return false;
}
Please, help!
--
David Allouche | GNU TeXmacs -- Writing is a pleasure
Free software engineer | http://www.texmacs.org
http://ddaa.net | http://alqua.com/tmresources
david@allouche.net | allouche@texmacs.org
TeXmacs is NOT a LaTeX front-end and is unrelated to emacs.
[-- Attachment #4: Type: text/plain, Size: 139 bytes --]
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user
reply other threads:[~2003-02-04 13:00 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20030204130010.GL26640@joe.xlii.org \
--to=david@allouche.net \
/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).