X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fdebug-int.lisp;h=d05a3dab8a10234ffdc0eeebc138915fce58ace7;hb=b3f188843330c56bd4d17a3c930e73f573b1c71f;hp=071a476058eb2e0be6c081e288622f9fd6d4649b;hpb=8b89077f2d8c3aec140ded650d95d7869f6a7f28;p=sbcl.git diff --git a/src/code/debug-int.lisp b/src/code/debug-int.lisp index 071a476..d05a3da 100644 --- a/src/code/debug-int.lisp +++ b/src/code/debug-int.lisp @@ -394,15 +394,15 @@ (breakpoint-data-offset obj)))) (defstruct (breakpoint (:constructor %make-breakpoint - (hook-function what kind %info)) + (hook-fun what kind %info)) (:copier nil)) ;; This is the function invoked when execution encounters the ;; breakpoint. It takes a frame, the breakpoint, and optionally a - ;; list of values. Values are supplied for :FUN-END breakpoints - ;; as values to return for the function containing the breakpoint. - ;; :FUN-END breakpoint hook-functions also take a cookie - ;; argument. See COOKIE-FUN slot. - (hook-function nil :type function) + ;; list of values. Values are supplied for :FUN-END breakpoints as + ;; values to return for the function containing the breakpoint. + ;; :FUN-END breakpoint hook functions also take a cookie argument. + ;; See the COOKIE-FUN slot. + (hook-fun (required-arg) :type function) ;; CODE-LOCATION or DEBUG-FUN (what nil :type (or code-location debug-fun)) ;; :CODE-LOCATION, :FUN-START, or :FUN-END for that kind @@ -431,7 +431,7 @@ ;; for identifying :FUN-END breakpoint executions. That is, if ;; there is one :FUN-END breakpoint, but there may be multiple ;; pending calls of its function on the stack. This function takes - ;; the cookie, and the hook-function takes the cookie too. + ;; the cookie, and the hook function takes the cookie too. (cookie-fun nil :type (or null function)) ;; This slot users can set with whatever information they find useful. %info) @@ -507,7 +507,7 @@ ;;;; frames ;;; This is used in FIND-ESCAPED-FRAME and with the bogus components -;;; and LRAs used for :FUN-END breakpoints. When a components +;;; and LRAs used for :FUN-END breakpoints. When a component's ;;; debug-info slot is :BOGUS-LRA, then the REAL-LRA-SLOT contains the ;;; real component to continue executing, as opposed to the bogus ;;; component which appeared in some frame's LRA location. @@ -524,18 +524,23 @@ (defun get-lisp-obj-address (thing) (get-lisp-obj-address thing)) (defun fun-word-offset (fun) (fun-word-offset fun)) -#!-sb-fluid (declaim (inline cstack-pointer-valid-p)) -(defun cstack-pointer-valid-p (x) +#!-sb-fluid (declaim (inline control-stack-pointer-valid-p)) +(defun control-stack-pointer-valid-p (x) (declare (type system-area-pointer x)) - #!-x86 ; stack grows toward high address values - (and (sap< x (current-sp)) - (sap<= (int-sap control-stack-start) - x) - (zerop (logand (sap-int x) #b11))) - #!+x86 ; stack grows toward low address values - (and (sap>= x (current-sp)) - (sap> (int-sap control-stack-end) x) - (zerop (logand (sap-int x) #b11)))) + (let* (#!-stack-grows-downward-not-upward + (control-stack-start + (descriptor-sap *control-stack-start*)) + #!+stack-grows-downward-not-upward + (control-stack-end + (descriptor-sap *control-stack-end*))) + #!-stack-grows-downward-not-upward + (and (sap< x (current-sp)) + (sap<= control-stack-start x) + (zerop (logand (sap-int x) #b11))) + #!+stack-grows-downward-not-upward + (and (sap>= x (current-sp)) + (sap> control-stack-end x) + (zerop (logand (sap-int x) #b11))))) #!+x86 (sb!alien:define-alien-routine component-ptr-from-pc (system-area-pointer) @@ -575,10 +580,13 @@ (defun ra-pointer-valid-p (ra) (declare (type system-area-pointer ra)) (and - ;; Not the first page which is unmapped. + ;; not the first page (which is unmapped) + ;; + ;; FIXME: Where is this documented? Is it really true of every CPU + ;; architecture? Is it even necessarily true in current SBCL? (>= (sap-int ra) 4096) - ;; Not a Lisp stack pointer. - (not (cstack-pointer-valid-p ra)))) + ;; not a Lisp stack pointer + (not (control-stack-pointer-valid-p ra)))) ;;; Try to find a valid previous stack. This is complex on the x86 as ;;; it can jump between C and Lisp frames. To help find a valid frame @@ -594,7 +602,7 @@ (fixnum depth)) ;;(format t "*CC ~S ~S~%" fp depth) (cond - ((not (cstack-pointer-valid-p fp)) + ((not (control-stack-pointer-valid-p fp)) #+nil (format t "debug invalid fp ~S~%" fp) nil) (t @@ -604,9 +612,9 @@ 4)))) (c-ocfp (sap-ref-sap fp (* 0 sb!vm:n-word-bytes))) (c-ra (sap-ref-sap fp (* 1 sb!vm:n-word-bytes)))) - (cond ((and (sap> lisp-ocfp fp) (cstack-pointer-valid-p lisp-ocfp) + (cond ((and (sap> lisp-ocfp fp) (control-stack-pointer-valid-p lisp-ocfp) (ra-pointer-valid-p lisp-ra) - (sap> c-ocfp fp) (cstack-pointer-valid-p c-ocfp) + (sap> c-ocfp fp) (control-stack-pointer-valid-p c-ocfp) (ra-pointer-valid-p c-ra)) #+nil (format t "*C Both valid ~S ~S ~S ~S~%" @@ -621,11 +629,11 @@ (format t "debug: both still valid ~S ~S ~S ~S~%" lisp-ocfp lisp-ra c-ocfp c-ra)) - #+freebsd + #!+freebsd (if (sap> lisp-ocfp c-ocfp) (values lisp-ra lisp-ocfp) (values c-ra c-ocfp)) - #-freebsd + #!-freebsd (values lisp-ra lisp-ocfp)) (lisp-path-fp ;; The lisp convention is looking good. @@ -640,12 +648,12 @@ #+nil (format t "debug: no valid2 fp found ~S ~S~%" lisp-ocfp c-ocfp) nil)))) - ((and (sap> lisp-ocfp fp) (cstack-pointer-valid-p lisp-ocfp) + ((and (sap> lisp-ocfp fp) (control-stack-pointer-valid-p lisp-ocfp) (ra-pointer-valid-p lisp-ra)) ;; The lisp convention is looking good. #+nil (format t "*C lisp-ocfp ~S ~S~%" lisp-ocfp lisp-ra) (values lisp-ra lisp-ocfp)) - ((and (sap> c-ocfp fp) (cstack-pointer-valid-p c-ocfp) + ((and (sap> c-ocfp fp) (control-stack-pointer-valid-p c-ocfp) #!-linux (ra-pointer-valid-p c-ra)) ;; The C convention is looking good. #+nil (format t "*C c-ocfp ~S ~S~%" c-ocfp c-ra) @@ -705,10 +713,10 @@ frame))) (bogus-debug-fun (let ((fp (frame-pointer frame))) - (when (cstack-pointer-valid-p fp) + (when (control-stack-pointer-valid-p fp) #!+x86 (multiple-value-bind (ra ofp) (x86-call-context fp) - (compute-calling-frame ofp ra frame)) + (and ra (compute-calling-frame ofp ra frame))) #!-x86 (compute-calling-frame #!-alpha @@ -791,7 +799,7 @@ #!-x86 (defun compute-calling-frame (caller lra up-frame) (declare (type system-area-pointer caller)) - (when (cstack-pointer-valid-p caller) + (when (control-stack-pointer-valid-p caller) (multiple-value-bind (code pc-offset escaped) (if lra (multiple-value-bind (word-offset code) @@ -820,7 +828,7 @@ "undefined function")) (:foreign-function (make-bogus-debug-fun - "foreign function call land")) + (format nil "foreign function call land:"))) ((nil) (make-bogus-debug-fun "bogus stack frame")) @@ -835,7 +843,7 @@ (defun compute-calling-frame (caller ra up-frame) (declare (type system-area-pointer caller ra)) (/noshow0 "entering COMPUTE-CALLING-FRAME") - (when (cstack-pointer-valid-p caller) + (when (control-stack-pointer-valid-p caller) (/noshow0 "in WHEN") ;; First check for an escaped frame. (multiple-value-bind (code pc-offset escaped) (find-escaped-frame caller) @@ -866,7 +874,8 @@ "undefined function")) (:foreign-function (make-bogus-debug-fun - "foreign function call land")) + (format nil "foreign function call land: ra=#x~X" + (sap-int ra)))) ((nil) (make-bogus-debug-fun "bogus stack frame")) @@ -879,15 +888,20 @@ (if up-frame (1+ (frame-number up-frame)) 0) escaped))))) +(defun nth-interrupt-context (n) + (declare (type (unsigned-byte 32) n) + (optimize (speed 3) (safety 0))) + (sb!alien:sap-alien (sb!vm::current-thread-offset-sap + (+ sb!vm::thread-interrupt-contexts-offset n)) + (* os-context-t))) + #!+x86 (defun find-escaped-frame (frame-pointer) (declare (type system-area-pointer frame-pointer)) (/noshow0 "entering FIND-ESCAPED-FRAME") (dotimes (index *free-interrupt-context-index* (values nil 0 nil)) - (sb!alien:with-alien - ((lisp-interrupt-contexts (array (* os-context-t) nil) :extern)) (/noshow0 "at head of WITH-ALIEN") - (let ((context (sb!alien:deref lisp-interrupt-contexts index))) + (let ((context (nth-interrupt-context index))) (/noshow0 "got CONTEXT") (when (= (sap-int frame-pointer) (sb!vm:context-register context sb!vm::cfp-offset)) @@ -919,51 +933,49 @@ pc-offset code)) (/noshow0 "returning from FIND-ESCAPED-FRAME") (return - (values code pc-offset context)))))))))) + (values code pc-offset context))))))))) #!-x86 (defun find-escaped-frame (frame-pointer) (declare (type system-area-pointer frame-pointer)) (dotimes (index *free-interrupt-context-index* (values nil 0 nil)) - (sb!alien:with-alien - ((lisp-interrupt-contexts (array (* os-context-t) nil) :extern)) - (let ((scp (sb!alien:deref lisp-interrupt-contexts index))) - (when (= (sap-int frame-pointer) - (sb!vm:context-register scp sb!vm::cfp-offset)) - (without-gcing - (let ((code (code-object-from-bits - (sb!vm:context-register scp sb!vm::code-offset)))) - (when (symbolp code) - (return (values code 0 scp))) - (let* ((code-header-len (* (get-header-data code) - sb!vm:n-word-bytes)) - (pc-offset + (let ((scp (nth-interrupt-context index))) + (when (= (sap-int frame-pointer) + (sb!vm:context-register scp sb!vm::cfp-offset)) + (without-gcing + (let ((code (code-object-from-bits + (sb!vm:context-register scp sb!vm::code-offset)))) + (when (symbolp code) + (return (values code 0 scp))) + (let* ((code-header-len (* (get-header-data code) + sb!vm:n-word-bytes)) + (pc-offset (- (sap-int (sb!vm:context-pc scp)) (- (get-lisp-obj-address code) sb!vm:other-pointer-lowtag) code-header-len))) - ;; Check to see whether we were executing in a branch - ;; delay slot. - #!+(or pmax sgi) ; pmax only (and broken anyway) - (when (logbitp 31 (sb!alien:slot scp '%mips::sc-cause)) - (incf pc-offset sb!vm:n-word-bytes)) - (unless (<= 0 pc-offset - (* (code-header-ref code sb!vm:code-code-size-slot) - sb!vm:n-word-bytes)) - ;; We were in an assembly routine. Therefore, use the - ;; LRA as the pc. - (setf pc-offset - (- (sb!vm:context-register scp sb!vm::lra-offset) - (get-lisp-obj-address code) - code-header-len))) - (return - (if (eq (%code-debug-info code) :bogus-lra) - (let ((real-lra (code-header-ref code - real-lra-slot))) - (values (lra-code-header real-lra) - (get-header-data real-lra) - nil)) - (values code pc-offset scp))))))))))) + ;; Check to see whether we were executing in a branch + ;; delay slot. + #!+(or pmax sgi) ; pmax only (and broken anyway) + (when (logbitp 31 (sb!alien:slot scp '%mips::sc-cause)) + (incf pc-offset sb!vm:n-word-bytes)) + (unless (<= 0 pc-offset + (* (code-header-ref code sb!vm:code-code-size-slot) + sb!vm:n-word-bytes)) + ;; We were in an assembly routine. Therefore, use the + ;; LRA as the pc. + (setf pc-offset + (- (sb!vm:context-register scp sb!vm::lra-offset) + (get-lisp-obj-address code) + code-header-len))) + (return + (if (eq (%code-debug-info code) :bogus-lra) + (let ((real-lra (code-header-ref code + real-lra-slot))) + (values (lra-code-header real-lra) + (get-header-data real-lra) + nil)) + (values code pc-offset scp)))))))))) ;;; Find the code object corresponding to the object represented by ;;; bits and return it. We assume bogus functions correspond to the @@ -1123,8 +1135,7 @@ ;;; nil). This may iterate over only some of DEBUG-FUN's variables or ;;; none depending on debug policy; for example, possibly the ;;; compilation only preserved argument information. -(defmacro do-debug-fun-variables ((var debug-fun &optional result) - &body body) +(defmacro do-debug-fun-vars ((var debug-fun &optional result) &body body) (let ((vars (gensym)) (i (gensym))) `(let ((,vars (debug-fun-debug-vars ,debug-fun))) @@ -1179,8 +1190,7 @@ (fun-debug-fun (%closure-fun fun))) (#.sb!vm:funcallable-instance-header-widetag (fun-debug-fun (funcallable-instance-fun fun))) - ((#.sb!vm:simple-fun-header-widetag - #.sb!vm:closure-fun-header-widetag) + (#.sb!vm:simple-fun-header-widetag (let* ((name (%simple-fun-name fun)) (component (fun-code-header fun)) (res (find-if @@ -1227,7 +1237,7 @@ ;;; as symbol. The result of this function is limited to the ;;; availability of variable information in DEBUG-FUN; for ;;; example, possibly DEBUG-FUN only knows about its arguments. -(defun debug-fun-symbol-variables (debug-fun symbol) +(defun debug-fun-symbol-vars (debug-fun symbol) (let ((vars (ambiguous-debug-vars debug-fun (symbol-name symbol))) (package (and (symbol-package symbol) (package-name (symbol-package symbol))))) @@ -1252,7 +1262,7 @@ (if variables (let* ((len (length variables)) (prefix-len (length name-prefix-string)) - (pos (find-variable name-prefix-string variables len)) + (pos (find-var name-prefix-string variables len)) (res nil)) (when pos ;; Find names from pos to variable's len that contain prefix. @@ -1271,19 +1281,19 @@ (setq res (nreverse res))) res)))) -;;; This returns a position in variables for one containing name as an -;;; initial substring. End is the length of variables if supplied. -(defun find-variable (name variables &optional end) +;;; This returns a position in VARIABLES for one containing NAME as an +;;; initial substring. END is the length of VARIABLES if supplied. +(defun find-var (name variables &optional end) (declare (simple-vector variables) (simple-string name)) (let ((name-len (length name))) (position name variables - :test #'(lambda (x y) - (let* ((y (debug-var-symbol-name y)) - (y-len (length y))) - (declare (simple-string y)) - (and (>= y-len name-len) - (string= x y :end1 name-len :end2 name-len)))) + :test (lambda (x y) + (let* ((y (debug-var-symbol-name y)) + (y-len (length y))) + (declare (simple-string y)) + (and (>= y-len name-len) + (string= x y :end1 name-len :end2 name-len)))) :end (or end (length variables))))) ;;; Return a list representing the lambda-list for DEBUG-FUN. The @@ -1511,19 +1521,18 @@ (list successors)) (dotimes (k (ldb sb!c::compiled-debug-block-nsucc-byte succ-and-flags)) - (push (sb!c::read-var-integer blocks i) successors)) + (push (sb!c:read-var-integer blocks i) successors)) (let* ((locations - (dotimes (k (sb!c::read-var-integer blocks i) + (dotimes (k (sb!c:read-var-integer blocks i) (result locations-buffer)) (let ((kind (svref sb!c::*compiled-code-location-kinds* (aref+ blocks i))) (pc (+ last-pc - (sb!c::read-var-integer blocks i))) + (sb!c:read-var-integer blocks i))) (tlf-offset (or tlf-number - (sb!c::read-var-integer blocks - i))) - (form-number (sb!c::read-var-integer blocks i)) - (live-set (sb!c::read-packed-bit-vector + (sb!c:read-var-integer blocks i))) + (form-number (sb!c:read-var-integer blocks i)) + (live-set (sb!c:read-packed-bit-vector live-set-len blocks i))) (vector-push-extend (make-known-code-location pc debug-fun tlf-offset @@ -1596,7 +1605,7 @@ (defun parse-compiled-debug-vars (debug-fun) (let* ((cdebug-fun (compiled-debug-fun-compiler-debug-fun debug-fun)) - (packed-vars (sb!c::compiled-debug-fun-variables cdebug-fun)) + (packed-vars (sb!c::compiled-debug-fun-vars cdebug-fun)) (args-minimal (eq (sb!c::compiled-debug-fun-arguments cdebug-fun) :minimal))) (when packed-vars @@ -1746,7 +1755,7 @@ (unless (fill-in-code-location code-location) ;; This check should be unnecessary. We're missing ;; debug info the compiler should have dumped. - (error "internal error: unknown code location")) + (bug "unknown code location")) (code-location-%tlf-offset code-location)) ;; (There used to be more cases back before sbcl-0.7.0,, ;; when we did special tricks to debug the IR1 @@ -1767,7 +1776,7 @@ (unless (fill-in-code-location code-location) ;; This check should be unnecessary. We're missing ;; debug info the compiler should have dumped. - (error "internal error: unknown code location")) + (bug "unknown code location")) (code-location-%form-number code-location)) ;; (There used to be more cases back before sbcl-0.7.0,, ;; when we did special tricks to debug the IR1 @@ -1789,7 +1798,7 @@ ((not (fill-in-code-location code-location)) ;; This check should be unnecessary. We're missing ;; debug info the compiler should have dumped. - (error "internal error: unknown code location")) + (bug "unknown code location")) (t (compiled-code-location-kind code-location))))) ;; (There used to be more cases back before sbcl-0.7.0,, @@ -1810,7 +1819,7 @@ ;; ;; FIXME: This error and comment happen over and over again. ;; Make them a shared function. - (error "internal error: unknown code location")) + (bug "unknown code location")) (compiled-code-location-%live-set code-location)) (t live-set))))) @@ -2049,7 +2058,7 @@ (sb!vm:context-float-register escaped (sb!c:sc-offset-offset sc-offset) 'double-float) (sb!vm:context-float-register - escaped (+ (sb!c:sc-offset-offset sc-offset) #!+sparc 2 #-sparc 1) + escaped (+ (sb!c:sc-offset-offset sc-offset) #!+sparc 2 #!-sparc 1) 'double-float)) :invalid-value-for-unescaped-register-storage)) #!+long-float @@ -2671,7 +2680,7 @@ (debug-signal 'no-debug-vars :debug-fun fun)) (sb!int:collect ((binds) (specs)) - (do-debug-fun-variables (var fun) + (do-debug-fun-vars (var fun) (let ((validity (debug-var-validity var loc))) (unless (eq validity :invalid) (let* ((sym (debug-var-symbol var)) @@ -2697,35 +2706,34 @@ (declare (ignorable ,n-frame)) (symbol-macrolet ,(specs) ,form)) 'function))) - #'(lambda (frame) - ;; This prevents these functions from being used in any - ;; location other than a function return location, so - ;; maybe this should only check whether frame's - ;; DEBUG-FUN is the same as loc's. - (unless (code-location= (frame-code-location frame) loc) - (debug-signal 'frame-fun-mismatch - :code-location loc :form form :frame frame)) - (funcall res frame)))))) + (lambda (frame) + ;; This prevents these functions from being used in any + ;; location other than a function return location, so maybe + ;; this should only check whether FRAME's DEBUG-FUN is the + ;; same as LOC's. + (unless (code-location= (frame-code-location frame) loc) + (debug-signal 'frame-fun-mismatch + :code-location loc :form form :frame frame)) + (funcall res frame)))))) ;;;; breakpoints ;;;; user-visible interface ;;; Create and return a breakpoint. When program execution encounters -;;; the breakpoint, the system calls HOOK-FUNCTION. HOOK-FUNCTION takes the -;;; current frame for the function in which the program is running and the -;;; breakpoint object. +;;; the breakpoint, the system calls HOOK-FUN. HOOK-FUN takes the +;;; current frame for the function in which the program is running and +;;; the breakpoint object. ;;; ;;; WHAT and KIND determine where in a function the system invokes -;;; HOOK-FUNCTION. WHAT is either a code-location or a DEBUG-FUN. -;;; KIND is one of :CODE-LOCATION, :FUN-START, or :FUN-END. -;;; Since the starts and ends of functions may not have code-locations -;;; representing them, designate these places by supplying WHAT as a -;;; DEBUG-FUN and KIND indicating the :FUN-START or -;;; :FUN-END. When WHAT is a DEBUG-FUN and kind is -;;; :FUN-END, then hook-function must take two additional -;;; arguments, a list of values returned by the function and a -;;; FUN-END-COOKIE. +;;; HOOK-FUN. WHAT is either a code-location or a DEBUG-FUN. KIND is +;;; one of :CODE-LOCATION, :FUN-START, or :FUN-END. Since the starts +;;; and ends of functions may not have code-locations representing +;;; them, designate these places by supplying WHAT as a DEBUG-FUN and +;;; KIND indicating the :FUN-START or :FUN-END. When WHAT is a +;;; DEBUG-FUN and kind is :FUN-END, then HOOK-FUN must take two +;;; additional arguments, a list of values returned by the function +;;; and a FUN-END-COOKIE. ;;; ;;; INFO is information supplied by and used by the user. ;;; @@ -2740,7 +2748,7 @@ ;;; function. ;;; ;;; Signal an error if WHAT is an unknown code-location. -(defun make-breakpoint (hook-function what +(defun make-breakpoint (hook-fun what &key (kind :code-location) info fun-end-cookie) (etypecase what (code-location @@ -2748,12 +2756,12 @@ (error "cannot make a breakpoint at an unknown code location: ~S" what)) (aver (eq kind :code-location)) - (let ((bpt (%make-breakpoint hook-function what kind info))) + (let ((bpt (%make-breakpoint hook-fun what kind info))) (etypecase what (compiled-code-location ;; This slot is filled in due to calling CODE-LOCATION-UNKNOWN-P. (when (eq (compiled-code-location-kind what) :unknown-return) - (let ((other-bpt (%make-breakpoint hook-function what + (let ((other-bpt (%make-breakpoint hook-fun what :unknown-return-partner info))) (setf (breakpoint-unknown-return-partner bpt) other-bpt) @@ -2766,7 +2774,7 @@ (compiled-debug-fun (ecase kind (:fun-start - (%make-breakpoint hook-function what kind info)) + (%make-breakpoint hook-fun what kind info)) (:fun-end (unless (eq (sb!c::compiled-debug-fun-returns (compiled-debug-fun-compiler-debug-fun what)) @@ -2774,11 +2782,11 @@ (error ":FUN-END breakpoints are currently unsupported ~ for the known return convention.")) - (let* ((bpt (%make-breakpoint hook-function what kind info)) + (let* ((bpt (%make-breakpoint hook-fun what kind info)) (starter (compiled-debug-fun-end-starter what))) (unless starter (setf starter (%make-breakpoint #'list what :fun-start nil)) - (setf (breakpoint-hook-function starter) + (setf (breakpoint-hook-fun starter) (fun-end-starter-hook starter what)) (setf (compiled-debug-fun-end-starter what) starter)) (setf (breakpoint-start-helper bpt) starter) @@ -2816,31 +2824,31 @@ (defun fun-end-starter-hook (starter-bpt debug-fun) (declare (type breakpoint starter-bpt) (type compiled-debug-fun debug-fun)) - #'(lambda (frame breakpoint) - (declare (ignore breakpoint) - (type frame frame)) - (let ((lra-sc-offset - (sb!c::compiled-debug-fun-return-pc - (compiled-debug-fun-compiler-debug-fun debug-fun)))) - (multiple-value-bind (lra component offset) - (make-bogus-lra - (get-context-value frame - lra-save-offset - lra-sc-offset)) - (setf (get-context-value frame - lra-save-offset - lra-sc-offset) - lra) - (let ((end-bpts (breakpoint-%info starter-bpt))) - (let ((data (breakpoint-data component offset))) - (setf (breakpoint-data-breakpoints data) end-bpts) - (dolist (bpt end-bpts) - (setf (breakpoint-internal-data bpt) data))) - (let ((cookie (make-fun-end-cookie lra debug-fun))) - (setf (gethash component *fun-end-cookies*) cookie) - (dolist (bpt end-bpts) - (let ((fun (breakpoint-cookie-fun bpt))) - (when fun (funcall fun frame cookie)))))))))) + (lambda (frame breakpoint) + (declare (ignore breakpoint) + (type frame frame)) + (let ((lra-sc-offset + (sb!c::compiled-debug-fun-return-pc + (compiled-debug-fun-compiler-debug-fun debug-fun)))) + (multiple-value-bind (lra component offset) + (make-bogus-lra + (get-context-value frame + lra-save-offset + lra-sc-offset)) + (setf (get-context-value frame + lra-save-offset + lra-sc-offset) + lra) + (let ((end-bpts (breakpoint-%info starter-bpt))) + (let ((data (breakpoint-data component offset))) + (setf (breakpoint-data-breakpoints data) end-bpts) + (dolist (bpt end-bpts) + (setf (breakpoint-internal-data bpt) data))) + (let ((cookie (make-fun-end-cookie lra debug-fun))) + (setf (gethash component *fun-end-cookies*) cookie) + (dolist (bpt end-bpts) + (let ((fun (breakpoint-cookie-fun bpt))) + (when fun (funcall fun frame cookie)))))))))) ;;; This takes a FUN-END-COOKIE and a frame, and it returns ;;; whether the cookie is still valid. A cookie becomes invalid when @@ -2860,14 +2868,14 @@ (do ((frame frame (frame-down frame))) ((not frame) nil) (when (and (compiled-frame-p frame) - (#-x86 eq #+x86 sap= + (#!-x86 eq #!+x86 sap= lra (get-context-value frame lra-save-offset lra-sc-offset))) (return t))))) ;;;; ACTIVATE-BREAKPOINT -;;; Cause the system to invoke the breakpoint's hook-function until +;;; Cause the system to invoke the breakpoint's hook function until ;;; the next call to DEACTIVATE-BREAKPOINT or DELETE-BREAKPOINT. The ;;; system invokes breakpoint hook functions in the opposite order ;;; that you activate them. @@ -2950,7 +2958,7 @@ ;;;; DEACTIVATE-BREAKPOINT -;;; Stop the system from invoking the breakpoint's hook-function. +;;; Stop the system from invoking the breakpoint's hook function. (defun deactivate-breakpoint (breakpoint) (when (eq (breakpoint-status breakpoint) :active) (without-interrupts @@ -2969,9 +2977,9 @@ (defun deactivate-compiled-breakpoint (breakpoint) (if (eq (breakpoint-kind breakpoint) :fun-end) (let ((starter (breakpoint-start-helper breakpoint))) - (unless (find-if #'(lambda (bpt) - (and (not (eq bpt breakpoint)) - (eq (breakpoint-status bpt) :active))) + (unless (find-if (lambda (bpt) + (and (not (eq bpt breakpoint)) + (eq (breakpoint-status bpt) :active))) (breakpoint-%info starter)) (deactivate-compiled-breakpoint starter))) (let* ((data (breakpoint-internal-data breakpoint)) @@ -3037,21 +3045,21 @@ ;;; returns the overwritten bits. You must call this in a context in ;;; which GC is disabled, so that Lisp doesn't move objects around ;;; that C is pointing to. -(sb!alien:define-alien-routine "breakpoint_install" sb!c-call:unsigned-long - (code-obj sb!c-call:unsigned-long) - (pc-offset sb!c-call:int)) +(sb!alien:define-alien-routine "breakpoint_install" sb!alien:unsigned-long + (code-obj sb!alien:unsigned-long) + (pc-offset sb!alien:int)) ;;; This removes the break instruction and replaces the original ;;; instruction. You must call this in a context in which GC is disabled ;;; so Lisp doesn't move objects around that C is pointing to. -(sb!alien:define-alien-routine "breakpoint_remove" sb!c-call:void - (code-obj sb!c-call:unsigned-long) - (pc-offset sb!c-call:int) - (old-inst sb!c-call:unsigned-long)) +(sb!alien:define-alien-routine "breakpoint_remove" sb!alien:void + (code-obj sb!alien:unsigned-long) + (pc-offset sb!alien:int) + (old-inst sb!alien:unsigned-long)) -(sb!alien:define-alien-routine "breakpoint_do_displaced_inst" sb!c-call:void +(sb!alien:define-alien-routine "breakpoint_do_displaced_inst" sb!alien:void (scp (* os-context-t)) - (orig-inst sb!c-call:unsigned-long)) + (orig-inst sb!alien:unsigned-long)) ;;;; breakpoint handlers (layer between C and exported interface) @@ -3116,7 +3124,7 @@ ;;; breakpoints. (defun handle-breakpoint-aux (breakpoints data offset component signal-context) (unless breakpoints - (error "internal error: breakpoint that nobody wants")) + (bug "breakpoint that nobody wants")) (unless (member data *executing-breakpoint-hooks*) (let ((*executing-breakpoint-hooks* (cons data *executing-breakpoint-hooks*))) @@ -3138,9 +3146,9 @@ (breakpoint-do-displaced-inst signal-context (breakpoint-data-instruction data)) ;; Some platforms have no usable sigreturn() call. If your - ;; implementation of arch_do_displaced_inst() doesn't sigreturn(), - ;; add it to this list. - #!-(or hpux irix x86 alpha) + ;; implementation of arch_do_displaced_inst() _does_ sigreturn(), + ;; it's polite to warn here + #!+(and sparc solaris) (error "BREAKPOINT-DO-DISPLACED-INST returned?")))) (defun invoke-breakpoint-hooks (breakpoints component offset) @@ -3148,7 +3156,7 @@ (frame (do ((f (top-frame) (frame-down f))) ((eq debug-fun (frame-debug-fun f)) f)))) (dolist (bpt breakpoints) - (funcall (breakpoint-hook-function bpt) + (funcall (breakpoint-hook-fun bpt) frame ;; If this is an :UNKNOWN-RETURN-PARTNER, then pass the ;; hook function the original breakpoint, so that users @@ -3186,7 +3194,7 @@ (cookie (gethash component *fun-end-cookies*))) (remhash component *fun-end-cookies*) (dolist (bpt breakpoints) - (funcall (breakpoint-hook-function bpt) + (funcall (breakpoint-hook-fun bpt) frame bpt (get-fun-end-breakpoint-values scp) cookie)))) @@ -3282,14 +3290,3 @@ ;; (There used to be more cases back before sbcl-0.7.0, when ;; we did special tricks to debug the IR1 interpreter.) )) - -(defun print-code-locations (function) - (let ((debug-fun (fun-debug-fun function))) - (do-debug-fun-blocks (block debug-fun) - (do-debug-block-locations (loc block) - (fill-in-code-location loc) - (format t "~S code location at ~W" - (compiled-code-location-kind loc) - (compiled-code-location-pc loc)) - (sb!debug::print-code-location-source-form loc 0) - (terpri)))))