0.8.17.8: x86 backtraces
authorNikodemus Siivola <nikodemus@random-state.net>
Wed, 1 Dec 2004 14:14:23 +0000 (14:14 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Wed, 1 Dec 2004 14:14:23 +0000 (14:14 +0000)
           * fixed bug #345: don't set the escaped flag to NIL on x86
              in COMPUTE-CALLING FRAME if we have no code from
              FIND-ESCAPED-FRAME. Add tag-bytes to undefined_tramp and
              closure_tramp on x86 like others.
           * partial fix for #61: instead of throwing no-debug-info
              conditions, return a "no debug information for frame"
              bogus-debug-fun from debug-fun-from-pc.
           * Two new BUGS entries about backtraces.
           * Tests. (debug.impure.lisp now passes on sparc as well,
              but only because one test now axxepts the XEP in lieu of
              the function on sparc and x86.

BUGS
NEWS
src/code/debug-int.lisp
src/runtime/x86-assem.S
tests/debug.impure.lisp
version.lisp-expr

diff --git a/BUGS b/BUGS
index 729da42..d5271f0 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -167,11 +167,11 @@ WORKAROUND:
   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
@@ -1529,15 +1529,6 @@ WORKAROUND:
   (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".
@@ -1578,3 +1569,22 @@ WORKAROUND:
         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)
diff --git a/NEWS b/NEWS
index bdc5339..3aabb52 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ changes in sbcl-0.8.18 relative to sbcl-0.8.17:
     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:
index 67d0a59..9964063 100644 (file)
    "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
@@ -1041,8 +1025,11 @@ register."
 (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
index 3dfb53b..d512676 100644 (file)
@@ -286,6 +286,7 @@ GNAME(fpu_restore):
        .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
@@ -302,6 +303,7 @@ GNAME(undefined_tramp):
        .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
index a1d1e19..5301d5a 100644 (file)
                       (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)
index 349c154..7c55463 100644 (file)
@@ -17,4 +17,4 @@
 ;;; 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"