From 16fa00e83bc553a6436f0eac7ca9d8455f7763fa Mon Sep 17 00:00:00 2001 From: Alastair Bridgewater Date: Thu, 1 Dec 2011 17:03:26 -0500 Subject: [PATCH] Improved undefined-function backtrace on PPC. 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 | 3 +++ src/runtime/ppc-assem.S | 21 +++++++++++++++++---- tests/debug.impure.lisp | 6 +++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 7e22e95..ac2965b 100644 --- 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: diff --git a/src/runtime/ppc-assem.S b/src/runtime/ppc-assem.S index 3f0dd99..32ec912 100644 --- a/src/runtime/ppc-assem.S +++ b/src/runtime/ppc-assem.S @@ -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 diff --git a/tests/debug.impure.lisp b/tests/debug.impure.lisp index 08bbca3..d9de575 100644 --- a/tests/debug.impure.lisp +++ b/tests/debug.impure.lisp @@ -151,7 +151,11 @@ (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)) -- 1.7.10.4