Improved undefined-function backtrace on PPC.
authorAlastair Bridgewater <nyef@arisu.lisphacker.com>
Thu, 1 Dec 2011 22:03:26 +0000 (17:03 -0500)
committerAlastair Bridgewater <nyef@arisu.lisphacker.com>
Mon, 5 Dec 2011 22:58:25 +0000 (17:58 -0500)
When there is an existing stack frame (either for a large number
of arguments or for a tail-call), undefined_tramp triggers a
strange case in build_fake_control_stack_frames() that can leave
the OCFP and LRA slots uninitialized, causing a truncated
backtrace.

  * Alter undefined_tramp to always allocate and initialize a
stack frame.

  * While we're here, tighten up the reg_CODE initialization
sequence.

NEWS
src/runtime/ppc-assem.S
tests/debug.impure.lisp

diff --git a/NEWS b/NEWS
index 7e22e95..ac2965b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -55,6 +55,9 @@ changes relative to sbcl-1.0.54:
     unknown type no longer causes a style-warning. (lp#806243)
   * bug fix: undefined functions now appear in backtraces as ("undefined
     function") instead of ("bogus stack frame") on non-x86oids.
+  * bug fix: backtraces are no longer cut off at ("undefined function") when
+    called under certain circumstances (involving a caller-allocated stack
+    frame) on PPC.
 
 changes in sbcl-1.0.54 relative to sbcl-1.0.53:
   * minor incompatible changes:
index 3f0dd99..32ec912 100644 (file)
@@ -605,10 +605,23 @@ CSYMBOL(undefined_tramp):
        /* Point reg_CODE to the header and tag it as function, since
           the debugger regards a function pointer in reg_CODE which
           doesn't point to a code object as undefined function.  */
-       bcl 20,31,.+4                  /* get address of the next instruction */
-       mflr reg_CODE                  /* header 1 extra word back from here */
-       addi reg_CODE,reg_CODE,-(SIMPLE_FUN_CODE_OFFSET+4)
-       
+       /* We are given that reg_LIP points to undefined_tramp by
+          virtue of the calling convention.  */
+       addi reg_CODE,reg_LIP,-SIMPLE_FUN_CODE_OFFSET
+
+       /* If we are called with stack arguments (or in a tail-call
+          scenario), we end up with an allocated stack frame, but the
+          frame link information is uninitialized.  Fix things by
+          allocating and initializing our stack frame "properly". */
+       cmpwi cr0,reg_NARGS,16
+       bt gt,1f
+       addi reg_CSP,reg_CFP,16
+       b 2f
+1:     add reg_CSP,reg_CFP,reg_NARGS
+2:     stw reg_OCFP,0(reg_CFP)
+       stw reg_LRA,4(reg_CFP)
+
+       /* Now that the preliminaries are dealt with, actually trap. */
        twllei reg_ZERO,trap_Cerror
        .byte 4
        .byte UNDEFINED_FUN_ERROR
index 08bbca3..d9de575 100644 (file)
          (funcall fun)))
 
   (with-test (:name (:undefined-function :bug-346)
-              :fails-on '(or :alpha :ppc :sparc :mips
+                    ;; Failures on ALPHA, SPARC, MIPS, and probably
+                    ;; HPPA are due to not having a full and valid
+                    ;; stack frame for the undefined function frame.
+                    ;; See PPC undefined_tramp for details.
+              :fails-on '(or :alpha :sparc :mips
                           (and :x86-64 :freebsd)))
     (assert (verify-backtrace
              (lambda () (test #'optimized))