Commit | Line | Data |
---|---|---|
8ee7506b NJ |
1 | ;;;; (ice-9 debugger commands) -- debugger commands |
2 | ||
8397a3a6 | 3 | ;;; Copyright (C) 2002, 2006, 2009 Free Software Foundation, Inc. |
8ee7506b | 4 | ;;; |
53befeb7 NJ |
5 | ;;;; This library is free software; you can redistribute it and/or |
6 | ;;;; modify it under the terms of the GNU Lesser General Public | |
7 | ;;;; License as published by the Free Software Foundation; either | |
8 | ;;;; version 3 of the License, or (at your option) any later version. | |
9 | ;;;; | |
10 | ;;;; This library is distributed in the hope that it will be useful, | |
11 | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | ;;;; Lesser General Public License for more details. | |
14 | ;;;; | |
15 | ;;;; You should have received a copy of the GNU Lesser General Public | |
16 | ;;;; License along with this library; if not, write to the Free Software | |
17 | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
8ee7506b NJ |
18 | |
19 | (define-module (ice-9 debugger commands) | |
20 | #:use-module (ice-9 debug) | |
21 | #:use-module (ice-9 debugger) | |
8ee7506b NJ |
22 | #:use-module (ice-9 debugger state) |
23 | #:use-module (ice-9 debugger utils) | |
ba5f8bf4 | 24 | #:use-module (ice-9 debugging steps) |
8ee7506b NJ |
25 | #:export (backtrace |
26 | evaluate | |
27 | info-args | |
28 | info-frame | |
29 | position | |
30 | up | |
31 | down | |
ba5f8bf4 NJ |
32 | frame |
33 | continue | |
34 | finish | |
35 | step | |
36 | next)) | |
8ee7506b NJ |
37 | |
38 | (define (backtrace state n-frames) | |
39 | "Print backtrace of all stack frames, or innermost COUNT frames. | |
40 | With a negative argument, print outermost -COUNT frames. | |
41 | If the number of frames isn't explicitly given, the debug option | |
42 | `depth' determines the maximum number of frames printed." | |
43 | (let ((stack (state-stack state))) | |
44 | ;; Kludge around lack of call-with-values. | |
45 | (let ((values | |
46 | (lambda (start end) | |
47 | (display-backtrace stack | |
48 | (current-output-port) | |
49 | (if (memq 'backwards (debug-options)) | |
50 | start | |
51 | (- end 1)) | |
52 | (- end start)) | |
53 | ))) | |
54 | (let ((end (stack-length stack))) | |
55 | (cond ((not n-frames) ;(>= (abs n-frames) end)) | |
56 | (values 0 (min end (cadr (memq 'depth (debug-options)))))) | |
57 | ((>= n-frames 0) | |
58 | (values 0 n-frames)) | |
59 | (else | |
60 | (values (+ end n-frames) end))))))) | |
61 | ||
62 | (define (eval-handler key . args) | |
63 | (let ((stack (make-stack #t eval-handler))) | |
64 | (if (= (length args) 4) | |
65 | (apply display-error stack (current-error-port) args) | |
66 | ;; We want display-error to be the "final common pathway" | |
67 | (catch #t | |
68 | (lambda () | |
69 | (apply bad-throw key args)) | |
70 | (lambda (key . args) | |
71 | (apply display-error stack (current-error-port) args))))) | |
72 | (throw 'continue)) | |
73 | ||
8397a3a6 | 74 | ;; FIXME: no longer working due to no more local-eval |
8ee7506b | 75 | (define (evaluate state expression) |
ee6be719 NJ |
76 | "Evaluate an expression in the environment of the selected stack frame. |
77 | The expression must appear on the same line as the command, however it | |
78 | may be continued over multiple lines." | |
8ee7506b NJ |
79 | (let ((source (frame-source (stack-ref (state-stack state) |
80 | (state-index state))))) | |
81 | (if (not source) | |
82 | (display "No environment for this frame.\n") | |
83 | (catch 'continue | |
84 | (lambda () | |
85 | (lazy-catch #t | |
86 | (lambda () | |
79b1c5b6 NJ |
87 | (let* ((expr |
88 | ;; We assume that no one will | |
89 | ;; really want to evaluate a | |
90 | ;; string (since it is | |
91 | ;; self-evaluating); so if we | |
92 | ;; have a string here, read the | |
93 | ;; expression to evaluate from | |
94 | ;; it. | |
95 | (if (string? expression) | |
96 | (with-input-from-string expression | |
97 | read) | |
98 | expression)) | |
99 | (env (memoized-environment source)) | |
100 | (value (local-eval expr env))) | |
101 | (write expr) | |
102 | (display " => ") | |
8ee7506b NJ |
103 | (write value) |
104 | (newline))) | |
105 | eval-handler)) | |
106 | (lambda args args))))) | |
107 | ||
108 | (define (info-args state) | |
ee6be719 NJ |
109 | "Display the argument variables of the current stack frame. |
110 | Arguments can also be seen in the backtrace, but are presented more | |
111 | clearly by this command." | |
8ee7506b NJ |
112 | (let ((index (state-index state))) |
113 | (let ((frame (stack-ref (state-stack state) index))) | |
114 | (write-frame-index-long frame) | |
115 | (write-frame-args-long frame)))) | |
116 | ||
117 | (define (info-frame state) | |
ee6be719 NJ |
118 | "Display a verbose description of the selected frame. The |
119 | information that this command provides is equivalent to what can be | |
120 | deduced from the one line summary for the frame that appears in a | |
121 | backtrace, but is presented and explained more clearly." | |
8ee7506b NJ |
122 | (write-state-long state)) |
123 | ||
124 | (define (position state) | |
ee6be719 NJ |
125 | "Display the name of the source file that the current expression |
126 | comes from, and the line and column number of the expression's opening | |
127 | parenthesis within that file. This information is only available when | |
128 | the 'positions read option is enabled." | |
8ee7506b NJ |
129 | (let* ((frame (stack-ref (state-stack state) (state-index state))) |
130 | (source (frame-source frame))) | |
131 | (if (not source) | |
132 | (display "No source available for this frame.") | |
133 | (let ((position (source-position source))) | |
134 | (if (not position) | |
135 | (display "No position information available for this frame.") | |
136 | (display-position position))))) | |
137 | (newline)) | |
138 | ||
139 | (define (up state n) | |
140 | "Move @var{n} frames up the stack. For positive @var{n}, this | |
ee6be719 | 141 | advances toward the outermost frame, to lower frame numbers, to |
8ee7506b NJ |
142 | frames that have existed longer. @var{n} defaults to one." |
143 | (set-stack-index! state (+ (state-index state) (or n 1))) | |
144 | (write-state-short state)) | |
145 | ||
146 | (define (down state n) | |
147 | "Move @var{n} frames down the stack. For positive @var{n}, this | |
ee6be719 | 148 | advances toward the innermost frame, to higher frame numbers, to frames |
8ee7506b NJ |
149 | that were created more recently. @var{n} defaults to one." |
150 | (set-stack-index! state (- (state-index state) (or n 1))) | |
151 | (write-state-short state)) | |
152 | ||
153 | (define (frame state n) | |
154 | "Select and print a stack frame. | |
155 | With no argument, print the selected stack frame. (See also \"info frame\"). | |
156 | An argument specifies the frame to select; it must be a stack-frame number." | |
157 | (if n (set-stack-index! state (frame-number->index n (state-stack state)))) | |
158 | (write-state-short state)) | |
159 | ||
ba5f8bf4 NJ |
160 | (define (assert-continuable state) |
161 | ;; Check that debugger is in a state where `continuing' makes sense. | |
162 | ;; If not, signal an error. | |
163 | (or (memq #:continuable (state-flags state)) | |
164 | (user-error "This debug session is not continuable."))) | |
165 | ||
166 | (define (continue state) | |
167 | "Tell the program being debugged to continue running. (In fact this is | |
168 | the same as the @code{quit} command, because it exits the debugger | |
169 | command loop and so allows whatever code it was that invoked the | |
170 | debugger to continue.)" | |
171 | (assert-continuable state) | |
172 | (throw 'exit-debugger)) | |
173 | ||
174 | (define (finish state) | |
175 | "Continue until evaluation of the current frame is complete, and | |
176 | print the result obtained." | |
177 | (assert-continuable state) | |
178 | (at-exit (- (stack-length (state-stack state)) | |
179 | (state-index state)) | |
180 | (list trace-trap debug-trap)) | |
181 | (continue state)) | |
182 | ||
183 | (define (step state n) | |
184 | "Tell the debugged program to do @var{n} more steps from its current | |
185 | position. One @dfn{step} means executing until the next frame entry | |
186 | or exit of any kind. @var{n} defaults to 1." | |
187 | (assert-continuable state) | |
188 | (at-step debug-trap (or n 1)) | |
189 | (continue state)) | |
190 | ||
191 | (define (next state n) | |
192 | "Tell the debugged program to do @var{n} more steps from its current | |
193 | position, but only counting frame entries and exits where the | |
194 | corresponding source code comes from the same file as the current | |
195 | stack frame. (See @ref{Step Traps} for the details of how this | |
196 | works.) If the current stack frame has no source code, the effect of | |
197 | this command is the same as of @code{step}. @var{n} defaults to 1." | |
198 | (assert-continuable state) | |
199 | (at-step debug-trap | |
200 | (or n 1) | |
201 | (frame-file-name (stack-ref (state-stack state) | |
202 | (state-index state))) | |
203 | (if (memq #:return (state-flags state)) | |
204 | #f | |
205 | (- (stack-length (state-stack state)) (state-index state)))) | |
206 | (continue state)) | |
207 | ||
8ee7506b | 208 | ;;; (ice-9 debugger commands) ends here. |