Merge commit 'e20d7001c3f7150400169fecb0bf0eefdf122fe2' into vm-check
[bpt/guile.git] / module / ice-9 / debugger.scm
CommitLineData
e80e1c98
MD
1;;;; Guile Debugger
2
cd5fea8d 3;;; Copyright (C) 1999, 2001, 2002, 2006 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
92205699 17;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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)
24 #:export (debug-stack
25 debug
26 debug-last-error
27 debugger-error
28 debugger-quit
29 debugger-input-port
79b1c5b6
NJ
30 debugger-output-port
31 debug-on-error)
8ee7506b
NJ
32 #:no-backtrace)
33
34;;; The old (ice-9 debugger) has been factored into its constituent
35;;; parts:
36;;;
37;;; (ice-9 debugger) - public interface to all of the following
38;;;
39;;; (... commands) - procedures implementing the guts of the commands
40;;; provided by the interactive debugger
41;;;
42;;; (... command-loop) - binding these commands into the interactive
43;;; debugger command loop
44;;;
45;;; (... state) - implementation of an object that tracks current
46;;; debugger state
47;;;
48;;; (... utils) - utilities for printing out frame and stack
49;;; information in various formats
50;;;
51;;; The division between (... commands) and (... command-loop) exists
52;;; because I (NJ) have another generic command loop implementation
53;;; under development, and I want to be able to switch easily between
54;;; that and the command loop implementation here. Thus the
55;;; procedures in this file delegate to a debugger command loop
56;;; implementation via the `debugger-command-loop-*' interface. The
57;;; (ice-9 debugger command-loop) implementation can be replaced by
58;;; any other that implements the `debugger-command-loop-*' interface
59;;; simply by changing the relevant #:use-module line above.
60;;;
4199ace5 61;;; - Neil Jerram <neil@ossau.uklinux.net> 2002-10-26, updated 2005-07-09
8ee7506b
NJ
62
63(define *not-yet-introduced* #t)
64
65(define (debug-stack stack . flags)
66 "Invoke the Guile debugger to explore the specified @var{stack}.
67
68@var{flags}, if present, are keywords indicating characteristics of
69the debugging session: the valid keywords are as follows.
70
71@table @code
72@item #:continuable
73Indicates that the debugger is being invoked from a context (such as
74an evaluator trap handler) where it is possible to return from the
75debugger and continue normal code execution. This enables the
76@dfn{continuing execution} commands, for example @code{continue} and
77@code{step}.
78
79@item #:with-introduction
80Indicates that the debugger should display an introductory message.
81@end table"
82 (start-stack 'debugger
83 (let ((state (apply make-state stack 0 flags)))
84 (with-input-from-port (debugger-input-port)
85 (lambda ()
86 (with-output-to-port (debugger-output-port)
87 (lambda ()
88 (if (or *not-yet-introduced*
89 (memq #:with-introduction flags))
90 (let ((ssize (stack-length stack)))
91 (display "This is the Guile debugger -- for help, type `help'.\n")
92 (set! *not-yet-introduced* #f)
93 (if (= ssize 1)
94 (display "There is 1 frame on the stack.\n\n")
95 (format #t "There are ~A frames on the stack.\n\n" ssize))))
96 (write-state-short state)
9f4f1758 97 (debugger-command-loop state))))))))
8be85ef1 98
1a179b03 99(define (debug)
8ee7506b 100 "Invoke the Guile debugger to explore the context of the last error."
e80e1c98
MD
101 (let ((stack (fluid-ref the-last-stack)))
102 (if stack
8ee7506b 103 (debug-stack stack)
e80e1c98
MD
104 (display "Nothing to debug.\n"))))
105
8ee7506b 106(define debug-last-error debug)
e80e1c98 107
8ee7506b
NJ
108(define (debugger-error message)
109 "Signal a debugger usage error with message @var{message}."
110 (debugger-command-loop-error message))
e80e1c98 111
8ee7506b 112(define (debugger-quit)
e80e1c98 113 "Exit the debugger."
8ee7506b 114 (debugger-command-loop-quit))
8b8fd2e3 115
8ee7506b 116;;; {Debugger Input and Output Ports}
0ea63246 117
8ee7506b
NJ
118(define debugger-input-port
119 (let ((input-port (current-input-port)))
120 (make-procedure-with-setter
121 (lambda () input-port)
122 (lambda (port) (set! input-port port)))))
e80e1c98 123
8ee7506b
NJ
124(define debugger-output-port
125 (let ((output-port (current-output-port)))
126 (make-procedure-with-setter
127 (lambda () output-port)
128 (lambda (port) (set! output-port port)))))
e80e1c98 129
79b1c5b6
NJ
130;;; {Debug on Error}
131
79b1c5b6
NJ
132(define (debug-on-error syms)
133 "Enable or disable debug on error."
9f0e9918 134 (set! pre-unwind-handler-dispatch
79b1c5b6
NJ
135 (if syms
136 (lambda (key . args)
30d90280
NJ
137 (if (memq key syms)
138 (begin
9f0e9918 139 (debug-stack (make-stack #t pre-unwind-handler-dispatch)
30d90280
NJ
140 #:with-introduction
141 #:continuable)
142 (throw 'abort key)))
9f0e9918
AW
143 (apply default-pre-unwind-handler key args))
144 default-pre-unwind-handler)))
79b1c5b6 145
8ee7506b 146;;; (ice-9 debugger) ends here.