;;; nestedness inside debugger command loops
(defvar *debug-command-level* 0)
-(defvar *stack-top-hint* nil
- #!+sb-doc
- "If this is bound before the debugger is invoked, it is used as the stack
- top by the debugger.")
+;;; If this is bound before the debugger is invoked, it is used as the
+;;; stack top by the debugger.
+(defvar *stack-top-hint* nil)
+
(defvar *stack-top* nil)
(defvar *real-stack-top* nil)
(defvar *current-frame* nil)
+;;; Beginner-oriented help messages are important because you end up
+;;; in the debugger whenever something bad happens, or if you try to
+;;; get out of the system with Ctrl-C or (EXIT) or EXIT or whatever.
+;;; But after memorizing them the wasted screen space gets annoying..
+(defvar *debug-beginner-help-p* t
+ "Should the debugger display beginner-oriented help messages?")
+
(defun debug-prompt (stream)
;; old behavior, will probably go away in sbcl-0.7.x
(declaim (type integer *number-of-steps*))
;;; This is used when listing and setting breakpoints.
-(defvar *default-breakpoint-debug-function* nil)
-(declaim (type (or list sb!di:debug-function) *default-breakpoint-debug-function*))
+(defvar *default-breakpoint-debug-fun* nil)
+(declaim (type (or list sb!di:debug-fun) *default-breakpoint-debug-fun*))
\f
;;;; code location utilities
(setf next-list (next-code-locations (first next-list))))
next-list)))
-;;; Returns a list of code-locations of the possible breakpoints of the
-;;; debug-function passed.
-(defun possible-breakpoints (debug-function)
+;;; Return a list of code-locations of the possible breakpoints of DEBUG-FUN.
+(defun possible-breakpoints (debug-fun)
(let ((possible-breakpoints nil))
- (sb!di:do-debug-function-blocks (debug-block debug-function)
+ (sb!di:do-debug-fun-blocks (debug-block debug-fun)
(unless (sb!di:debug-block-elsewhere-p debug-block)
(if *only-block-start-locations*
(push (first-code-location debug-block) possible-breakpoints)
(push code-location possible-breakpoints))))))
(nreverse possible-breakpoints)))
-;;; Searches the info-list for the item passed (code-location,
-;;; debug-function, or breakpoint-info). If the item passed is a debug
+;;; Search the info-list for the item passed (CODE-LOCATION,
+;;; DEBUG-FUN, or BREAKPOINT-INFO). If the item passed is a debug
;;; function then kind will be compared if it was specified. The kind
;;; if also compared if a breakpoint-info is passed since it's in the
;;; breakpoint. The info structure is returned if found.
(sb!di:code-location= x y)))))
(t
(find place info-list
- :test #'(lambda (x-debug-function y-info)
+ :test #'(lambda (x-debug-fun y-info)
(let ((y-place (breakpoint-info-place y-info))
(y-breakpoint (breakpoint-info-breakpoint
y-info)))
- (and (sb!di:debug-function-p y-place)
- (eq x-debug-function y-place)
+ (and (sb!di:debug-fun-p y-place)
+ (eq x-debug-fun y-place)
(or (not kind)
(eq kind (sb!di:breakpoint-kind
y-breakpoint))))))))))
(defstruct (breakpoint-info (:copier nil))
;; where we are going to stop
(place (required-argument)
- :type (or sb!di:code-location sb!di:debug-function))
+ :type (or sb!di:code-location sb!di:debug-fun))
;; the breakpoint returned by sb!di:make-breakpoint
(breakpoint (required-argument) :type sb!di:breakpoint)
- ;; the function returned from sb!di:preprocess-for-eval. If result is
+ ;; the function returned from SB!DI:PREPROCESS-FOR-EVAL. If result is
;; non-NIL, drop into the debugger.
(break #'identity :type function)
;; the function returned from sb!di:preprocess-for-eval. If result is
"~&~S: ~S in ~S"
bp-number
loc-number
- (sb!di:debug-function-name (sb!di:code-location-debug-function
- place))))
+ (sb!di:debug-fun-name (sb!di:code-location-debug-fun
+ place))))
(:function-start
(format t "~&~S: FUNCTION-START in ~S" bp-number
- (sb!di:debug-function-name place)))
+ (sb!di:debug-fun-name place)))
(:function-end
(format t "~&~S: FUNCTION-END in ~S" bp-number
- (sb!di:debug-function-name place))))))
+ (sb!di:debug-fun-name place))))))
\f
;;;; MAIN-HOOK-FUNCTION for steps and breakpoints
;;; STEP breakpoints are.
(defun main-hook-function (current-frame breakpoint &optional return-vals
function-end-cookie)
- (setf *default-breakpoint-debug-function*
- (sb!di:frame-debug-function current-frame))
+ (setf *default-breakpoint-debug-fun*
+ (sb!di:frame-debug-fun current-frame))
(dolist (step-info *step-breakpoints*)
(sb!di:delete-breakpoint (breakpoint-info-breakpoint step-info))
(let ((bp-info (location-in-list step-info *breakpoints*)))
(push (create-breakpoint-info code-location bp 0)
*step-breakpoints*))))
(t
- (let* ((debug-function (sb!di:frame-debug-function *current-frame*))
- (bp (sb!di:make-breakpoint #'main-hook-function debug-function
+ (let* ((debug-fun (sb!di:frame-debug-fun *current-frame*))
+ (bp (sb!di:make-breakpoint #'main-hook-function debug-fun
:kind :function-end)))
(sb!di:activate-breakpoint bp)
- (push (create-breakpoint-info debug-function bp 0)
+ (push (create-breakpoint-info debug-fun bp 0)
*step-breakpoints*))))))))
\f
;;;; STEP
(*standard-output* *debug-io*))
#!+sb-doc
"Show a listing of the call stack going down from the current frame. In the
- debugger, the current frame is indicated by the prompt. Count is how many
+ debugger, the current frame is indicated by the prompt. COUNT is how many
frames to show."
(fresh-line *standard-output*)
(do ((frame (if *in-the-debugger* *current-frame* (sb!di:top-frame))
;;; lambda-list variables since any other arguments will be in the
;;; &REST arg's list of values.
(defun print-frame-call-1 (frame)
- (let* ((d-fun (sb!di:frame-debug-function frame))
+ (let* ((d-fun (sb!di:frame-debug-fun frame))
(loc (sb!di:frame-code-location frame))
- (results (list (sb!di:debug-function-name d-fun))))
+ (results (list (sb!di:debug-fun-name d-fun))))
(handler-case
- (dolist (ele (sb!di:debug-function-lambda-list d-fun))
+ (dolist (ele (sb!di:debug-fun-lambda-list d-fun))
(lambda-list-element-dispatch ele
:required ((push (frame-call-arg ele loc frame) results))
:optional ((push (frame-call-arg (second ele) loc frame) results))
(pprint-logical-block (*standard-output* nil)
(let ((x (nreverse (mapcar #'ensure-printable-object results))))
(format t "(~@<~S~{ ~_~S~}~:>)" (first x) (rest x))))
- (when (sb!di:debug-function-kind d-fun)
+ (when (sb!di:debug-fun-kind d-fun)
(write-char #\[)
- (prin1 (sb!di:debug-function-kind d-fun))
+ (prin1 (sb!di:debug-fun-kind d-fun))
(write-char #\]))))
(defun ensure-printable-object (object)
;;; Prints a representation of the function call causing FRAME to
;;; exist. VERBOSITY indicates the level of information to output;
-;;; zero indicates just printing the debug-function's name, and one
+;;; zero indicates just printing the DEBUG-FUN's name, and one
;;; indicates displaying call-like, one-liner format with argument
;;; values.
(defun print-frame-call (frame &key (verbosity 1) (number nil))
(defvar *debug-restarts*)
(defvar *debug-condition*)
-;;; Print *DEBUG-CONDITION*, taking care to avoid recursive invocation
-;;; of the debugger in case of a problem (e.g. a bug in the PRINT-OBJECT
-;;; method for *DEBUG-CONDITION*).
-(defun princ-debug-condition-carefully (stream)
- (handler-case (princ *debug-condition* stream)
- (error (condition)
- (format stream
- " (caught ~S when trying to print ~S)"
- (type-of condition)
- '*debug-condition*)))
- *debug-condition*)
-
(defun invoke-debugger (condition)
#!+sb-doc
"Enter the debugger."
;; the last line of output or so, and get confused.
(flush-standard-output-streams)
- ;; The initial output here goes to *ERROR-OUTPUT*, because the
+ ;; (The initial output here goes to *ERROR-OUTPUT*, because the
;; initial output is not interactive, just an error message,
;; and when people redirect *ERROR-OUTPUT*, they could
;; reasonably expect to see error messages logged there,
- ;; regardless of what the debugger does afterwards.
- (format *error-output*
- "~2&debugger invoked on condition of type ~S:~% "
- (type-of *debug-condition*))
- (princ-debug-condition-carefully *error-output*)
- (terpri *error-output*)
+ ;; regardless of what the debugger does afterwards.)
+ (handler-case
+ (format *error-output*
+ "~2&~@<debugger invoked on condition of type ~S: ~
+ ~2I~_~A~:>~%"
+ (type-of *debug-condition*)
+ *debug-condition*)
+ (error (condition)
+ (format *error-output*
+ "~&(caught ~S trying to print ~S when entering debugger)~%"
+ (type-of condition)
+ '*debug-condition*)))
;; After the initial error/condition/whatever announcement to
;; *ERROR-OUTPUT*, we become interactive, and should talk on
;; that file, and right to send them to *DEBUG-IO*.
(*error-output* *debug-io*))
(unless (typep condition 'step-condition)
- (format *debug-io*
- "~%~@<Within the debugger, you can type HELP for help. At ~
- any command prompt (within the debugger or not) you can ~
- type (SB-EXT:QUIT) to terminate the SBCL executable. ~
- The condition which caused the debugger to be entered ~
- is bound to ~S.~:@>~2%"
- '*debug-condition*)
- (show-restarts *debug-restarts* *debug-io*)
- (terpri *debug-io*))
+ (when *debug-beginner-help-p*
+ (format *debug-io*
+ "~%~@<Within the debugger, you can type HELP for help. ~
+ At any command prompt (within the debugger or not) you ~
+ can type (SB-EXT:QUIT) to terminate the SBCL ~
+ executable. The condition which caused the debugger to ~
+ be entered is bound to ~S. You can suppress this ~
+ message by clearing ~S.~:@>~2%"
+ '*debug-condition*
+ '*debug-beginner-help-p*))
+ (show-restarts *debug-restarts* *debug-io*))
(internal-debug))))))
(defun show-restarts (restarts s)
(t
(funcall cmd-fun)))))))))))))))
-;;; FIXME: As far as I know, the CMU CL X86 codebase has never
-;;; supported access to the environment of the debugged function. It
-;;; would be really, really nice to make that work! (Until then,
-;;; non-NIL *AUTO-EVAL-IN-FRAME* seems to be useless, and as of
-;;; sbcl-0.6.10 it even seemed to be actively harmful, since the
-;;; debugger gets confused when trying to unwind the frames which
-;;; arise in SIGINT interrupts. So it's set to NIL.)
-(defvar *auto-eval-in-frame* nil
- #!+sb-doc
- "When set, evaluations in the debugger's command loop occur relative
- to the current frame's environment without the need of debugger
- forms that explicitly control this kind of evaluation. In an ideal
- world, the default would be T, but since unfortunately the X86
- debugger support isn't good enough to make this useful, the
- default is NIL instead.")
-
;;; FIXME: We could probably use INTERACTIVE-EVAL for much of this logic.
(defun debug-eval-print (expr)
(/noshow "entering DEBUG-EVAL-PRINT" expr)
(/noshow (fboundp 'compile))
- (/noshow (and (fboundp 'compile) *auto-eval-in-frame*))
(setq +++ ++ ++ + + - - expr)
- (let* ((values (multiple-value-list
- (if (and (fboundp 'compile) *auto-eval-in-frame*)
- (sb!di:eval-in-frame *current-frame* -)
- (eval -))))
+ (let* ((values (multiple-value-list (eval -)))
(*standard-output* *debug-io*))
(/noshow "done with EVAL in DEBUG-EVAL-PRINT")
(fresh-line)
(sb!xc:defmacro define-var-operation (ref-or-set &optional value-var)
`(let* ((temp (etypecase name
- (symbol (sb!di:debug-function-symbol-variables
- (sb!di:frame-debug-function *current-frame*)
+ (symbol (sb!di:debug-fun-symbol-variables
+ (sb!di:frame-debug-fun *current-frame*)
name))
(simple-string (sb!di:ambiguous-debug-vars
- (sb!di:frame-debug-function *current-frame*)
+ (sb!di:frame-debug-fun *current-frame*)
name))))
(location (sb!di:frame-code-location *current-frame*))
;; Let's only deal with valid variables.
(define-var-operation :set value))
;;; This returns the COUNT'th arg as the user sees it from args, the
-;;; result of SB!DI:DEBUG-FUNCTION-LAMBDA-LIST. If this returns a
+;;; result of SB!DI:DEBUG-FUN-LAMBDA-LIST. If this returns a
;;; potential DEBUG-VAR from the lambda-list, then the second value is
;;; T. If this returns a keyword symbol or a value from a rest arg,
;;; then the second value is NIL.
(defun arg (n)
#!+sb-doc
- "Returns the N'th argument's value if possible. Argument zero is the first
+ "Return the N'th argument's value if possible. Argument zero is the first
argument in a frame's default printed representation. Count keyword/value
pairs as separate arguments."
(multiple-value-bind (var lambda-var-p)
- (nth-arg n (handler-case (sb!di:debug-function-lambda-list
- (sb!di:frame-debug-function *current-frame*))
+ (nth-arg n (handler-case (sb!di:debug-fun-lambda-list
+ (sb!di:frame-debug-fun *current-frame*))
(sb!di:lambda-list-unavailable ()
(error "No argument values are available."))))
(if lambda-var-p
(!def-debug-command-alias "P" "PRINT")
(!def-debug-command "LIST-LOCALS" ()
- (let ((d-fun (sb!di:frame-debug-function *current-frame*)))
+ (let ((d-fun (sb!di:frame-debug-fun *current-frame*)))
(if (sb!di:debug-var-info-available d-fun)
(let ((*standard-output* *debug-io*)
(location (sb!di:frame-code-location *current-frame*))
(defvar *cached-readtable* nil)
(declaim (type (or readtable null) *cached-readtable*))
-(pushnew #'(lambda ()
- (setq *cached-debug-source* nil *cached-source-stream* nil
- *cached-readtable* nil))
- sb!int:*before-save-initializations*)
+(pushnew (lambda ()
+ (setq *cached-debug-source* nil *cached-source-stream* nil
+ *cached-readtable* nil))
+ *before-save-initializations*)
;;; We also cache the last top-level form that we printed a source for
;;; so that we don't have to do repeated reads and calls to
;;; *POSSIBLE-BREAKPOINTS* to the code-locations which can then be
;;; used by sbreakpoint.
(!def-debug-command "LIST-LOCATIONS" ()
- (let ((df (read-if-available *default-breakpoint-debug-function*)))
+ (let ((df (read-if-available *default-breakpoint-debug-fun*)))
(cond ((consp df)
- (setf df (sb!di:function-debug-function (eval df)))
- (setf *default-breakpoint-debug-function* df))
+ (setf df (sb!di:fun-debug-fun (eval df)))
+ (setf *default-breakpoint-debug-fun* df))
((or (eq ':c df)
- (not *default-breakpoint-debug-function*))
- (setf df (sb!di:frame-debug-function *current-frame*))
- (setf *default-breakpoint-debug-function* df)))
+ (not *default-breakpoint-debug-fun*))
+ (setf df (sb!di:frame-debug-fun *current-frame*))
+ (setf *default-breakpoint-debug-fun* df)))
(setf *possible-breakpoints* (possible-breakpoints df)))
(let ((continue-at (sb!di:frame-code-location *current-frame*)))
- (let ((active (location-in-list *default-breakpoint-debug-function*
+ (let ((active (location-in-list *default-breakpoint-debug-fun*
*breakpoints* :function-start))
(here (sb!di:code-location=
- (sb!di:debug-function-start-location
- *default-breakpoint-debug-function*) continue-at)))
+ (sb!di:debug-fun-start-location
+ *default-breakpoint-debug-fun*) continue-at)))
(when (or active here)
(format t "::FUNCTION-START ")
(when active (format t " *Active*"))
(incf this-num))))
- (when (location-in-list *default-breakpoint-debug-function*
+ (when (location-in-list *default-breakpoint-debug-fun*
*breakpoints*
:function-end)
(format t "~&::FUNCTION-END *Active* "))))
(print-functions nil)
(function nil)
(bp)
- (place *default-breakpoint-debug-function*))
+ (place *default-breakpoint-debug-fun*))
(flet ((get-command-line ()
(let ((command-line nil)
(unique '(nil)))
(:break (setf break (pop command-line)))
(:function
(setf function (eval (pop command-line)))
- (setf *default-breakpoint-debug-function*
- (sb!di:function-debug-function function))
- (setf place *default-breakpoint-debug-function*)
+ (setf *default-breakpoint-debug-fun*
+ (sb!di:fun-debug-fun function))
+ (setf place *default-breakpoint-debug-fun*)
(setf *possible-breakpoints*
(possible-breakpoints
- *default-breakpoint-debug-function*))))))
+ *default-breakpoint-debug-fun*))))))
(setup-function-start ()
- (let ((code-loc (sb!di:debug-function-start-location place)))
+ (let ((code-loc (sb!di:debug-fun-start-location place)))
(setf bp (sb!di:make-breakpoint #'main-hook-function
place
:kind :function-start))
(!def-debug-command "DESCRIBE" ()
(let* ((curloc (sb!di:frame-code-location *current-frame*))
- (debug-fun (sb!di:code-location-debug-function curloc))
- (function (sb!di:debug-function-function debug-fun)))
+ (debug-fun (sb!di:code-location-debug-fun curloc))
+ (function (sb!di:debug-fun-fun debug-fun)))
(if function
(describe function)
(format t "can't figure out the function for this frame"))))