then requesting a BACKTRACE at the debugger prompt gives no information
about where in the user program the problem occurred.
- (this is apparently mostly fixed on the SPARC and PPC architectures:
- while giving the backtrace the system complains about "unknown
+ (this is apparently mostly fixed on the SPARC, PPC, and x86 architectures:
+ while giving the backtrace the non-x86 systems complains about "unknown
source location: using block start", but apart from that the
- backtrace seems reasonable. See tests/debug.impure.lisp for a test
- case)
+ backtrace seems reasonable. On x86 this is masked by bug 353. See
+ tests/debug.impure.lisp for a test case)
64:
Using the pretty-printer from the command prompt gives funny
(Note: there's at least one dubious thing in room.lisp: see the
comment in VALID-OBJ)
-345: backtrace on x86 undefined function
- In sbcl-0.8.13 (and probably earlier versions), code of the form
- (flet ((test () (#:undefined-fun 42)))
- (funcall #'test))
- yields the debugger with a poorly-functioning backtrace. Brian
- Downing fixed most of the problems on non-x86 architectures, but on
- the x86 the backtrace from this evaluation does not reveal anything
- about the problem. (See tests in debug.impure.lisp)
-
346: alpha backtrace
In sbcl-0.8.13, all backtraces from errors caused by internal errors
on the alpha seem to have a "bogus stack frame".
While computing the class precedence list of the class named C.
The class named B is a forward referenced class.
The class named B is a direct superclass of the class named C.
+
+353: debugger suboptimalities on x86
+ On x86 backtraces for undefined functions start with a bogus stack
+ frame, and backtraces for throws to unknown catch tags with a "no
+ debug information" frame. These are both due to CODE-COMPONENT-FROM-BITS
+ (used on non-x86 platforms) being a more complete solution then what
+ is done on x86.
+
+ More generally, the debugger internals suffer from excessive x86/non-x86
+ conditionalization and OAOOMization: refactoring the common parts would
+ be good.
+
+354: XEPs in backtraces
+ Under default compilation policy
+ (defun test ()
+ (throw :unknown t))
+ (test)
+ Has the XEP for TEST in the backtrace, not the TEST frame itself.
+ (sparc and x86 at least)
supported. (thanks to Dan Debertin)
* fixed bug #331: structure-class instances corresponding to
DEFSTRUCT forms are now created eagerly.
+ * fixed bug #345: backtraces from calls to undefined functions work
+ on x86 as well. Related bug #61 is now also partially fixed on x86
+ (backtraces from throws to unknown catch tags.)
* bug fix: lambda-list parsing is now stricter vrt. order and number
of lambda-list keywords.
* fixed some bugs revealed by Paul Dietz' test suite:
"All DEBUG-CONDITIONs inherit from this type. These are serious conditions
that must be handled, but they are not programmer errors."))
-(define-condition no-debug-info (debug-condition)
- ((code-component :reader no-debug-info-code-component
- :initarg :code-component))
- #!+sb-doc
- (:documentation "There is no usable debugging information available.")
- (:report (lambda (condition stream)
- (fresh-line stream)
- (format stream
- "no debug information available for ~S~%"
- (no-debug-info-code-component condition)))))
-
(define-condition no-debug-fun-returns (debug-condition)
((debug-fun :reader no-debug-fun-returns-debug-fun
:initarg :debug-fun))
(multiple-value-bind (code pc-offset escaped) (find-escaped-frame caller)
(/noshow0 "at COND")
(cond (code
- (/noshow0 "in CODE clause")
;; If it's escaped it may be a function end breakpoint trap.
(when (and (code-component-p code)
(eq (%code-debug-info code) :bogus-lra))
code (1+ real-lra-slot)))
(setq code (code-header-ref code real-lra-slot))
(aver code)))
- (t
- (/noshow0 "in T clause")
- ;; not escaped
+ ((not escaped)
(multiple-value-setq (pc-offset code)
(compute-lra-data-from-pc ra))
(unless code
(setf code :foreign-function
- pc-offset 0
- escaped nil))))
-
+ pc-offset 0))))
(let ((d-fun (case code
(:undefined-function
(make-bogus-debug-fun
(defun debug-fun-from-pc (component pc)
(let ((info (%code-debug-info component)))
(cond
- ((not info)
- (debug-signal 'no-debug-info :code-component component))
+ ((not info)
+ ;; FIXME: It seems that most of these (at least on x86) are
+ ;; actually assembler routines, and could be named by looking
+ ;; at the sb-fasl:*assembler-routines*.
+ (make-bogus-debug-fun "no debug information for frame"))
((eq info :bogus-lra)
(make-bogus-debug-fun "function end breakpoint"))
(t
.align align_4byte,0x90
.global GNAME(undefined_tramp)
.type GNAME(undefined_tramp),@function
+ .byte 0, 0, 0, SIMPLE_FUN_HEADER_WIDETAG
GNAME(undefined_tramp):
int3
.byte trap_Error
.align align_4byte,0x90
.global GNAME(closure_tramp)
.type GNAME(closure_tramp),@function
+ .byte 0, 0, 0, SIMPLE_FUN_HEADER_WIDETAG
GNAME(closure_tramp):
movl FDEFN_FUN_OFFSET(%eax),%eax
/* FIXME: The '*' after "jmp" in the next line is from PVE's
(let ((backtrace (ignore-errors
(sb-debug:backtrace-as-list))))
;; Make sure we find what we're looking for.
- (when (member frame-name backtrace
- :key key :test test)
- (setf result (list :error condition)))
+ (if (member frame-name backtrace :key key :test test)
+ (setf result (list :error condition))
+ (print (list :failed :frame frame-name :backtrace backtrace)))
;; Make sure there's no bogus stack frames
;; unless they're explicitly allowed.
(when (and (not allow-bogus-frames)
(member "bogus stack frame" backtrace
:key #'first :test #'equal))
+ (print 'verify-backtrace-bogus)
(setf result nil))
;; Make sure the backtrace isn't stunted in
;; any way. (Depends on running in the main
;; thread.)
(unless (member 'sb-impl::toplevel-init backtrace
:key #'first :test #'equal)
+ (print 'verify-backtrace-stunted)
(setf result nil)))
(return-from outer-handler))))
(funcall test-function)))
;;; Try it with and without tail call elimination, since they can have
;;; different effects. (Specifically, if undefined_tramp is incorrect
;;; a stunted stack can result from the tail call variant.)
-#-(or alpha x86) ; bug 345
-(progn
- (flet ((test-function ()
- (declare (optimize (speed 2) (debug 1))) ; tail call elimination
- (#:undefined-function 42)))
- (assert (verify-backtrace #'test-function "undefined function"
- :test #'equal)))
-
- (flet ((test-function ()
- (declare (optimize (speed 1) (debug 2))) ; no tail call elimination
- (#:undefined-function 42)))
- (assert (verify-backtrace #'test-function "undefined function"
- :test #'equal))))
+#-(or alpha) ; bug 346
+(flet ((optimized ()
+ (declare (optimize (speed 2) (debug 1))) ; tail call elimination
+ (#:undefined-function 42))
+ (not-optimized ()
+ (declare (optimize (speed 1) (debug 2))) ; no tail call elimination
+ (#:undefined-function 42))
+ (test (fun)
+ (declare (optimize (speed 1) (debug 2))) ; no tail call elimination
+ (funcall fun)))
+ (dolist (frame '(#-x86 "undefined function" ; bug 353
+ "FLET COMMON-LISP-USER::TEST"))
+ (assert (verify-backtrace (lambda () (test #'optimized)) frame
+ :test #'equal
+ :allow-bogus-frames (or #+x86 t))))
+ (dolist (frame '(#-x86 "undefined function" ; bug 353
+ "FLET COMMON-LISP-USER::NOT-OPTIMIZED"
+ "FLET COMMON-LISP-USER::TEST"))
+ (assert (verify-backtrace (lambda () (test #'not-optimized)) frame
+ :test #'equal
+ :allow-bogus-frames (or #+x86 t)))))
;;; Division by zero was a common error on PPC. It depended on the
;;; return function either being before INTEGER-/-INTEGER in memory,
(/ 42 0)))
(assert (verify-backtrace #'test-function '/))))
-#-(or x86 alpha) ; bug 61
+#-(or alpha) ; bug 61
(progn
(defun throw-test ()
(throw 'no-such-tag t))
- (assert (verify-backtrace #'throw-test 'throw-test)))
+ (assert (verify-backtrace #'throw-test
+ #-(or x86 sparc) 'throw-test
+ #+(or x86 sparc) "XEP for COMMON-LISP-USER::THROW-TEST" ; bug 354
+ :test #'equal)))
;;; success
(quit :unix-status 104)
;;; 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".)
-"0.8.17.7"
+"0.8.17.8"