"If the trace indentation exceeds this value, then indentation restarts at
0.")
-(defvar *trace-encapsulate-default* :default
+(defvar *trace-encapsulate-default* t
#+sb-doc
"the default value for the :ENCAPSULATE option to TRACE")
\f
;;;; internal state
;;; a hash table that maps each traced function to the TRACE-INFO. The
-;;; entry for a closure is the shared function-entry object.
-(defvar *traced-functions* (make-hash-table :test 'eq))
+;;; entry for a closure is the shared function entry object.
+(defvar *traced-funs* (make-hash-table :test 'eq))
;;; A TRACE-INFO object represents all the information we need to
;;; trace a given function.
(defun trace-redefined-update (fname new-value)
(when (fboundp fname)
(let* ((fun (trace-fdefinition fname))
- (info (gethash fun *traced-functions*)))
+ (info (gethash fun *traced-funs*)))
(when (and info (trace-info-named info))
(untrace-1 fname)
(trace-1 fname info new-value)))))
(let ((exp (car form)))
(if (sb-di:code-location-p loc)
(let ((fun (sb-di:preprocess-for-eval exp loc)))
+ (declare (type function fun))
(cons exp
(lambda (frame)
(let ((*current-frame* frame))
((nil) exp)
(:encapsulated
`(flet ((sb-debug:arg (n)
- (declare (special argument-list))
- (elt argument-list n)))
+ (declare (special arg-list))
+ (elt arg-list n)))
(declare (ignorable #'sb-debug:arg))
,exp))))
(fun (coerce `(lambda () ,bod) 'function)))
(dolist (entry *traced-entries*)
(when (cdr entry) (incf depth)))
(format t
- "~@V,0T~W: "
+ "~V,0@T~W: "
(+ (mod (* depth *trace-indentation-step*)
(- *max-trace-indentation* *trace-indentation-step*))
*trace-indentation-step*)
(or (not wherein)
(trace-wherein-p frame wherein)))))
(when conditionp
- (let ((sb-kernel:*current-level* 0)
- (*standard-output* *trace-output*)
+ (let ((sb-kernel:*current-level-in-print* 0)
+ (*standard-output* (make-string-output-stream))
(*in-trace* t))
(fresh-line)
(print-trace-indentation)
(if (trace-info-encapsulated info)
- (locally (declare (special basic-definition argument-list))
- (prin1 `(,(trace-info-what info) ,@argument-list)))
+ ;; FIXME: These special variables should be given
+ ;; *FOO*-style names, and probably declared globally
+ ;; with DEFVAR.
+ (locally
+ (declare (special basic-definition arg-list))
+ (prin1 `(,(trace-info-what info) ,@arg-list)))
(print-frame-call frame))
(terpri)
- (trace-print frame (trace-info-print info)))
+ (trace-print frame (trace-info-print info))
+ (write-sequence (get-output-stream-string *standard-output*)
+ *trace-output*))
(trace-maybe-break info (trace-info-break info) "before" frame)))
(lambda (frame cookie)
;;; to determine the correct indentation for output. We then check to
;;; see whether the function is still traced and that the condition
;;; succeeded before printing anything.
+(declaim (ftype (function (trace-info) function) trace-end-breakpoint-fun))
(defun trace-end-breakpoint-fun (info)
(lambda (frame bpt *trace-values* cookie)
(declare (ignore bpt))
(or (cdr entry)
(let ((cond (trace-info-condition-after info)))
(and cond (funcall (cdr cond) frame)))))
- (let ((sb-kernel:*current-level* 0)
- (*standard-output* *trace-output*)
+ (let ((sb-kernel:*current-level-in-print* 0)
+ (*standard-output* (make-string-output-stream))
(*in-trace* t))
(fresh-line)
(pprint-logical-block (*standard-output* nil)
(pprint-newline :linear)
(prin1 v)))
(terpri)
- (trace-print frame (trace-info-print-after info)))
+ (trace-print frame (trace-info-print-after info))
+ (write-sequence (get-output-stream-string *standard-output*)
+ *trace-output*))
(trace-maybe-break info
(trace-info-break-after info)
"after"
;;; which we have cleverly contrived to work for our hook functions.
(defun trace-call (info)
(multiple-value-bind (start cookie) (trace-start-breakpoint-fun info)
+ (declare (type function start cookie))
(let ((frame (sb-di:frame-down (sb-di:top-frame))))
(funcall start frame nil)
(let ((*traced-entries* *traced-entries*))
- (declare (special basic-definition argument-list))
+ (declare (special basic-definition arg-list))
(funcall cookie frame nil)
(let ((vals
(multiple-value-list
- (apply basic-definition argument-list))))
+ (apply basic-definition arg-list))))
(funcall (trace-end-breakpoint-fun info) frame nil vals nil)
(values-list vals))))))
\f
(values definition t
(nth-value 2 (trace-fdefinition definition)))
(trace-fdefinition function-or-name))
- (when (gethash fun *traced-functions*)
+ (when (gethash fun *traced-funs*)
(warn "~S is already TRACE'd, untracing it." function-or-name)
(untrace-1 fun))
(sb-di:activate-breakpoint start)
(sb-di:activate-breakpoint end)))))
- (setf (gethash fun *traced-functions*) info)))
+ (setf (gethash fun *traced-funs*) info)))
function-or-name)
\f
`(let ,(binds) (list ,@(forms)))
`(list ,@(forms)))))
-(defun %list-traced-functions ()
- (loop for x being each hash-value in *traced-functions*
+(defun %list-traced-funs ()
+ (loop for x being each hash-value in *traced-funs*
collect (trace-info-what x)))
(defmacro trace (&rest specs)
-AFTER and -ALL forms are evaluated in the null environment."
(if specs
(expand-trace specs)
- '(%list-traced-functions)))
+ '(%list-traced-funs)))
\f
;;;; untracing
;;; Untrace one function.
(defun untrace-1 (function-or-name)
(let* ((fun (trace-fdefinition function-or-name))
- (info (gethash fun *traced-functions*)))
+ (info (gethash fun *traced-funs*)))
(cond
((not info)
(warn "Function is not TRACEd: ~S" function-or-name))
(sb-di:delete-breakpoint (trace-info-start-breakpoint info))
(sb-di:delete-breakpoint (trace-info-end-breakpoint info))))
(setf (trace-info-untraced info) t)
- (remhash fun *traced-functions*)))))
+ (remhash fun *traced-funs*)))))
;;; Untrace all traced functions.
(defun untrace-all ()
- (dolist (fun (%list-traced-functions))
+ (dolist (fun (%list-traced-funs))
(untrace-1 fun))
t)