* srfi-60.scm, srfi-60.c, srfi-60.h: New files.
[bpt/guile.git] / ice-9 / debugger.scm
CommitLineData
e80e1c98
MD
1;;;; Guile Debugger
2
8ee7506b 3;;; Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
e80e1c98 4;;;
73be1d9e
MV
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 2.1 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
e80e1c98 18
8be85ef1 19(define-module (ice-9 debugger)
8ee7506b
NJ
20 #:use-module (ice-9 debugger command-loop)
21 #:use-module (ice-9 debugger state)
22 #:use-module (ice-9 debugger utils)
23 #:use-module (ice-9 format)
30d90280 24 #:use-module (emacs gds-client)
8ee7506b
NJ
25 #:export (debug-stack
26 debug
27 debug-last-error
28 debugger-error
29 debugger-quit
30 debugger-input-port
79b1c5b6
NJ
31 debugger-output-port
32 debug-on-error)
8ee7506b
NJ
33 #:no-backtrace)
34
35;;; The old (ice-9 debugger) has been factored into its constituent
36;;; parts:
37;;;
38;;; (ice-9 debugger) - public interface to all of the following
39;;;
40;;; (... commands) - procedures implementing the guts of the commands
41;;; provided by the interactive debugger
42;;;
43;;; (... command-loop) - binding these commands into the interactive
44;;; debugger command loop
45;;;
46;;; (... state) - implementation of an object that tracks current
47;;; debugger state
48;;;
49;;; (... utils) - utilities for printing out frame and stack
50;;; information in various formats
51;;;
52;;; The division between (... commands) and (... command-loop) exists
53;;; because I (NJ) have another generic command loop implementation
54;;; under development, and I want to be able to switch easily between
55;;; that and the command loop implementation here. Thus the
56;;; procedures in this file delegate to a debugger command loop
57;;; implementation via the `debugger-command-loop-*' interface. The
58;;; (ice-9 debugger command-loop) implementation can be replaced by
59;;; any other that implements the `debugger-command-loop-*' interface
60;;; simply by changing the relevant #:use-module line above.
61;;;
62;;; The following new parts add breakpoint support:
63;;;
64;;; (... behaviour) - codification of the things that can happen when
65;;; a breakpoint is hit, regardless of the type of
66;;; the breakpoint
67;;;
68;;; (... breakpoints) - management of breakpoints in general
69;;;
70;;; (... breakpoints procedural) - breakpoints that trigger upon
71;;; application of a specified
72;;; procedure
73;;;
74;;; (... breakpoints source) - breakpoints that trigger upon
75;;; evaluation of a specific source
76;;; expression
77;;;
78;;; (... trap-hooks) - a (slightly) higher-level abstraction of
79;;; Guile's evaluator traps interface
80;;;
81;;; (... trc) - generic tracing interface for debugging tricky code
82;;; using the `printf' method :-)
83;;;
84;;; Note that (... breakpoints range) doesn't work yet. If loaded, it
85;;; seems to cause some kind of explosion in the GOOPS method cache
86;;; calculation code.
87;;;
88;;; - Neil Jerram <neil@ossau.uklinux.net> 2002-10-26
89
90(define *not-yet-introduced* #t)
91
92(define (debug-stack stack . flags)
93 "Invoke the Guile debugger to explore the specified @var{stack}.
94
95@var{flags}, if present, are keywords indicating characteristics of
96the debugging session: the valid keywords are as follows.
97
98@table @code
99@item #:continuable
100Indicates that the debugger is being invoked from a context (such as
101an evaluator trap handler) where it is possible to return from the
102debugger and continue normal code execution. This enables the
103@dfn{continuing execution} commands, for example @code{continue} and
104@code{step}.
105
106@item #:with-introduction
107Indicates that the debugger should display an introductory message.
108@end table"
109 (start-stack 'debugger
110 (let ((state (apply make-state stack 0 flags)))
111 (with-input-from-port (debugger-input-port)
112 (lambda ()
113 (with-output-to-port (debugger-output-port)
114 (lambda ()
115 (if (or *not-yet-introduced*
116 (memq #:with-introduction flags))
117 (let ((ssize (stack-length stack)))
118 (display "This is the Guile debugger -- for help, type `help'.\n")
119 (set! *not-yet-introduced* #f)
120 (if (= ssize 1)
121 (display "There is 1 frame on the stack.\n\n")
122 (format #t "There are ~A frames on the stack.\n\n" ssize))))
123 (write-state-short state)
30d90280
NJ
124 (if (gds-connected?)
125 (gds-command-loop state)
79b1c5b6 126 (debugger-command-loop state)))))))))
8be85ef1 127
1a179b03 128(define (debug)
8ee7506b 129 "Invoke the Guile debugger to explore the context of the last error."
e80e1c98
MD
130 (let ((stack (fluid-ref the-last-stack)))
131 (if stack
8ee7506b 132 (debug-stack stack)
e80e1c98
MD
133 (display "Nothing to debug.\n"))))
134
8ee7506b 135(define debug-last-error debug)
e80e1c98 136
8ee7506b
NJ
137(define (debugger-error message)
138 "Signal a debugger usage error with message @var{message}."
139 (debugger-command-loop-error message))
e80e1c98 140
8ee7506b 141(define (debugger-quit)
e80e1c98 142 "Exit the debugger."
8ee7506b 143 (debugger-command-loop-quit))
8b8fd2e3 144
8ee7506b 145;;; {Debugger Input and Output Ports}
0ea63246 146
8ee7506b
NJ
147(define debugger-input-port
148 (let ((input-port (current-input-port)))
149 (make-procedure-with-setter
150 (lambda () input-port)
151 (lambda (port) (set! input-port port)))))
e80e1c98 152
8ee7506b
NJ
153(define debugger-output-port
154 (let ((output-port (current-output-port)))
155 (make-procedure-with-setter
156 (lambda () output-port)
157 (lambda (port) (set! output-port port)))))
e80e1c98 158
79b1c5b6
NJ
159;;; {Debug on Error}
160
79b1c5b6
NJ
161(define (debug-on-error syms)
162 "Enable or disable debug on error."
9f1af5d9 163 (set! lazy-handler-dispatch
79b1c5b6
NJ
164 (if syms
165 (lambda (key . args)
30d90280
NJ
166 (if (memq key syms)
167 (begin
168 (debug-stack (make-stack #t lazy-handler-dispatch)
169 #:with-introduction
170 #:continuable)
171 (throw 'abort key)))
9f1af5d9
NJ
172 (apply default-lazy-handler key args))
173 default-lazy-handler)))
79b1c5b6 174
8ee7506b 175;;; (ice-9 debugger) ends here.