X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fdebug-int.lisp;h=f610a0c6dc46da8eb27ab7fdc5c676e1b0bf149b;hb=c8af15e61b030c8d4b0e950bc9b7618530044618;hp=a7856e97bb7e116e0aa34515c6cdf00aa1ab3b8e;hpb=943f38e6232a69ab1bbcfb2c86801eea391f8ae1;p=sbcl.git diff --git a/src/code/debug-int.lisp b/src/code/debug-int.lisp index a7856e9..f610a0c 100644 --- a/src/code/debug-int.lisp +++ b/src/code/debug-int.lisp @@ -193,7 +193,8 @@ ;;; These exist for caching data stored in packed binary form in ;;; compiler debug-functions. Debug-functions store these. -(defstruct (debug-var (:constructor nil)) +(defstruct (debug-var (:constructor nil) + (:copier nil)) ;; the name of the variable (symbol (required-argument) :type symbol) ;; a unique integer identification relative to other variables with the same @@ -216,7 +217,8 @@ (defstruct (compiled-debug-var (:include debug-var) (:constructor make-compiled-debug-var - (symbol id alive-p sc-offset save-sc-offset))) + (symbol id alive-p sc-offset save-sc-offset)) + (:copier nil)) ;; Storage class and offset. (unexported). (sc-offset nil :type sb!c::sc-offset) ;; Storage class and offset when saved somewhere. @@ -224,14 +226,16 @@ (defstruct (interpreted-debug-var (:include debug-var (alive-p t)) - (:constructor make-interpreted-debug-var (symbol ir1-var))) + (:constructor make-interpreted-debug-var (symbol ir1-var)) + (:copier nil)) ;; This is the IR1 structure that holds information about interpreted vars. (ir1-var nil :type sb!c::lambda-var)) ;;;; frames ;;; These represent call-frames on the stack. -(defstruct (frame (:constructor nil)) +(defstruct (frame (:constructor nil) + (:copier nil)) ;; the next frame up, or NIL when top frame (up nil :type (or frame null)) ;; the previous frame down, or NIL when the bottom frame. Before @@ -273,7 +277,8 @@ (:constructor make-compiled-frame (pointer up debug-function code-location number #!+gengc saved-state-chain - &optional escaped))) + &optional escaped)) + (:copier nil)) ;; This indicates whether someone interrupted the frame. ;; (unexported). If escaped, this is a pointer to the state that was ;; saved when we were interrupted. On the non-gengc system, this is @@ -296,7 +301,8 @@ (:include frame) (:constructor make-interpreted-frame (pointer up debug-function code-location number - real-frame closure))) + real-frame closure)) + (:copier nil)) ;; This points to the compiled-frame for SB!EVAL:INTERNAL-APPLY-LOOP. (real-frame nil :type compiled-frame) ;; This is the closed over data used by the interpreter. @@ -314,7 +320,7 @@ ;;; code-locations and other objects that reference DEBUG-FUNCTIONs ;;; point to unique objects. This is due to the overhead in cached ;;; information. -(defstruct debug-function +(defstruct (debug-function (:copier nil)) ;; Some representation of the function arguments. See ;; DEBUG-FUNCTION-LAMBDA-LIST. ;; NOTE: must parse vars before parsing arg list stuff. @@ -334,7 +340,8 @@ (defstruct (compiled-debug-function (:include debug-function) (:constructor %make-compiled-debug-function - (compiler-debug-fun component))) + (compiler-debug-fun component)) + (:copier nil)) ;; Compiler's dumped debug-function information. (unexported). (compiler-debug-fun nil :type sb!c::compiled-debug-function) ;; Code object. (unexported). @@ -360,7 +367,8 @@ (defstruct (interpreted-debug-function (:include debug-function) - (:constructor %make-interpreted-debug-function (ir1-lambda))) + (:constructor %make-interpreted-debug-function (ir1-lambda)) + (:copier nil)) ;; This is the IR1 lambda that this debug-function represents. (ir1-lambda nil :type sb!c::clambda)) @@ -368,7 +376,8 @@ (:include debug-function) (:constructor make-bogus-debug-function (%name &aux (%lambda-list nil) (%debug-vars nil) - (blocks nil) (%function nil)))) + (blocks nil) (%function nil))) + (:copier nil)) %name) (defvar *ir1-lambda-debug-function* (make-hash-table :test 'eq)) @@ -382,8 +391,9 @@ ;;;; DEBUG-BLOCKs ;;; These exist for caching data stored in packed binary form in compiler -;;; debug-blocks. -(defstruct (debug-block (:constructor nil)) +;;; DEBUG-BLOCKs. +(defstruct (debug-block (:constructor nil) + (:copier nil)) ;; Code-locations where execution continues after this block. (successors nil :type list) ;; This indicates whether the block is a special glob of code shared by @@ -408,14 +418,16 @@ (defstruct (compiled-debug-block (:include debug-block) (:constructor make-compiled-debug-block - (code-locations successors elsewhere-p))) - ;; Code-location information for the block. + (code-locations successors elsewhere-p)) + (:copier nil)) + ;; code-location information for the block (code-locations nil :type simple-vector)) (defstruct (interpreted-debug-block (:include debug-block (elsewhere-p nil)) (:constructor %make-interpreted-debug-block - (ir1-block))) + (ir1-block)) + (:copier nil)) ;; This is the IR1 block this debug-block represents. (ir1-block nil :type sb!c::cblock) ;; Code-location information for the block. @@ -466,7 +478,8 @@ ;;; This is an internal structure that manages information about a ;;; breakpoint locations. See *COMPONENT-BREAKPOINT-OFFSETS*. (defstruct (breakpoint-data (:constructor make-breakpoint-data - (component offset))) + (component offset)) + (:copier nil)) ;; This is the component in which the breakpoint lies. component ;; This is the byte offset into the component. @@ -484,7 +497,8 @@ (breakpoint-data-offset obj)))) (defstruct (breakpoint (:constructor %make-breakpoint - (hook-function what kind %info))) + (hook-function 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 :FUNCTION-END breakpoints @@ -551,7 +565,8 @@ ;;;; CODE-LOCATIONs -(defstruct (code-location (:constructor nil)) +(defstruct (code-location (:constructor nil) + (:copier nil)) ;; This is the debug-function containing code-location. (debug-function nil :type debug-function) ;; This is initially :UNSURE. Upon first trying to access an @@ -587,7 +602,8 @@ (:constructor make-known-code-location (pc debug-function %tlf-offset %form-number %live-set kind &aux (%unknown-p nil))) - (:constructor make-compiled-code-location (pc debug-function))) + (:constructor make-compiled-code-location (pc debug-function)) + (:copier nil)) ;; This is an index into debug-function's component slot. (pc nil :type sb!c::index) ;; This is a bit-vector indexed by a variable's position in @@ -602,7 +618,8 @@ (:include code-location (%unknown-p nil)) (:constructor make-interpreted-code-location - (ir1-node debug-function))) + (ir1-node debug-function)) + (:copier nil)) ;; This is an index into debug-function's component slot. (ir1-node nil :type sb!c::node)) @@ -736,9 +753,9 @@ ;;; XXX Should probably check whether it has reached the bottom of the ;;; stack. ;;; -;;; XXX Should handle interrupted frames, both Lisp and C. At present it -;;; manages to find a fp trail, see linux hack below. -(defun x86-call-context (fp &key (depth 8)) +;;; XXX Should handle interrupted frames, both Lisp and C. At present +;;; it manages to find a fp trail, see linux hack below. +(defun x86-call-context (fp &key (depth 0)) (declare (type system-area-pointer fp) (fixnum depth)) ;;(format t "*CC ~S ~S~%" fp depth) @@ -762,15 +779,20 @@ lisp-ocfp lisp-ra c-ocfp c-ra) ;; Look forward another step to check their validity. (let ((lisp-path-fp (x86-call-context lisp-ocfp - :depth (- depth 1))) - (c-path-fp (x86-call-context c-ocfp :depth (- depth 1)))) + :depth (1+ depth))) + (c-path-fp (x86-call-context c-ocfp :depth (1+ depth)))) (cond ((and lisp-path-fp c-path-fp) - ;; Both still seem valid - choose the smallest. - #+nil (format t "debug: both still valid ~S ~S ~S ~S~%" - lisp-ocfp lisp-ra c-ocfp c-ra) - (if (sap< lisp-ocfp c-ocfp) - (values lisp-ra lisp-ocfp) - (values c-ra c-ocfp))) + ;; Both still seem valid - choose the lisp frame. + #+nil (when (zerop depth) + (format t + "debug: both still valid ~S ~S ~S ~S~%" + lisp-ocfp lisp-ra c-ocfp c-ra)) + #+freebsd + (if (sap> lisp-ocfp c-ocfp) + (values lisp-ra lisp-ocfp) + (values c-ra c-ocfp)) + #-freebsd + (values lisp-ra lisp-ocfp)) (lisp-path-fp ;; The lisp convention is looking good. #+nil (format t "*C lisp-ocfp ~S ~S~%" lisp-ocfp lisp-ra) @@ -1056,7 +1078,7 @@ code (1+ real-lra-slot))) (setq code (code-header-ref code real-lra-slot)) ; (format t "ccf3 :bogus-lra ~S ~S~%" code pc-offset) - (assert code))) + (aver code))) (t ;; Not escaped (multiple-value-setq (pc-offset code) @@ -1577,7 +1599,7 @@ (push (frob final-arg debug-vars) res)) (:keyword (push (list :keyword - (sb!c::arg-info-keyword info) + (sb!c::arg-info-key info) (frob final-arg debug-vars)) res)) (:rest @@ -1678,11 +1700,11 @@ res)) (sb!c::more-arg ;; Just ignore the fact that the next two args are - ;; the more arg context and count, and act like they + ;; the &MORE arg context and count, and act like they ;; are regular arguments. nil) (t - ;; keyword arg + ;; &KEY arg (push (list :keyword ele (compiled-debug-function-lambda-list-var @@ -1972,7 +1994,7 @@ 0)) (sc-offset (if deleted 0 (geti))) (save-sc-offset (if save (geti) nil))) - (assert (not (and args-minimal (not minimal)))) + (aver (not (and args-minimal (not minimal)))) (vector-push-extend (make-compiled-debug-var symbol id live @@ -2067,14 +2089,14 @@ (coerce (cdr (res)) 'simple-vector)))) -;;; This variable maps minimal debug-info function maps to an unpacked -;;; version thereof. +;;; a map from minimal DEBUG-INFO function maps to unpacked +;;; versions thereof (defvar *uncompacted-function-maps* (make-hash-table :test 'eq)) -;;; Return a function-map for a given compiled-debug-info object. If +;;; Return a FUNCTION-MAP for a given COMPILED-DEBUG-info object. If ;;; the info is minimal, and has not been parsed, then parse it. ;;; -;;; FIXME: Now that we no longer use the minimal-debug-function +;;; FIXME: Now that we no longer use the MINIMAL-DEBUG-FUNCTION ;;; representation, calls to this function can be replaced by calls to ;;; the bare COMPILED-DEBUG-INFO-FUNCTION-MAP slot accessor function, ;;; and this function and everything it calls become dead code which @@ -2090,17 +2112,14 @@ ;;;; CODE-LOCATIONs -;;; If we're sure of whether code-location is known, return t or nil. -;;; If we're :unsure, then try to fill in the code-location's slots. +;;; If we're sure of whether code-location is known, return T or NIL. +;;; If we're :UNSURE, then try to fill in the code-location's slots. ;;; This determines whether there is any debug-block information, and ;;; if code-location is known. ;;; ;;; ??? IF this conses closures every time it's called, then break off the -;;; :unsure part to get the HANDLER-CASE into another function. +;;; :UNSURE part to get the HANDLER-CASE into another function. (defun code-location-unknown-p (basic-code-location) - #!+sb-doc - "Returns whether basic-code-location is unknown. It returns nil when the - code-location is known." (ecase (code-location-%unknown-p basic-code-location) ((t) t) ((nil) nil) @@ -2109,11 +2128,10 @@ (handler-case (not (fill-in-code-location basic-code-location)) (no-debug-blocks () t)))))) +;;; Return the DEBUG-BLOCK containing code-location if it is available. +;;; Some debug policies inhibit debug-block information, and if none +;;; is available, then this signals a NO-DEBUG-BLOCKS condition. (defun code-location-debug-block (basic-code-location) - #!+sb-doc - "Returns the debug-block containing code-location if it is available. Some - debug policies inhibit debug-block information, and if none is available, - then this signals a no-debug-blocks condition." (let ((block (code-location-%debug-block basic-code-location))) (if (eq block :unparsed) (etypecase basic-code-location @@ -2126,10 +2144,10 @@ (interpreted-code-location-ir1-node basic-code-location)))))) block))) -;;; This stores and returns BASIC-CODE-LOCATION's debug-block. It -;;; determines the correct one using the code-location's pc. This uses +;;; Store and return BASIC-CODE-LOCATION's debug-block. We determines +;;; the correct one using the code-location's pc. We use ;;; DEBUG-FUNCTION-DEBUG-BLOCKS to return the cached block information -;;; or signal a 'no-debug-blocks condition. The blocks are sorted by +;;; or signal a NO-DEBUG-BLOCKS condition. The blocks are sorted by ;;; their first code-location's pc, in ascending order. Therefore, as ;;; soon as we find a block that starts with a pc greater than ;;; basic-code-location's pc, we know the previous block contains the @@ -2280,8 +2298,8 @@ (let ((live-set (compiled-code-location-%live-set code-location))) (cond ((eq live-set :unparsed) (unless (fill-in-code-location code-location) - ;; This check should be unnecessary. We're missing debug info - ;; the compiler should have dumped. + ;; This check should be unnecessary. We're missing + ;; debug info the compiler should have dumped. ;; ;; FIXME: This error and comment happen over and over again. ;; Make them a shared function. @@ -2289,9 +2307,8 @@ (compiled-code-location-%live-set code-location)) (t live-set))))) +;;; true if OBJ1 and OBJ2 are the same place in the code (defun code-location= (obj1 obj2) - #!+sb-doc - "Returns whether obj1 and obj2 are the same place in the code." (etypecase obj1 (compiled-code-location (etypecase obj2 @@ -2312,7 +2329,7 @@ (= (compiled-code-location-pc obj1) (compiled-code-location-pc obj2))) -;;; This fills in CODE-LOCATION's :unparsed slots. It returns t or nil +;;; Fill in CODE-LOCATION's :UNPARSED slots, returning T or NIL ;;; depending on whether the code-location was known in its ;;; debug-function's debug-block information. This may signal a ;;; NO-DEBUG-BLOCKS condition due to DEBUG-FUNCTION-DEBUG-BLOCKS, and @@ -2456,7 +2473,7 @@ ;;; those variables are invalid.) (defun make-valid-lisp-obj (val) (/show0 "entering MAKE-VALID-LISP-OBJ, VAL=..") - #!+sb-show (%primitive print (sb!impl::hexstr val)) + #!+sb-show (/hexstr val) (if (or ;; fixnum (zerop (logand val 3)) @@ -2492,16 +2509,14 @@ (defun sub-access-debug-var-slot (fp sc-offset &optional escaped) (declare (type system-area-pointer fp)) (/show0 "entering SUB-ACCESS-DEBUG-VAR-SLOT, FP,SC-OFFSET,ESCAPED=..") - #!+sb-show (%primitive print (sb!impl::hexstr fp)) - #!+sb-show (%primitive print (sb!impl::hexstr sc-offset)) - #!+sb-show (%primitive print (sb!impl::hexstr escaped)) + (/hexstr fp) (/hexstr sc-offset) (/hexstr escaped) (macrolet ((with-escaped-value ((var) &body forms) `(if escaped (let ((,var (sb!vm:context-register escaped (sb!c:sc-offset-offset sc-offset)))) (/show0 "in escaped case, ,VAR value=..") - #!+sb-show (%primitive print (sb!impl::hexstr ,var)) + (/hexstr ,var) ,@forms) :invalid-value-for-unescaped-register-storage)) (escaped-float-value (format) @@ -2523,7 +2538,7 @@ (without-gcing (with-escaped-value (val) (/show0 "VAL=..") - #!+sb-show (%primitive print (sb!impl::hexstr val)) + (/hexstr val) (make-valid-lisp-obj val)))) (#.sb!vm:base-char-reg-sc-number (/show0 "case of BASE-CHAR-REG-SC-NUMBER") @@ -3121,49 +3136,53 @@ :code-location loc :form form :frame frame)) (funcall res frame)))))) +;;; Evaluate FORM in the lexical context of FRAME's current code +;;; location, returning the results of the evaluation. (defun eval-in-frame (frame form) (declare (type frame frame)) - #!+sb-doc - "Evaluate Form in the lexical context of Frame's current code location, - returning the results of the evaluation." (funcall (preprocess-for-eval form (frame-code-location frame)) 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. +;;; +;;; WHAT and KIND determine where in a function the system invokes +;;; HOOK-FUNCTION. WHAT is either a code-location or a debug-function. +;;; KIND is one of :CODE-LOCATION, :FUNCTION-START, or :FUNCTION-END. +;;; Since the starts and ends of functions may not have code-locations +;;; representing them, designate these places by supplying WHAT as a +;;; debug-function and KIND indicating the :FUNCTION-START or +;;; :FUNCTION-END. When WHAT is a debug-function and kind is +;;; :FUNCTION-END, then hook-function must take two additional +;;; arguments, a list of values returned by the function and a +;;; FUNCTION-END-COOKIE. +;;; +;;; INFO is information supplied by and used by the user. +;;; +;;; FUNCTION-END-COOKIE is a function. To implement :FUNCTION-END +;;; breakpoints, the system uses starter breakpoints to establish the +;;; :FUNCTION-END breakpoint for each invocation of the function. Upon +;;; each entry, the system creates a unique cookie to identify the +;;; invocation, and when the user supplies a function for this +;;; argument, the system invokes it on the frame and the cookie. The +;;; system later invokes the :FUNCTION-END breakpoint hook on the same +;;; cookie. The user may save the cookie for comparison in the hook +;;; function. +;;; +;;; Signal an error if WHAT is an unknown code-location. (defun make-breakpoint (hook-function what &key (kind :code-location) info function-end-cookie) - #!+sb-doc - "This creates and returns 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. - What and kind determine where in a function the system invokes - hook-function. What is either a code-location or a debug-function. Kind is - one of :code-location, :function-start, or :function-end. Since the starts - and ends of functions may not have code-locations representing them, - designate these places by supplying what as a debug-function and kind - indicating the :function-start or :function-end. When what is a - debug-function and kind is :function-end, then hook-function must take two - additional arguments, a list of values returned by the function and a - function-end-cookie. - Info is information supplied by and used by the user. - Function-end-cookie is a function. To implement :function-end breakpoints, - the system uses starter breakpoints to establish the :function-end breakpoint - for each invocation of the function. Upon each entry, the system creates a - unique cookie to identify the invocation, and when the user supplies a - function for this argument, the system invokes it on the frame and the - cookie. The system later invokes the :function-end breakpoint hook on the - same cookie. The user may save the cookie for comparison in the hook - function. - This signals an error if what is an unknown code-location." (etypecase what (code-location (when (code-location-unknown-p what) (error "cannot make a breakpoint at an unknown code location: ~S" what)) - (assert (eq kind :code-location)) + (aver (eq kind :code-location)) (let ((bpt (%make-breakpoint hook-function what kind info))) (etypecase what (interpreted-code-location @@ -3211,13 +3230,14 @@ (defstruct (function-end-cookie (:print-object (lambda (obj str) (print-unreadable-object (obj str :type t)))) - (:constructor make-function-end-cookie (bogus-lra debug-fun))) - ;; This is a pointer to the bogus-lra created for :function-end bpts. + (:constructor make-function-end-cookie (bogus-lra debug-fun)) + (:copier nil)) + ;; a pointer to the bogus-lra created for :FUNCTION-END breakpoints bogus-lra - ;; This is the debug-function associated with the cookie. + ;; the debug-function associated with the cookie debug-fun) -;;; This maps bogus-lra-components to cookies, so +;;; This maps bogus-lra-components to cookies, so that ;;; HANDLE-FUNCTION-END-BREAKPOINT can find the appropriate cookie for the ;;; breakpoint hook. (defvar *function-end-cookies* (make-hash-table :test 'eq)) @@ -3260,16 +3280,17 @@ (let ((fun (breakpoint-cookie-fun bpt))) (when fun (funcall fun frame cookie)))))))))) +;;; This takes a FUNCTION-END-COOKIE and a frame, and it returns +;;; whether the cookie is still valid. A cookie becomes invalid when +;;; the frame that established the cookie has exited. Sometimes cookie +;;; holders are unaware of cookie invalidation because their +;;; :FUNCTION-END breakpoint hooks didn't run due to THROW'ing. +;;; +;;; This takes a frame as an efficiency hack since the user probably +;;; has a frame object in hand when using this routine, and it saves +;;; repeated parsing of the stack and consing when asking whether a +;;; series of cookies is valid. (defun function-end-cookie-valid-p (frame cookie) - #!+sb-doc - "This takes a function-end-cookie and a frame, and it returns whether the - cookie is still valid. A cookie becomes invalid when the frame that - established the cookie has exited. Sometimes cookie holders are unaware - of cookie invalidation because their :function-end breakpoint hooks didn't - run due to THROW'ing. This takes a frame as an efficiency hack since the - user probably has a frame object in hand when using this routine, and it - saves repeated parsing of the stack and consing when asking whether a - series of cookies is valid." (let ((lra (function-end-cookie-bogus-lra cookie)) (lra-sc-offset (sb!c::compiled-debug-function-return-pc (compiled-debug-function-compiler-debug-fun @@ -3283,14 +3304,14 @@ #!+gengc sb!vm::ra-save-offset lra-sc-offset))) (return t))))) - + ;;;; ACTIVATE-BREAKPOINT +;;; 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. (defun activate-breakpoint (breakpoint) - #!+sb-doc - "This causes 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." (when (eq (breakpoint-status breakpoint) :deleted) (error "cannot activate a deleted breakpoint: ~S" breakpoint)) (unless (eq (breakpoint-status breakpoint) :active) @@ -3317,7 +3338,7 @@ (compiled-debug-function (let ((starter (breakpoint-start-helper breakpoint))) (unless (eq (breakpoint-status starter) :active) - ;; May already be active by some other :function-end breakpoint. + ;; may already be active by some other :FUNCTION-END breakpoint (activate-compiled-function-start-breakpoint starter))) (setf (breakpoint-status breakpoint) :active)) (interpreted-debug-function @@ -3365,7 +3386,7 @@ (setf (breakpoint-data-breakpoints data) (append (breakpoint-data-breakpoints data) (list breakpoint))) (setf (breakpoint-internal-data breakpoint) data))) - + ;;;; DEACTIVATE-BREAKPOINT (defun deactivate-breakpoint (breakpoint) @@ -3406,7 +3427,7 @@ (delete-breakpoint-data data)))) (setf (breakpoint-status breakpoint) :inactive) breakpoint) - + ;;;; BREAKPOINT-INFO (defun breakpoint-info (breakpoint) @@ -3419,7 +3440,7 @@ (let ((other (breakpoint-unknown-return-partner breakpoint))) (when other (setf (breakpoint-%info other) value)))) - + ;;;; BREAKPOINT-ACTIVE-P and DELETE-BREAKPOINT (defun breakpoint-active-p (breakpoint) @@ -3453,7 +3474,7 @@ (breakpoint-what breakpoint)) nil)))))) breakpoint) - + ;;;; C call out stubs ;;; This actually installs the break instruction in the component. It @@ -3589,7 +3610,7 @@ offset)) (let ((breakpoints (breakpoint-data-breakpoints data))) (when breakpoints - (assert (eq (breakpoint-kind (car breakpoints)) :function-end)) + (aver (eq (breakpoint-kind (car breakpoints)) :function-end)) (handle-function-end-breakpoint-aux breakpoints data context))))) ;;; Either HANDLE-BREAKPOINT calls this for :FUNCTION-END breakpoints @@ -3632,7 +3653,7 @@ (stack-ref ocfp arg-num)) results))) (nreverse results))) - + ;;;; MAKE-BOGUS-LRA (used for :FUNCTION-END breakpoints) (defconstant