;;;; -*- coding: utf-8; fill-column: 78 -*-
+changes relative to sbcl-1.0.46:
+ * bug fix: SB-DEBUG:BACKTRACE-AS-LIST guards against potentially leaking
+ stack-allocated values out of their dynamic-extent. (lp#310175)
+
changes in sbcl-1.0.46 relative to sbcl-1.0.45:
* enhancement: largefile support on Solaris.
* enhancement: SB-PROFILE:REPORT now supports :LIMIT and :PRINT-NO-CALL-LIST
(values))
(defun backtrace-as-list (&optional (count most-positive-fixnum))
- #!+sb-doc "Return a list representing the current BACKTRACE."
+ #!+sb-doc
+ "Return a list representing the current BACKTRACE.
+
+Objects in the backtrace with dynamic-extent allocation by the current
+thread are represented by substitutes to avoid references to them from
+leaking outside their legal extent."
(let ((reversed-result (list)))
(map-backtrace (lambda (frame)
- (push (frame-call-as-list frame) reversed-result))
+ (let ((frame-list (frame-call-as-list frame)))
+ (if (listp (cdr frame-list))
+ (push (mapcar #'replace-dynamic-extent-object frame-list)
+ reversed-result)
+ (push frame-list reversed-result))))
:count count)
(nreverse reversed-result)))
(defun frame-call-as-list (frame)
(multiple-value-bind (name args) (frame-call frame)
(cons name args)))
+
+(defun replace-dynamic-extent-object (obj)
+ (if (stack-allocated-p obj)
+ (make-unprintable-object
+ (handler-case
+ (format nil "dynamic-extent: ~S" obj)
+ (error ()
+ "error printing dynamic-extent object")))
+ obj))
+
+(defun stack-allocated-p (obj)
+ "Returns T if OBJ is allocated on the stack of the current
+thread, NIL otherwise."
+ (with-pinned-objects (obj)
+ (let ((sap (int-sap (get-lisp-obj-address obj))))
+ (when (sb!vm:control-stack-pointer-valid-p sap nil)
+ t))))
\f
;;;; frame printing
(load (compile-file "bug-414.lisp"))
(disassemble 'bug-414)))
+(with-test (:name :bug-310175)
+ (let ((dx-arg (cons t t)))
+ (declare (dynamic-extent dx-arg))
+ (flet ((dx-arg-backtrace (x)
+ (declare (optimize (debug 2)))
+ (prog1 (sb-debug:backtrace-as-list 10)
+ (assert (sb-debug::stack-allocated-p x)))))
+ (declare (notinline dx-arg-backtrace))
+ (assert (member-if (lambda (frame)
+ (and (consp frame)
+ (equal '(flet dx-arg-backtrace) (car frame))
+ (notany #'sb-debug::stack-allocated-p (cdr frame))))
+ (dx-arg-backtrace dx-arg))))))
+
;;;; test infinite error protection
(defmacro nest-errors (n-levels error-form)
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.46"
\ No newline at end of file
+"1.0.46.1"