+(declaim (unsigned-byte *backtrace-frame-count*))
+(defvar *backtrace-frame-count* 1000
+ "Default number of frames to backtrace. Defaults to 1000.")
+
+(declaim (type (member :minimal :normal :full) *method-frame-style*))
+(defvar *method-frame-style* :normal
+ "Determines how frames corresponding to method functions are represented in
+backtraces. Possible values are :MINIMAL, :NORMAL, and :FULL.
+
+ :MINIMAL represents them as
+
+ (<gf-name> ...args...)
+
+ if all arguments are available, and only a single method is applicable to
+ the arguments -- otherwise behaves as :NORMAL.
+
+ :NORMAL represents them as
+
+ ((:method <gf-name> [<qualifier>*] (<specializer>*)) ...args...)
+
+ The frame is then followed by either [fast-method] or [slow-method],
+ designating the kind of method function. (See below.)
+
+ :FULL represents them using the actual funcallable method function name:
+
+ ((sb-pcl:fast-method <gf-name> [<qualifier>*] (<specializer>*)) ...args...)
+
+ or
+
+ ((sb-pcl:slow-method <gf-name> [<qualifier>*] (<specializer>*)) ...args...)
+
+ In the this case arguments may include values internal to SBCL's method
+ dispatch machinery.")
+
+(define-deprecated-variable :early "1.1.4.9" *show-entry-point-details*
+ :value nil)
+
+(defun backtrace (&optional (count *backtrace-frame-count*) (stream *debug-io*))
+ "Replaced by PRINT-BACKTRACE, will eventually be deprecated."
+ (print-backtrace :count count :stream stream))
+
+(defun backtrace-as-list (&optional (count *backtrace-frame-count*))
+ "Replaced by LIST-BACKTRACE, will eventually be deprecated."
+ (list-backtrace :count count))
+
+(defun backtrace-start-frame (frame-designator)
+ (let ((here (sb!di:top-frame)))
+ (labels ((current-frame ()
+ (let ((frame here))
+ ;; Our caller's caller.
+ (loop repeat 2
+ do (setf frame (or (sb!di:frame-down frame) frame)))
+ frame))
+ (interrupted-frame ()
+ (or (nth-value 1 (find-interrupted-name-and-frame))
+ (current-frame))))
+ (cond ((eq :current-frame frame-designator)
+ (current-frame))
+ ((eq :interrupted-frame frame-designator)
+ (interrupted-frame))
+ ((eq :debugger-frame frame-designator)
+ (if (and *in-the-debugger* *current-frame*)
+ *current-frame*
+ (interrupted-frame)))
+ ((sb!di:frame-p frame-designator)
+ frame-designator)
+ (t
+ (error "Invalid designator for initial backtrace frame: ~S"
+ frame-designator))))))
+
+(defun map-backtrace (function &key
+ (start 0)
+ (from :debugger-frame)
+ (count *backtrace-frame-count*))
+ #!+sb-doc
+ "Calls the designated FUNCTION with each frame on the call stack.
+Returns the last value returned by FUNCTION.
+
+COUNT is the number of frames to backtrace, defaulting to
+*BACKTRACE-FRAME-COUNT*.
+
+START is the number of the frame the backtrace should start from.
+
+FROM specifies the frame relative to which the frames are numbered. Possible
+values are an explicit SB-DI:FRAME object, and the
+keywords :CURRENT-FRAME, :INTERRUPTED-FRAME, and :DEBUGGER-FRAME. Default
+is :DEBUGGER-FRAME.
+
+ :CURRENT-FRAME
+ specifies the caller of MAP-BACKTRACE.
+
+ :INTERRUPTED-FRAME
+ specifies the first interrupted frame on the stack \(typically the frame
+ where the error occured, as opposed to error handling frames) if any,
+ otherwise behaving as :CURRENT-FRAME.
+
+ :DEBUGGER-FRAME
+ specifies the currently debugged frame when inside the debugger, and
+ behaves as :INTERRUPTED-FRAME outside the debugger.
+"
+ (loop with result = nil
+ for index upfrom 0
+ for frame = (backtrace-start-frame from)
+ then (sb!di:frame-down frame)
+ until (null frame)
+ when (<= start index) do
+ (if (minusp (decf count))
+ (return result)
+ (setf result (funcall function frame)))
+ finally (return result)))
+
+(defun print-backtrace (&key
+ (stream *debug-io*)
+ (start 0)
+ (from :debugger-frame)
+ (count *backtrace-frame-count*)
+ (print-thread t)
+ (print-frame-source nil)
+ (method-frame-style *method-frame-style*))