In the debugger, the current frame is indicated by the prompt. COUNT
is how many frames to show."
(fresh-line stream)
- (map-backtrace (lambda (frame)
- (print-frame-call frame stream :number t))
- :count count)
+ (let ((*suppress-print-errors* (if (subtypep 'serious-condition *suppress-print-errors*)
+ *suppress-print-errors*
+ 'serious-condition))
+ (*print-circle* t))
+ (handler-bind ((print-not-readable #'print-unreadably))
+ (map-backtrace (lambda (frame)
+ (print-frame-call frame stream :number t))
+ :count count)))
(fresh-line stream)
(values))
;; For the function arguments, we can just print normally.
(let ((*print-length* nil)
(*print-level* nil))
- (prin1 (ensure-printable-object name) stream))
- ;; If we hit a &REST arg, then print as many of the values as
- ;; possible, punting the loop over lambda-list variables since any
- ;; other arguments will be in the &REST arg's list of values.
- (let ((print-args (ensure-printable-object args))
- ;; Special case *PRINT-PRETTY* for eval frames: if
- ;; *PRINT-LINES* is 1, turn off pretty-printing.
- (*print-pretty*
- (if (and (eql 1 *print-lines*)
- (member name '(eval simple-eval-in-lexenv)))
- nil
- *print-pretty*)))
- (if (listp print-args)
- (format stream "~{ ~_~S~}" print-args)
- (format stream " ~S" print-args))))
+ (prin1 name stream))
+ ;; If we hit a &REST arg, then print as many of the values
+ ;; as possible, punting the loop over lambda-list variables
+ ;; since any other arguments will be in the &REST arg's list
+ ;; of values. Special case *PRINT-PRETTY* for eval frames:
+ ;; if *PRINT-LINES* is 1, turn off pretty-printing.
+ (let ((*print-pretty*
+ (if (and (eql 1 *print-lines*)
+ (member name '(eval simple-eval-in-lexenv)))
+ nil
+ *print-pretty*))))
+ (if (listp args)
+ (format stream "~{ ~_~S~}" args)
+ (format stream " ~S" args)))
(when kind
(format stream "[~S]" kind))))
(when (>= verbosity 2)
;; definitely preferred, because the FORMAT alternative was acting odd.
(pprint-logical-block (stream nil)
(format stream
- "debugger invoked on a ~S~@[ in thread ~A~]: ~2I~_~A"
+ "debugger invoked on a ~S~@[ in thread ~_~A~]: ~2I~_~A"
(type-of condition)
#!+sb-thread sb!thread:*current-thread*
#!-sb-thread nil
(location (sb!di:frame-code-location *current-frame*))
(prefix (read-if-available nil))
(any-p nil)
- (any-valid-p nil))
+ (any-valid-p nil)
+ (more-context nil)
+ (more-count nil))
(dolist (v (sb!di:ambiguous-debug-vars
- d-fun
- (if prefix (string prefix) "")))
+ d-fun
+ (if prefix (string prefix) "")))
(setf any-p t)
(when (eq (sb!di:debug-var-validity v location) :valid)
(setf any-valid-p t)
+ (case (sb!di::debug-var-info v)
+ (:more-context
+ (setf more-context (sb!di:debug-var-value v *current-frame*)))
+ (:more-count
+ (setf more-count (sb!di:debug-var-value v *current-frame*))))
(format *debug-io* "~S~:[#~W~;~*~] = ~S~%"
(sb!di:debug-var-symbol v)
(zerop (sb!di:debug-var-id v))
(sb!di:debug-var-id v)
(sb!di:debug-var-value v *current-frame*))))
-
+ (when (and more-context more-count)
+ (format *debug-io* "~S = ~S~%"
+ 'more
+ (multiple-value-list (sb!c:%more-arg-values more-context 0 more-count))))
(cond
((not any-p)
(format *debug-io*
(!def-debug-command "RESTART-FRAME" ()
(if (frame-has-debug-tag-p *current-frame*)
- (let* ((call-list (frame-call-as-list *current-frame*))
- (fun (fdefinition (car call-list))))
- (unwind-to-frame-and-call *current-frame*
- (lambda ()
- (apply fun (cdr call-list)))))
+ (multiple-value-bind (fname args) (frame-call *current-frame*)
+ (multiple-value-bind (fun arglist ok)
+ (if (and (legal-fun-name-p fname) (fboundp fname))
+ (values (fdefinition fname) args t)
+ (values (sb!di:debug-fun-fun (sb!di:frame-debug-fun *current-frame*))
+ (frame-args-as-list *current-frame*)
+ nil))
+ (when (and fun
+ (or ok
+ (y-or-n-p "~@<No global function for the frame, but we ~
+ do have access to a function object that we ~
+ can try to call -- but if it is normally part ~
+ of a closure, then this is NOT going to end well.~_~_~
+ Try it anyways?~:@>")))
+ (unwind-to-frame-and-call *current-frame*
+ (lambda ()
+ ;; Ensure TCO.
+ (declare (optimize (debug 0)))
+ (apply fun arglist))))
+ (format *debug-io*
+ "Can't restart ~S: no function for frame."
+ *current-frame*)))
(format *debug-io*
- "~@<can't find a tag for this frame ~
- ~2I~_(hint: try increasing the DEBUG optimization quality ~
- and recompiling)~:@>")))
+ "~@<Can't restart ~S: tag not found. ~
+ ~2I~_(hint: try increasing the DEBUG optimization quality ~
+ and recompiling)~:@>"
+ *current-frame*)))
(defun frame-has-debug-tag-p (frame)
#!+unwind-to-frame-and-call-vop