3
;;; A simple debugger (improvements by Thomas M. Breuel <tmb@ai.mit.edu>).
5
(define (backtrace . args)
6
(if (> (length args) 1)
7
(error 'backtrace "too many arguments"))
9
(if (not (eq? (type (car args)) 'control-point))
10
(error 'backtrace "argument must be a control point")))
11
(let ((trace (apply backtrace-list args)))
13
(set! trace (cdddr trace)))
14
(show-backtrace trace 0 999999)))
16
(define (show-backtrace trace start-frame end-frame)
18
(let* ((y (string-append (make-string n #\space) x))
19
(l (string-length y)))
20
(substring y (- l n) l)))
22
(let loop ((frames (list-tail trace start-frame)) (num start-frame))
23
(if (or (null? frames) (>= num end-frame)) #v
24
(let ((frame (car frames)))
26
(format #f "~s" (vector-ref frame 0)))
28
(- maxlen (+ 5 (string-length func)))))
29
(display (rjust 4 (number->string num)))
32
(if (negative? indent)
35
(set! indent maxlen)))
36
(do ((i indent (1- i)))
42
(display (vector-ref frame 1)))
44
(loop (cdr frames) (1+ num))))))
46
(define (show-environment env)
50
(do ((f (environment->list env) (cdr f)))
52
(do ((b (car f) (cdr b)))
54
(format #t "~s\t~s~%" (caar b) (cdar b)))
63
'("q -- quit inspector"
64
"f -- print current frame"
65
"u -- go up one frame"
66
"d -- go down one frame"
67
"^ -- go to top frame"
68
"$ -- go to bottom frame"
69
"g <n> -- goto to n-th frame"
70
"e -- eval expressions in environment"
71
"p -- pretty-print procedure"
72
"v -- show environment"
73
"<n> -- pretty-print n-th argument"
74
"b -- show backtrace starting at current frame"
75
"t -- show top of bracktrace starting at current frame"
76
"z -- show and move top of backtrace starting at current frame"
77
"o -- obarray information")))
79
(define (inspect-command-loop)
80
(let ((input) (done #f))
98
(set! frame (1- (length trace)))
102
(format #t "Already on top frame.~%")
103
(set! frame (1- frame))
106
(if (= frame (1- (length trace)))
107
(format #t "Already on bottom frame.~%")
108
(set! frame (1+ frame))
114
(cond ((negative? input) 0)
115
((>= input (length trace)) (1- (length trace)))
117
(format #t "Frame number must be an integer.~%")))
119
(show-environment (vector-ref (list-ref trace frame) 2)))
121
(format #t "Type ^D to return to Inspector.~%")
125
(if (not (eof-object? input))
128
(vector-ref (list-ref trace frame) 2)))
133
(pp (vector-ref (list-ref trace frame) 0))
136
(show-backtrace trace frame (+ frame 10))
137
(set! frame (+ frame 9))
138
(if (>= frame (length trace)) (set! frame (1- (length trace)))))
140
(show-backtrace trace frame (+ frame 10)))
142
(show-backtrace trace frame 999999))
144
(let ((l (map length (oblist))))
146
(for-each (lambda (x) (set! n (+ x n))) l)
147
(format #t "~s symbols " n)
148
(format #t "(maximum bucket: ~s).~%" (apply max l)))))
152
(let ((args (vector-ref (list-ref trace frame) 1)))
153
(if (or (< input 1) (> input (length args)))
154
(format #t "No such argument.~%")
155
(pp (list-ref args (1- input)))
160
(format #t "Invalid command. Type ? for help.~%")))))
162
(inspect-command-loop))))
164
(define (print-frame)
165
(format #t "~%Frame ~s of ~s:~%~%" frame (1- (length trace)))
166
(let* ((f (list-ref trace frame)) (args (vector-ref f 1)))
167
(format #t "Procedure: ~s~%" (vector-ref f 0))
168
(format #t "Environment: ~s~%" (vector-ref f 2))
170
(format #t "No arguments.~%")
174
(do ((i 1 (1+ i)) (args args (cdr args))) ((null? args))
175
(format #t "Argument ~s: ~s~%" i (car args))))))
178
(define (find-frame proc)
179
(let loop ((l trace) (i 0))
181
((eq? (vector-ref (car l) 0) proc) i)
182
(else (loop (cdr l) (1+ i))))))
186
(set! trace (backtrace-list))
187
(set! trace (cddr trace))
188
(do ((t trace (cdr t)) (f 1 (1+ f))) ((null? t))
189
(if (not (null? (vector-ref (car t) 1)))
190
(let ((last (last-pair (vector-ref (car t) 1))))
191
(if (not (null? (cdr last)))
194
"[inspector: fixing improper arglist in frame ~s]~%" f)
195
(set-cdr! last (cons (cdr last) '())))))))
196
(set! frame (find-frame error-handler))
197
(if (negative? frame)
199
(format #t "Inspector (type ? for help):~%")
201
(if (call-with-current-continuation
202
(lambda (control-point)
203
(push-frame control-point)
204
(inspect-command-loop)
211
(let ((next-frame (car rep-frames)))