1 ;;;; the implementation of the programmer's interface to writing
4 ;;;; This software is part of the SBCL system. See the README file for
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
15 ;;; FIXME: There are an awful lot of package prefixes in this code.
16 ;;; Couldn't we have SB-DI use the SB-C and SB-VM packages?
20 ;;;; The interface to building debugging tools signals conditions that
21 ;;;; prevent it from adhering to its contract. These are
22 ;;;; serious-conditions because the program using the interface must
23 ;;;; handle them before it can correctly continue execution. These
24 ;;;; debugging conditions are not errors since it is no fault of the
25 ;;;; programmers that the conditions occur. The interface does not
26 ;;;; provide for programs to detect these situations other than
27 ;;;; calling a routine that detects them and signals a condition. For
28 ;;;; example, programmers call A which may fail to return successfully
29 ;;;; due to a lack of debug information, and there is no B the they
30 ;;;; could have called to realize A would fail. It is not an error to
31 ;;;; have called A, but it is an error for the program to then ignore
32 ;;;; the signal generated by A since it cannot continue without A's
33 ;;;; correctly returning a value or performing some operation.
35 ;;;; Use DEBUG-SIGNAL to signal these conditions.
37 (define-condition debug-condition
(serious-condition)
40 "All DEBUG-CONDITIONs inherit from this type. These are serious conditions
41 that must be handled, but they are not programmer errors."))
43 (define-condition no-debug-fun-returns
(debug-condition)
44 ((debug-fun :reader no-debug-fun-returns-debug-fun
47 "The system could not return values from a frame with DEBUG-FUN since
48 it lacked information about returning values.")
49 (:report
(lambda (condition stream
)
50 (let ((fun (debug-fun-fun
51 (no-debug-fun-returns-debug-fun condition
))))
53 "~&Cannot return values from ~:[frame~;~:*~S~] since ~
54 the debug information lacks details about returning ~
58 (define-condition no-debug-blocks
(debug-condition)
59 ((debug-fun :reader no-debug-blocks-debug-fun
61 (:documentation
"The debug-fun has no debug-block information.")
62 (:report
(lambda (condition stream
)
63 (format stream
"~&~S has no debug-block information."
64 (no-debug-blocks-debug-fun condition
)))))
66 (define-condition no-debug-vars
(debug-condition)
67 ((debug-fun :reader no-debug-vars-debug-fun
69 (:documentation
"The DEBUG-FUN has no DEBUG-VAR information.")
70 (:report
(lambda (condition stream
)
71 (format stream
"~&~S has no debug variable information."
72 (no-debug-vars-debug-fun condition
)))))
74 (define-condition lambda-list-unavailable
(debug-condition)
75 ((debug-fun :reader lambda-list-unavailable-debug-fun
78 "The DEBUG-FUN has no lambda list since argument DEBUG-VARs are
80 (:report
(lambda (condition stream
)
81 (format stream
"~&~S has no lambda-list information available."
82 (lambda-list-unavailable-debug-fun condition
)))))
84 (define-condition invalid-value
(debug-condition)
85 ((debug-var :reader invalid-value-debug-var
:initarg
:debug-var
)
86 (frame :reader invalid-value-frame
:initarg
:frame
))
87 (:report
(lambda (condition stream
)
88 (format stream
"~&~S has :invalid or :unknown value in ~S."
89 (invalid-value-debug-var condition
)
90 (invalid-value-frame condition
)))))
92 (define-condition ambiguous-var-name
(debug-condition)
93 ((name :reader ambiguous-var-name-name
:initarg
:name
)
94 (frame :reader ambiguous-var-name-frame
:initarg
:frame
))
95 (:report
(lambda (condition stream
)
96 (format stream
"~&~S names more than one valid variable in ~S."
97 (ambiguous-var-name-name condition
)
98 (ambiguous-var-name-frame condition
)))))
100 ;;;; errors and DEBUG-SIGNAL
102 ;;; The debug-internals code tries to signal all programmer errors as
103 ;;; subtypes of DEBUG-ERROR. There are calls to ERROR signalling
104 ;;; SIMPLE-ERRORs, but these dummy checks in the code and shouldn't
107 ;;; While under development, this code also signals errors in code
108 ;;; branches that remain unimplemented.
110 (define-condition debug-error
(error) ()
112 "All programmer errors from using the interface for building debugging
113 tools inherit from this type."))
115 (define-condition unhandled-debug-condition
(debug-error)
116 ((condition :reader unhandled-debug-condition-condition
:initarg
:condition
))
117 (:report
(lambda (condition stream
)
118 (format stream
"~&unhandled DEBUG-CONDITION:~%~A"
119 (unhandled-debug-condition-condition condition
)))))
121 (define-condition unknown-code-location
(debug-error)
122 ((code-location :reader unknown-code-location-code-location
123 :initarg
:code-location
))
124 (:report
(lambda (condition stream
)
125 (format stream
"~&invalid use of an unknown code-location: ~S"
126 (unknown-code-location-code-location condition
)))))
128 (define-condition unknown-debug-var
(debug-error)
129 ((debug-var :reader unknown-debug-var-debug-var
:initarg
:debug-var
)
130 (debug-fun :reader unknown-debug-var-debug-fun
131 :initarg
:debug-fun
))
132 (:report
(lambda (condition stream
)
133 (format stream
"~&~S is not in ~S."
134 (unknown-debug-var-debug-var condition
)
135 (unknown-debug-var-debug-fun condition
)))))
137 (define-condition invalid-control-stack-pointer
(debug-error)
139 (:report
(lambda (condition stream
)
140 (declare (ignore condition
))
142 (write-string "invalid control stack pointer" stream
))))
144 (define-condition frame-fun-mismatch
(debug-error)
145 ((code-location :reader frame-fun-mismatch-code-location
146 :initarg
:code-location
)
147 (frame :reader frame-fun-mismatch-frame
:initarg
:frame
)
148 (form :reader frame-fun-mismatch-form
:initarg
:form
))
149 (:report
(lambda (condition stream
)
152 "~&Form was preprocessed for ~S,~% but called on ~S:~% ~S"
153 (frame-fun-mismatch-code-location condition
)
154 (frame-fun-mismatch-frame condition
)
155 (frame-fun-mismatch-form condition
)))))
157 ;;; This signals debug-conditions. If they go unhandled, then signal
158 ;;; an UNHANDLED-DEBUG-CONDITION error.
160 ;;; ??? Get SIGNAL in the right package!
161 (defmacro debug-signal
(datum &rest arguments
)
162 `(let ((condition (make-condition ,datum
,@arguments
)))
164 (error 'unhandled-debug-condition
:condition condition
)))
168 ;;;; Most of these structures model information stored in internal
169 ;;;; data structures created by the compiler. Whenever comments
170 ;;;; preface an object or type with "compiler", they refer to the
171 ;;;; internal compiler thing, not to the object or type with the same
172 ;;;; name in the "SB-DI" package.
176 ;;; These exist for caching data stored in packed binary form in
177 ;;; compiler DEBUG-FUNs.
178 (defstruct (debug-var (:constructor nil
)
180 ;; the name of the variable
181 (symbol (missing-arg) :type symbol
)
182 ;; a unique integer identification relative to other variables with the same
184 (id 0 :type index
:read-only t
)
185 ;; Does the variable always have a valid value?
186 (alive-p nil
:type boolean
:read-only t
))
187 (defmethod print-object ((debug-var debug-var
) stream
)
188 (print-unreadable-object (debug-var stream
:type t
:identity t
)
191 (debug-var-symbol debug-var
)
192 (debug-var-id debug-var
))))
194 (setf (fdocumentation 'debug-var-id
'function
)
195 "Return the integer that makes DEBUG-VAR's name and package unique
196 with respect to other DEBUG-VARs in the same function.")
198 (defstruct (compiled-debug-var
200 (:constructor make-compiled-debug-var
202 sc-offset save-sc-offset indirect-sc-offset info
))
204 ;; storage class and offset (unexported)
205 (sc-offset nil
:type sb
!c
:sc-offset
:read-only t
)
206 ;; storage class and offset when saved somewhere
207 (save-sc-offset nil
:type
(or sb
!c
:sc-offset null
) :read-only t
)
208 ;; For indirect closures the fp of the parent frame is stored in the
209 ;; normal sc-offsets above, and this has the offset into the frame
210 (indirect-sc-offset nil
:type
(or sb
!c
:sc-offset null
) :read-only t
)
211 (info nil
:read-only t
))
215 ;;; These exist for caching data stored in packed binary form in
216 ;;; compiler DEBUG-FUNs. *COMPILED-DEBUG-FUNS* maps a SB!C::DEBUG-FUN
217 ;;; to a DEBUG-FUN. There should only be one DEBUG-FUN in existence
218 ;;; for any function; that is, all CODE-LOCATIONs and other objects
219 ;;; that reference DEBUG-FUNs point to unique objects. This is
220 ;;; due to the overhead in cached information.
222 (defstruct (debug-fun (:constructor nil
)
224 ;; some representation of the function arguments. See
225 ;; DEBUG-FUN-LAMBDA-LIST.
226 ;; NOTE: must parse vars before parsing arg list stuff.
227 (%lambda-list
:unparsed
)
228 ;; cached DEBUG-VARS information (unexported).
229 ;; These are sorted by their name.
230 (%debug-vars
:unparsed
:type
(or simple-vector null
(member :unparsed
)))
231 ;; cached debug-block information. This is NIL when we have tried to
232 ;; parse the packed binary info, but none is available.
233 (blocks :unparsed
:type
(or simple-vector null
(member :unparsed
)))
234 ;; the actual function if available
235 (%function
:unparsed
:type
(or null function
(member :unparsed
))))
236 (defmethod print-object ((obj debug-fun
) stream
)
237 (print-unreadable-object (obj stream
:type t
)
238 (prin1 (debug-fun-name obj
) stream
)))
240 (defstruct (bogus-debug-fun
242 (:constructor make-bogus-debug-fun
249 (%name nil
:read-only t
))
253 ;;; These exist for caching data stored in packed binary form in compiler
255 (defstruct (debug-block (:constructor nil
)
257 ;; This indicates whether the block is a special glob of code shared
258 ;; by various functions and tucked away elsewhere in a component.
259 ;; This kind of block has no start code-location. This slot is in
260 ;; all debug-blocks since it is an exported interface.
261 (elsewhere-p nil
:type boolean
))
262 (defmethod print-object ((obj debug-block
) str
)
263 (print-unreadable-object (obj str
:type t
)
264 (prin1 (debug-block-fun-name obj
) str
)))
266 (setf (fdocumentation 'debug-block-elsewhere-p
'function
)
267 "Return whether debug-block represents elsewhere code.")
269 (defstruct (compiled-debug-block (:include debug-block
)
271 ;; code-location information for the block
272 (code-locations #() :type simple-vector
))
274 (defstruct (code-location (:constructor nil
)
276 ;; the DEBUG-FUN containing this CODE-LOCATION
277 (debug-fun nil
:type debug-fun
:read-only t
)
278 ;; This is initially :UNSURE. Upon first trying to access an
279 ;; :UNPARSED slot, if the data is unavailable, then this becomes T,
280 ;; and the code-location is unknown. If the data is available, this
281 ;; becomes NIL, a known location. We can't use a separate type
282 ;; code-location for this since we must return code-locations before
283 ;; we can tell whether they're known or unknown. For example, when
284 ;; parsing the stack, we don't want to unpack all the variables and
285 ;; blocks just to make frames.
286 (%unknown-p
:unsure
:type
(member t nil
:unsure
))
287 ;; the DEBUG-BLOCK containing CODE-LOCATION. XXX Possibly toss this
288 ;; out and just find it in the blocks cache in DEBUG-FUN.
289 (%debug-block
:unparsed
:type
(or debug-block
(member :unparsed
)))
290 ;; This is the depth-first number of the node that begins
291 ;; code-location within its top level form.
292 (%form-number
:unparsed
:type
(or index
(member :unparsed
))))
296 ;;; These represent call frames on the stack.
297 (defstruct (frame (:constructor nil
)
299 ;; the next frame up, or NIL when top frame
300 (up nil
:type
(or frame null
))
301 ;; the previous frame down, or NIL when the bottom frame. Before
302 ;; computing the next frame down, this slot holds the frame pointer
303 ;; to the control stack for the given frame. This lets us get the
304 ;; next frame down and the return-pc for that frame.
305 (%down
:unparsed
:type
(or frame
(member nil
:unparsed
)))
306 ;; the DEBUG-FUN for the function whose call this frame represents
307 (debug-fun nil
:type debug-fun
:read-only t
)
308 ;; the CODE-LOCATION where the frame's DEBUG-FUN will continue
309 ;; running when program execution returns to this frame. If someone
310 ;; interrupted this frame, the result could be an unknown
312 (code-location nil
:type code-location
:read-only t
)
313 ;; an a-list of catch-tags to code-locations
314 (%catches
:unparsed
:type
(or list
(member :unparsed
)))
315 ;; pointer to frame on control stack (unexported)
316 (pointer nil
:read-only t
)
317 ;; This is the frame's number for prompt printing. Top is zero.
318 (number 0 :type index
))
320 (defstruct (compiled-frame
322 (:constructor make-compiled-frame
323 (pointer up debug-fun code-location number
326 ;; This indicates whether someone interrupted the frame.
327 ;; (unexported). If escaped, this is a pointer to the state that was
328 ;; saved when we were interrupted, an os_context_t, i.e. the third
329 ;; argument to an SA_SIGACTION-style signal handler.
330 (escaped nil
:read-only t
))
331 (defmethod print-object ((obj compiled-frame
) str
)
332 (print-unreadable-object (obj str
:type t
)
334 "~S~:[~;, interrupted~]"
335 (debug-fun-name (frame-debug-fun obj
))
336 (compiled-frame-escaped obj
))))
339 ;;; This maps SB!C::COMPILED-DEBUG-FUNs to
340 ;;; COMPILED-DEBUG-FUNs, so we can get at cached stuff and not
341 ;;; duplicate COMPILED-DEBUG-FUN structures.
342 (defvar *compiled-debug-funs
* (make-hash-table :test
'eq
:weakness
:key
))
344 ;;; Make a COMPILED-DEBUG-FUN for a SB!C::COMPILER-DEBUG-FUN and its
345 ;;; component. This maps the latter to the former in
346 ;;; *COMPILED-DEBUG-FUNS*. If there already is a COMPILED-DEBUG-FUN,
347 ;;; then this returns it from *COMPILED-DEBUG-FUNS*.
349 ;;; FIXME: It seems this table can potentially grow without bounds,
350 ;;; and retains roots to functions that might otherwise be collected.
351 (defun make-compiled-debug-fun (compiler-debug-fun component
)
352 (let ((table *compiled-debug-funs
*))
353 (with-locked-system-table (table)
354 (or (gethash compiler-debug-fun table
)
355 (setf (gethash compiler-debug-fun table
)
356 (%make-compiled-debug-fun compiler-debug-fun component
))))))
360 ;;; This is an internal structure that manages information about a
361 ;;; breakpoint locations. See *COMPONENT-BREAKPOINT-OFFSETS*.
362 (defstruct (breakpoint-data (:constructor make-breakpoint-data
365 ;; This is the component in which the breakpoint lies.
366 (component nil
:read-only t
)
367 ;; This is the byte offset into the component.
368 (offset nil
:type index
:read-only t
)
369 ;; The original instruction replaced by the breakpoint.
370 (instruction nil
:type
(or null sb
!vm
::word
))
371 ;; A list of user breakpoints at this location.
372 (breakpoints nil
:type list
))
373 (defmethod print-object ((obj breakpoint-data
) str
)
374 (print-unreadable-object (obj str
:type t
)
375 (format str
"~S at ~S"
377 (debug-fun-from-pc (breakpoint-data-component obj
)
378 (breakpoint-data-offset obj
)))
379 (breakpoint-data-offset obj
))))
381 (defstruct (breakpoint (:constructor %make-breakpoint
382 (hook-fun what kind %info
))
384 ;; This is the function invoked when execution encounters the
385 ;; breakpoint. It takes a frame, the breakpoint, and optionally a
386 ;; list of values. Values are supplied for :FUN-END breakpoints as
387 ;; values to return for the function containing the breakpoint.
388 ;; :FUN-END breakpoint hook functions also take a cookie argument.
389 ;; See the COOKIE-FUN slot.
390 (hook-fun (required-arg) :type function
)
391 ;; CODE-LOCATION or DEBUG-FUN
392 (what nil
:type
(or code-location debug-fun
) :read-only t
)
393 ;; :CODE-LOCATION, :FUN-START, or :FUN-END for that kind
394 ;; of breakpoint. :UNKNOWN-RETURN-PARTNER if this is the partner of
395 ;; a :code-location breakpoint at an :UNKNOWN-RETURN code-location.
396 (kind nil
:type
(member :code-location
:fun-start
:fun-end
397 :unknown-return-partner
)
399 ;; Status helps the user and the implementation.
400 (status :inactive
:type
(member :active
:inactive
:deleted
))
401 ;; This is a backpointer to a breakpoint-data.
402 (internal-data nil
:type
(or null breakpoint-data
))
403 ;; With code-locations whose type is :UNKNOWN-RETURN, there are
404 ;; really two breakpoints: one at the multiple-value entry point,
405 ;; and one at the single-value entry point. This slot holds the
406 ;; breakpoint for the other one, or NIL if this isn't at an
407 ;; :UNKNOWN-RETURN code location.
408 (unknown-return-partner nil
:type
(or null breakpoint
))
409 ;; :FUN-END breakpoints use a breakpoint at the :FUN-START
410 ;; to establish the end breakpoint upon function entry. We do this
411 ;; by frobbing the LRA to jump to a special piece of code that
412 ;; breaks and provides the return values for the returnee. This slot
413 ;; points to the start breakpoint, so we can activate, deactivate,
415 (start-helper nil
:type
(or null breakpoint
))
416 ;; This is a hook users supply to get a dynamically unique cookie
417 ;; for identifying :FUN-END breakpoint executions. That is, if
418 ;; there is one :FUN-END breakpoint, but there may be multiple
419 ;; pending calls of its function on the stack. This function takes
420 ;; the cookie, and the hook function takes the cookie too.
421 (cookie-fun nil
:type
(or null function
))
422 ;; This slot users can set with whatever information they find useful.
424 (defmethod print-object ((obj breakpoint
) str
)
425 (let ((what (breakpoint-what obj
)))
426 (print-unreadable-object (obj str
:type t
)
431 (debug-fun (debug-fun-name what
)))
434 (debug-fun (breakpoint-kind obj
)))))))
436 (defstruct (compiled-debug-fun
438 (:constructor %make-compiled-debug-fun
439 (compiler-debug-fun component
))
441 ;; compiler's dumped DEBUG-FUN information (unexported)
442 (compiler-debug-fun nil
:type sb
!c
::compiled-debug-fun
444 ;; code object (unexported).
445 (component nil
:read-only t
)
446 ;; the :FUN-START breakpoint (if any) used to facilitate
447 ;; function end breakpoints
448 (end-starter nil
:type
(or null breakpoint
)))
452 (defmethod print-object ((obj code-location
) str
)
453 (print-unreadable-object (obj str
:type t
)
454 (prin1 (debug-fun-name (code-location-debug-fun obj
))
457 (defstruct (compiled-code-location
458 (:include code-location
)
459 (:constructor make-known-code-location
460 (pc debug-fun %debug-block %form-number
461 %live-set kind step-info context
&aux
(%unknown-p nil
)))
462 (:constructor make-compiled-code-location
(pc debug-fun
))
464 ;; an index into DEBUG-FUN's component slot
465 (pc nil
:type index
:read-only t
)
466 ;; a bit-vector indexed by a variable's position in
467 ;; DEBUG-FUN-DEBUG-VARS indicating whether the variable has a
468 ;; valid value at this code-location. (unexported).
469 (%live-set
:unparsed
:type
(or simple-bit-vector
(member :unparsed
)))
470 ;; (unexported) To see SB!C::LOCATION-KIND, do
471 ;; (SB!KERNEL:TYPEXPAND 'SB!C::LOCATION-KIND).
472 (kind :unparsed
:type
(or (member :unparsed
) sb
!c
::location-kind
))
473 (step-info :unparsed
:type
(or (member :unparsed
:foo
) simple-string
))
478 ;;; This is used in FIND-ESCAPED-FRAME and with the bogus components
479 ;;; and LRAs used for :FUN-END breakpoints. When a component's
480 ;;; debug-info slot is :BOGUS-LRA, then the REAL-LRA-SLOT contains the
481 ;;; real component to continue executing, as opposed to the bogus
482 ;;; component which appeared in some frame's LRA location.
483 (defconstant real-lra-slot
484 ;; X86 stores a fixup vector at the first constant slot
485 #!-x86 sb
!vm
:code-constants-offset
486 #!+x86
(1+ sb
!vm
:code-constants-offset
))
488 ;;; These are magically converted by the compiler.
489 (defun current-sp () (current-sp))
490 (defun current-fp () (current-fp))
491 (defun stack-ref (s n
) (stack-ref s n
))
492 (defun %set-stack-ref
(s n value
) (%set-stack-ref s n value
))
493 (defun fun-code-header (fun) (fun-code-header fun
))
494 (defun lra-code-header (lra) (lra-code-header lra
))
495 (defun %make-lisp-obj
(value) (%make-lisp-obj value
))
496 (defun get-lisp-obj-address (thing) (get-lisp-obj-address thing
))
497 (defun fun-word-offset (fun) (fun-word-offset fun
))
499 #!-sb-fluid
(declaim (inline control-stack-pointer-valid-p
))
500 (defun control-stack-pointer-valid-p (x &optional
(aligned t
))
501 (declare (type system-area-pointer x
))
502 (let* (#!-stack-grows-downward-not-upward
504 (descriptor-sap *control-stack-start
*))
505 #!+stack-grows-downward-not-upward
507 (descriptor-sap *control-stack-end
*)))
508 #!-stack-grows-downward-not-upward
509 (and (sap< x
(current-sp))
510 (sap<= control-stack-start x
)
511 (or (not aligned
) (zerop (logand (sap-int x
)
512 (1- (ash 1 sb
!vm
:word-shift
))))))
513 #!+stack-grows-downward-not-upward
514 (and (sap>= x
(current-sp))
515 (sap> control-stack-end x
)
516 (or (not aligned
) (zerop (logand (sap-int x
)
517 (1- (ash 1 sb
!vm
:word-shift
))))))))
519 (declaim (inline component-ptr-from-pc
))
520 (sb!alien
:define-alien-routine component-ptr-from-pc
(system-area-pointer)
521 (pc system-area-pointer
))
523 (declaim (inline valid-lisp-pointer-p
))
524 (sb!alien
:define-alien-routine valid-lisp-pointer-p sb
!alien
:int
525 (pointer system-area-pointer
))
527 (declaim (inline component-from-component-ptr
))
528 (defun component-from-component-ptr (component-ptr)
529 (declare (type system-area-pointer component-ptr
))
530 (make-lisp-obj (logior (sap-int component-ptr
)
531 sb
!vm
:other-pointer-lowtag
)))
533 ;;;; (OR X86 X86-64) support
535 (defun compute-lra-data-from-pc (pc)
536 (declare (type system-area-pointer pc
))
537 (let ((component-ptr (component-ptr-from-pc pc
)))
538 (unless (sap= component-ptr
(int-sap #x0
))
539 (let* ((code (component-from-component-ptr component-ptr
))
540 (code-header-len (* (code-header-words code
) sb
!vm
:n-word-bytes
))
541 (pc-offset (- (sap-int pc
)
542 (- (get-lisp-obj-address code
)
543 sb
!vm
:other-pointer-lowtag
)
545 ;;(format t "c-lra-fpc ~A ~A ~A~%" pc code pc-offset)
546 (values pc-offset code
)))))
551 (defconstant sb
!vm
::nargs-offset
#.sb
!vm
::ecx-offset
)
553 ;;; Check for a valid return address - it could be any valid C/Lisp
556 ;;; XXX Could be a little smarter.
557 #!-sb-fluid
(declaim (inline ra-pointer-valid-p
))
558 (defun ra-pointer-valid-p (ra)
559 (declare (type system-area-pointer ra
))
561 ;; not the first page (which is unmapped)
563 ;; FIXME: Where is this documented? Is it really true of every CPU
564 ;; architecture? Is it even necessarily true in current SBCL?
565 (>= (sap-int ra
) 4096)
566 ;; not a Lisp stack pointer
567 (not (control-stack-pointer-valid-p ra
))))
569 ;;; Try to find a valid previous stack. This is complex on the x86 as
570 ;;; it can jump between C and Lisp frames. To help find a valid frame
571 ;;; it searches backwards.
573 ;;; XXX Should probably check whether it has reached the bottom of the
576 ;;; XXX Should handle interrupted frames, both Lisp and C. At present
577 ;;; it manages to find a fp trail, see linux hack below.
578 (declaim (maybe-inline x86-call-context
))
579 (defun x86-call-context (fp)
580 (declare (type system-area-pointer fp
))
581 (let ((ocfp (sap-ref-sap fp
(sb!vm
::frame-byte-offset ocfp-save-offset
)))
582 (ra (sap-ref-sap fp
(sb!vm
::frame-byte-offset return-pc-save-offset
))))
583 (if (and (control-stack-pointer-valid-p fp
)
585 (control-stack-pointer-valid-p ocfp
)
586 (ra-pointer-valid-p ra
))
588 (values nil
(int-sap 0) (int-sap 0)))))
592 ;;; Return the top frame of the control stack as it was before calling
595 (/noshow0
"entering TOP-FRAME")
596 (compute-calling-frame (descriptor-sap (%caller-frame
))
600 ;;; Flush all of the frames above FRAME, and renumber all the frames
602 (defun flush-frames-above (frame)
603 (setf (frame-up frame
) nil
)
604 (do ((number 0 (1+ number
))
605 (frame frame
(frame-%down frame
)))
606 ((not (frame-p frame
)))
607 (setf (frame-number frame
) number
)))
609 (defun find-saved-frame-down (fp up-frame
)
610 (multiple-value-bind (saved-fp saved-pc
)
611 (sb!alien-internals
:find-saved-fp-and-pc fp
)
613 (compute-calling-frame saved-fp saved-pc up-frame t
))))
615 ;;; Return the frame immediately below FRAME on the stack; or when
616 ;;; FRAME is the bottom of the stack, return NIL.
617 (defun frame-down (frame)
618 (/noshow0
"entering FRAME-DOWN")
619 ;; We have to access the old-fp and return-pc out of frame and pass
620 ;; them to COMPUTE-CALLING-FRAME.
621 (let ((down (frame-%down frame
)))
622 (if (eq down
:unparsed
)
623 (let ((debug-fun (frame-debug-fun frame
)))
624 (/noshow0
"in DOWN :UNPARSED case")
625 (setf (frame-%down frame
)
628 (let (#!-fp-and-pc-standard-save
629 (c-d-f (compiled-debug-fun-compiler-debug-fun
631 (compute-calling-frame
634 frame ocfp-save-offset
635 #!-fp-and-pc-standard-save
636 (sb!c
::compiled-debug-fun-old-fp c-d-f
)
637 #!+fp-and-pc-standard-save
638 sb
!c
:old-fp-passing-offset
))
640 frame lra-save-offset
641 #!-fp-and-pc-standard-save
642 (sb!c
::compiled-debug-fun-return-pc c-d-f
)
643 #!+fp-and-pc-standard-save
644 sb
!c
:return-pc-passing-offset
)
647 (let ((fp (frame-pointer frame
)))
648 (when (control-stack-pointer-valid-p fp
)
650 (multiple-value-bind (ok ra ofp
) (x86-call-context fp
)
652 (compute-calling-frame ofp ra frame
)
653 (find-saved-frame-down fp frame
)))
655 (compute-calling-frame
657 (sap-ref-sap fp
(* ocfp-save-offset
661 (sap-ref-32 fp
(* ocfp-save-offset
662 sb
!vm
:n-word-bytes
)))
664 (stack-ref fp lra-save-offset
)
669 ;;; Get the old FP or return PC out of FRAME. STACK-SLOT is the
670 ;;; standard save location offset on the stack. LOC is the saved
671 ;;; SC-OFFSET describing the main location.
672 (defun get-context-value (frame stack-slot loc
)
673 (declare (type compiled-frame frame
) (type unsigned-byte stack-slot
)
674 (type sb
!c
:sc-offset loc
))
675 (let ((pointer (frame-pointer frame
))
676 (escaped (compiled-frame-escaped frame
)))
678 (sub-access-debug-var-slot pointer loc escaped
)
680 (stack-ref pointer stack-slot
)
684 (stack-ref pointer stack-slot
))
686 (sap-ref-sap pointer
(sb!vm
::frame-byte-offset stack-slot
)))))))
688 (defun (setf get-context-value
) (value frame stack-slot loc
)
689 (declare (type compiled-frame frame
) (type unsigned-byte stack-slot
)
690 (type sb
!c
:sc-offset loc
))
691 (let ((pointer (frame-pointer frame
))
692 (escaped (compiled-frame-escaped frame
)))
694 (sub-set-debug-var-slot pointer loc value escaped
)
696 (setf (stack-ref pointer stack-slot
) value
)
700 (setf (stack-ref pointer stack-slot
) value
))
702 (setf (sap-ref-sap pointer
(sb!vm
::frame-byte-offset stack-slot
))
705 (defun foreign-function-backtrace-name (sap)
706 (let ((name (sap-foreign-symbol sap
)))
708 (format nil
"foreign function: ~A" name
)
709 (format nil
"foreign function: #x~X" (sap-int sap
)))))
711 ;;; This returns a frame for the one existing in time immediately
712 ;;; prior to the frame referenced by current-fp. This is current-fp's
713 ;;; caller or the next frame down the control stack. If there is no
714 ;;; down frame, this returns NIL for the bottom of the stack. UP-FRAME
715 ;;; is the up link for the resulting frame object, and it is null when
716 ;;; we call this to get the top of the stack.
718 ;;; The current frame contains the pointer to the temporally previous
719 ;;; frame we want, and the current frame contains the pc at which we
720 ;;; will continue executing upon returning to that previous frame.
722 ;;; Note: Sometimes LRA is actually a fixnum. This happens when lisp
723 ;;; calls into C. In this case, the code object is stored on the stack
724 ;;; after the LRA, and the LRA is the word offset.
726 (defun compute-calling-frame (caller lra up-frame
&optional savedp
)
727 (declare (type system-area-pointer caller
)
729 (/noshow0
"entering COMPUTE-CALLING-FRAME")
730 (when (control-stack-pointer-valid-p caller
)
732 (multiple-value-bind (code pc-offset escaped
)
734 (multiple-value-bind (word-offset code
)
736 (let ((fp (frame-pointer up-frame
)))
738 (stack-ref fp
(1+ lra-save-offset
))))
739 (values (get-header-data lra
)
740 (lra-code-header lra
)))
743 (* (1+ (- word-offset
(code-header-words code
)))
746 (values :foreign-function
749 (find-escaped-frame caller
))
750 (if (and (code-component-p code
)
751 (eq (%code-debug-info code
) :bogus-lra
))
752 (let ((real-lra (code-header-ref code real-lra-slot
)))
753 (compute-calling-frame caller real-lra up-frame
))
754 (let ((d-fun (case code
756 (make-bogus-debug-fun
757 "undefined function"))
759 (make-bogus-debug-fun
760 (foreign-function-backtrace-name
761 (int-sap (get-lisp-obj-address lra
)))))
763 (make-bogus-debug-fun
764 "bogus stack frame"))
766 (debug-fun-from-pc code pc-offset
)))))
767 (/noshow0
"returning MAKE-COMPILED-FRAME from COMPUTE-CALLING-FRAME")
768 (make-compiled-frame caller up-frame d-fun
769 (code-location-from-pc d-fun pc-offset
771 (if up-frame
(1+ (frame-number up-frame
)) 0)
775 (defun compute-calling-frame (caller ra up-frame
&optional savedp
)
776 (declare (type system-area-pointer caller ra
))
777 (/noshow0
"entering COMPUTE-CALLING-FRAME")
778 (when (control-stack-pointer-valid-p caller
)
780 ;; First check for an escaped frame.
781 (multiple-value-bind (code pc-offset escaped off-stack
)
782 (find-escaped-frame caller
)
785 ;; If it's escaped it may be a function end breakpoint trap.
786 (when (and (code-component-p code
)
787 (eq (%code-debug-info code
) :bogus-lra
))
788 ;; If :bogus-lra grab the real lra.
789 (setq pc-offset
(code-header-ref
790 code
(1+ real-lra-slot
)))
791 (setq code
(code-header-ref code real-lra-slot
))
794 (multiple-value-setq (pc-offset code
)
795 (compute-lra-data-from-pc ra
))
797 (setf code
:foreign-function
799 (let ((d-fun (case code
801 (make-bogus-debug-fun
802 "undefined function"))
804 (make-bogus-debug-fun
805 (foreign-function-backtrace-name ra
)))
807 (make-bogus-debug-fun
808 "bogus stack frame"))
810 (debug-fun-from-pc code pc-offset escaped
)))))
811 (/noshow0
"returning MAKE-COMPILED-FRAME from COMPUTE-CALLING-FRAME")
812 (make-compiled-frame caller up-frame d-fun
813 (code-location-from-pc d-fun pc-offset
815 (if up-frame
(1+ (frame-number up-frame
)) 0)
816 ;; If we have an interrupt-context that's not on
817 ;; our stack at all, and we're computing the
818 ;; from from a saved FP, we're probably looking
819 ;; at an interrupted syscall.
820 (or escaped
(and savedp off-stack
)))))))
822 (defun nth-interrupt-context (n)
823 (declare (muffle-conditions t
))
824 (declare (type (unsigned-byte 32) n
)
825 (optimize (speed 3) (safety 0)))
826 (sb!alien
:sap-alien
(sb!vm
::current-thread-offset-sap
827 (+ sb
!vm
::thread-interrupt-contexts-offset
832 ;;; On SB-DYNAMIC-CORE symbols which come from the runtime go through
833 ;;; an indirection table, but the debugger needs to know the actual
835 (defun static-foreign-symbol-address (name)
837 (find-dynamic-foreign-symbol-address name
)
839 (foreign-symbol-address name
))
842 (defun static-foreign-symbol-sap (name)
843 (int-sap (static-foreign-symbol-address name
)))
846 (defun find-escaped-frame (frame-pointer)
847 (declare (type system-area-pointer frame-pointer
))
848 (/noshow0
"entering FIND-ESCAPED-FRAME")
849 (dotimes (index *free-interrupt-context-index
* (values nil
0 nil
))
850 (let* ((context (nth-interrupt-context index
))
851 (cfp (int-sap (context-register context sb
!vm
::cfp-offset
))))
852 (/noshow0
"got CONTEXT")
853 (unless (control-stack-pointer-valid-p cfp
)
854 (return (values nil nil nil t
)))
855 (when (sap= frame-pointer cfp
)
857 (/noshow0
"in WITHOUT-GCING")
858 (let* ((pc (context-pc context
))
859 (component-ptr (component-ptr-from-pc pc
))
860 (code (unless (sap= component-ptr
(int-sap #x0
))
861 (component-from-component-ptr component-ptr
))))
862 (/noshow0
"got CODE")
864 ;; KLUDGE: Detect undefined functions by a range-check
865 ;; against the trampoline address and the following
866 ;; function in the runtime.
867 (return (values code
0 context
)))
868 (let* ((code-header-len (* (code-header-words code
)
872 (- (get-lisp-obj-address code
)
873 sb
!vm
:other-pointer-lowtag
)
875 (/noshow
"got PC-OFFSET")
876 (unless (<= 0 pc-offset
(%code-code-size code
))
877 ;; We were in an assembly routine. Therefore, use the
880 ;; FIXME: Should this be WARN or ERROR or what?
881 (format t
"** pc-offset ~S not in code obj ~S?~%"
883 (/noshow0
"returning from FIND-ESCAPED-FRAME")
885 (values code pc-offset context
)))))))))
888 (defun find-escaped-frame (frame-pointer)
889 (declare (type system-area-pointer frame-pointer
))
890 (/noshow0
"entering FIND-ESCAPED-FRAME")
891 (dotimes (index *free-interrupt-context-index
* (values nil
0 nil
))
892 (let ((scp (nth-interrupt-context index
)))
894 (when (= (sap-int frame-pointer
)
895 (sb!vm
:context-register scp sb
!vm
::cfp-offset
))
897 (/noshow0
"in WITHOUT-GCING")
898 (let ((code (code-object-from-bits
899 (sb!vm
:context-register scp sb
!vm
::code-offset
))))
900 (/noshow0
"got CODE")
902 (return (values code
0 scp
)))
903 (let* ((code-header-len (* (code-header-words code
)
906 (- (sap-int (sb!vm
:context-pc scp
))
907 (- (get-lisp-obj-address code
)
908 sb
!vm
:other-pointer-lowtag
)
910 (let ((code-size (%code-code-size code
)))
911 (unless (<= 0 pc-offset code-size
)
912 ;; We were in an assembly routine.
913 (multiple-value-bind (new-pc-offset computed-return
)
914 (find-pc-from-assembly-fun code scp
)
915 (setf pc-offset new-pc-offset
)
916 (unless (<= 0 pc-offset code-size
)
918 "Set PC-OFFSET to zero and continue backtrace."
921 "~@<PC-OFFSET (~D) not in code object. Frame details:~
922 ~2I~:@_PC: #X~X~:@_CODE: ~S~:@_CODE FUN: ~S~:@_LRA: ~
923 #X~X~:@_COMPUTED RETURN: #X~X.~:>"
926 (sap-int (sb!vm
:context-pc scp
))
928 (%code-entry-point code
0)
930 (sb!vm
:context-register scp sb
!vm
::lra-offset
)
932 (stack-ref frame-pointer lra-save-offset
)
934 ;; We failed to pinpoint where PC is, but set
935 ;; pc-offset to 0 to keep the backtrace from
937 (setf pc-offset
0)))))
938 (/noshow0
"returning from FIND-ESCAPED-FRAME")
940 (if (eq (%code-debug-info code
) :bogus-lra
)
941 (let ((real-lra (code-header-ref code
943 (values (lra-code-header real-lra
)
944 (get-header-data real-lra
)
946 (values code pc-offset scp
))))))))))
949 (defun find-pc-from-assembly-fun (code scp
)
950 "Finds the PC for the return from an assembly routine properly.
951 For some architectures (such as PPC) this will not be the $LRA
953 (let ((return-machine-address (sb!vm
::return-machine-address scp
))
954 (code-header-len (* (code-header-words code
) sb
!vm
:n-word-bytes
)))
955 (values (- return-machine-address
956 (- (get-lisp-obj-address code
)
957 sb
!vm
:other-pointer-lowtag
)
959 return-machine-address
)))
961 ;;; Find the code object corresponding to the object represented by
962 ;;; bits and return it. We assume bogus functions correspond to the
963 ;;; undefined-function.
965 (defun code-object-from-bits (bits)
966 (declare (type word bits
))
967 (let ((object (make-lisp-obj bits nil
)))
968 (if (functionp object
)
969 (or (fun-code-header object
)
971 (let ((lowtag (lowtag-of object
)))
972 (when (= lowtag sb
!vm
:other-pointer-lowtag
)
973 (let ((widetag (widetag-of object
)))
974 (cond ((= widetag sb
!vm
:code-header-widetag
)
976 ((= widetag sb
!vm
:return-pc-widetag
)
977 (lra-code-header object
))
983 (defun find-assembly-routine (component pc
)
984 (let* ((start (sap-int (code-instructions component
)))
988 (loop for name being the hash-key of sb
!fasl
:*assembler-routines
*
989 using
(hash-value address
)
990 when
(and (<= start address end
)
992 (< (- end address
) min-diff
)))
993 do
(setf min-name name
994 min-diff
(- end address
)))
997 (defun compiled-debug-fun-from-pc (debug-info pc
&optional escaped
)
998 (let* ((fun-map (sb!c
::compiled-debug-info-fun-map debug-info
))
999 (len (length fun-map
)))
1000 (declare (type simple-vector fun-map
))
1004 (first-elsewhere-pc (sb!c
::compiled-debug-fun-elsewhere-pc
1007 (if escaped
;; See the comment below
1008 (>= pc first-elsewhere-pc
)
1009 (> pc first-elsewhere-pc
))))
1010 (declare (type sb
!int
:index i
))
1013 (let ((next-pc (if elsewhere-p
1014 (sb!c
::compiled-debug-fun-elsewhere-pc
1015 (svref fun-map
(1+ i
)))
1016 (svref fun-map i
))))
1019 ;; Non-escaped frame means that this frame calls something.
1020 ;; And the PC points to where something should return.
1021 ;; The return adress may be in the next
1022 ;; function, e.g. in local tail calls the
1023 ;; function will be entered just after the
1025 ;; See debug.impure.lisp/:local-tail-call for a test-case
1027 (return (svref fun-map
(1- i
))))
1030 ;;; This returns a COMPILED-DEBUG-FUN for COMPONENT and PC. We fetch the
1031 ;;; SB!C::DEBUG-INFO and run down its FUN-MAP to get a
1032 ;;; SB!C::COMPILED-DEBUG-FUN from the PC. The result only needs to
1033 ;;; reference the COMPONENT, for function constants, and the
1034 ;;; SB!C::COMPILED-DEBUG-FUN.
1035 (defun debug-fun-from-pc (component pc
&optional
(escaped t
))
1036 (let ((info (%code-debug-info component
)))
1039 (let ((routine (find-assembly-routine component pc
)))
1040 (make-bogus-debug-fun (cond ((not routine
)
1041 "no debug information for frame")
1042 ((memq routine
'(sb!vm
::undefined-tramp
1043 sb
!vm
::undefined-alien-tramp
))
1044 "undefined function")
1046 ((eq info
:bogus-lra
)
1047 (make-bogus-debug-fun "function end breakpoint"))
1049 (make-compiled-debug-fun (compiled-debug-fun-from-pc info pc escaped
) component
)))))
1051 ;;; This returns a code-location for the COMPILED-DEBUG-FUN,
1052 ;;; DEBUG-FUN, and the pc into its code vector. If we stopped at a
1053 ;;; breakpoint, find the CODE-LOCATION for that breakpoint. Otherwise,
1054 ;;; make an :UNSURE code location, so it can be filled in when we
1055 ;;; figure out what is going on.
1056 (defun code-location-from-pc (debug-fun pc escaped
)
1057 (or (and (compiled-debug-fun-p debug-fun
)
1059 (let ((data (breakpoint-data
1060 (compiled-debug-fun-component debug-fun
)
1062 (when (and data
(breakpoint-data-breakpoints data
))
1063 (let ((what (breakpoint-what
1064 (first (breakpoint-data-breakpoints data
)))))
1065 (when (compiled-code-location-p what
)
1067 (make-compiled-code-location pc debug-fun
)))
1069 ;;; Return an alist mapping catch tags to CODE-LOCATIONs. These are
1070 ;;; CODE-LOCATIONs at which execution would continue with frame as the
1071 ;;; top frame if someone threw to the corresponding tag.
1072 (defun frame-catches (frame)
1073 (let ((catch (descriptor-sap sb
!vm
:*current-catch-block
*))
1074 (reversed-result nil
)
1075 (fp (frame-pointer frame
)))
1076 (loop until
(zerop (sap-int catch
))
1077 finally
(return (nreverse reversed-result
))
1082 (* sb
!vm
:catch-block-cfp-slot
1083 sb
!vm
:n-word-bytes
))
1087 (* sb
!vm
:catch-block-cfp-slot
1088 sb
!vm
:n-word-bytes
))))
1089 (let* (#!-
(or x86 x86-64
)
1090 (lra (stack-ref catch sb
!vm
:catch-block-entry-pc-slot
))
1093 catch
(* sb
!vm
:catch-block-entry-pc-slot
1094 sb
!vm
:n-word-bytes
)))
1097 (stack-ref catch sb
!vm
:catch-block-code-slot
))
1099 (component (component-from-component-ptr
1100 (component-ptr-from-pc ra
)))
1103 (* (- (1+ (get-header-data lra
))
1104 (code-header-words component
))
1108 (- (get-lisp-obj-address component
)
1109 sb
!vm
:other-pointer-lowtag
)
1110 (* (code-header-words component
) sb
!vm
:n-word-bytes
))))
1111 (push (cons #!-
(or x86 x86-64
)
1112 (stack-ref catch sb
!vm
:catch-block-tag-slot
)
1115 (sap-ref-word catch
(* sb
!vm
:catch-block-tag-slot
1116 sb
!vm
:n-word-bytes
)))
1117 (make-compiled-code-location
1118 offset
(frame-debug-fun frame
)))
1123 (* sb
!vm
:catch-block-previous-catch-slot
1124 sb
!vm
:n-word-bytes
))
1128 (* sb
!vm
:catch-block-previous-catch-slot
1129 sb
!vm
:n-word-bytes
)))))))
1131 ;;; Modify the value of the OLD-TAG catches in FRAME to NEW-TAG
1132 (defun replace-frame-catch-tag (frame old-tag new-tag
)
1133 (let ((catch (descriptor-sap sb
!vm
:*current-catch-block
*))
1134 (fp (frame-pointer frame
)))
1135 (loop until
(zerop (sap-int catch
))
1139 (* sb
!vm
:catch-block-cfp-slot
1140 sb
!vm
:n-word-bytes
))
1144 (* sb
!vm
:catch-block-cfp-slot
1145 sb
!vm
:n-word-bytes
))))
1148 (stack-ref catch sb
!vm
:catch-block-tag-slot
)
1151 (sap-ref-word catch
(* sb
!vm
:catch-block-tag-slot
1152 sb
!vm
:n-word-bytes
)))))
1153 (when (eq current-tag old-tag
)
1155 (setf (stack-ref catch sb
!vm
:catch-block-tag-slot
) new-tag
)
1157 (setf (sap-ref-word catch
(* sb
!vm
:catch-block-tag-slot
1158 sb
!vm
:n-word-bytes
))
1159 (get-lisp-obj-address new-tag
)))))
1163 (* sb
!vm
:catch-block-previous-catch-slot
1164 sb
!vm
:n-word-bytes
))
1168 (* sb
!vm
:catch-block-previous-catch-slot
1169 sb
!vm
:n-word-bytes
)))))))
1173 ;;;; operations on DEBUG-FUNs
1175 ;;; Execute the forms in a context with BLOCK-VAR bound to each
1176 ;;; DEBUG-BLOCK in DEBUG-FUN successively. Result is an optional
1177 ;;; form to execute for return values, and DO-DEBUG-FUN-BLOCKS
1178 ;;; returns nil if there is no result form. This signals a
1179 ;;; NO-DEBUG-BLOCKS condition when the DEBUG-FUN lacks
1180 ;;; DEBUG-BLOCK information.
1181 (defmacro do-debug-fun-blocks
((block-var debug-fun
&optional result
)
1183 (let ((blocks (gensym))
1185 `(let ((,blocks
(debug-fun-debug-blocks ,debug-fun
)))
1186 (declare (simple-vector ,blocks
))
1187 (dotimes (,i
(length ,blocks
) ,result
)
1188 (let ((,block-var
(svref ,blocks
,i
)))
1191 ;;; Execute body in a context with VAR bound to each DEBUG-VAR in
1192 ;;; DEBUG-FUN. This returns the value of executing result (defaults to
1193 ;;; nil). This may iterate over only some of DEBUG-FUN's variables or
1194 ;;; none depending on debug policy; for example, possibly the
1195 ;;; compilation only preserved argument information.
1196 (defmacro do-debug-fun-vars
((var debug-fun
&optional result
) &body body
)
1197 (let ((vars (gensym))
1199 `(let ((,vars
(debug-fun-debug-vars ,debug-fun
)))
1200 (declare (type (or null simple-vector
) ,vars
))
1202 (dotimes (,i
(length ,vars
) ,result
)
1203 (let ((,var
(svref ,vars
,i
)))
1207 (defun function-start-pc-offset (function)
1208 (let* ((fun (%fun-fun function
))
1209 (code (fun-code-header fun
)))
1210 (- (* (fun-word-offset fun
) n-word-bytes
)
1211 (code-header-words code
))))
1213 ;;; Return the object of type FUNCTION associated with the DEBUG-FUN,
1214 ;;; or NIL if the function is unavailable or is non-existent as a user
1215 ;;; callable function object.
1216 (defun debug-fun-fun (debug-fun)
1217 (let ((cached-value (debug-fun-%function debug-fun
)))
1218 (if (eq cached-value
:unparsed
)
1219 (setf (debug-fun-%function debug-fun
)
1220 (etypecase debug-fun
1223 (loop with component
= (compiled-debug-fun-component debug-fun
)
1224 with start-pc
= (sb!c
::compiled-debug-fun-start-pc
1225 (compiled-debug-fun-compiler-debug-fun debug-fun
))
1226 for i below
(code-n-entries component
)
1227 for entry
= (%code-entry-point component i
)
1228 while
(> start-pc
(function-start-pc-offset entry
))
1229 do
(setf result entry
))
1231 (bogus-debug-fun nil
)))
1234 ;;; Return the name of the function represented by DEBUG-FUN. This may
1235 ;;; be a string or a cons; do not assume it is a symbol.
1236 (defun debug-fun-name (debug-fun &optional
(pretty t
))
1237 (declare (type debug-fun debug-fun
) (ignorable pretty
))
1238 (etypecase debug-fun
1240 (let ((name (sb!c
::compiled-debug-fun-name
1241 (compiled-debug-fun-compiler-debug-fun debug-fun
))))
1242 ;; Frames named (.EVAL. special-operator) should show the operator name
1243 ;; in backtraces, but if the debugger needs to detect that the frame is
1244 ;; interpreted for other purposes, it can specify PRETTY = NIL.
1245 (cond #!+sb-fasteval
1246 ((and (typep name
'(cons (eql sb
!interpreter
::.eval.
)))
1248 (if (singleton-p (cdr name
)) (cadr name
) (cdr name
)))
1251 (bogus-debug-fun-%name debug-fun
))))
1253 (defun interrupted-frame-error (frame)
1254 (declare (special sb
!kernel
::*current-internal-error
*))
1255 (when (and (compiled-frame-p frame
)
1256 (compiled-frame-escaped frame
)
1257 sb
!kernel
::*current-internal-error
*
1258 (array-in-bounds-p sb
!c
:+backend-internal-errors
+
1259 sb
!kernel
::*current-internal-error
*))
1260 (cadr (svref sb
!c
:+backend-internal-errors
+
1261 sb
!kernel
::*current-internal-error
*))))
1263 (defun all-args-available-p (frame)
1264 (let ((error (interrupted-frame-error frame
))
1265 (df (frame-debug-fun frame
)))
1266 (or #!+precise-arg-count-error
1267 (and (eq error
'invalid-arg-count-error
)
1268 (eq (debug-fun-kind df
) :external
))
1269 (and (eq error
'undefined-fun-error
)
1270 (bogus-debug-fun-p df
)))))
1272 ;; Return the name of the closure, if named, otherwise nil.
1273 (defun debug-fun-closure-name (debug-fun frame
)
1274 (unless (typep debug-fun
'compiled-debug-fun
)
1275 (return-from debug-fun-closure-name nil
))
1276 (let ((compiler-debug-fun (compiled-debug-fun-compiler-debug-fun debug-fun
)))
1278 ;; Frames named (.APPLY. something) are interpreted function applicators.
1279 ;; Show them as the name of the interpreted function being applied.
1281 ((let ((name (sb!c
::compiled-debug-fun-name compiler-debug-fun
)))
1282 (when (typep name
'(cons (eql sb
!interpreter
::.apply.
)))
1283 ;; Find a variable named FUN.
1284 (awhen (car (debug-fun-symbol-vars debug-fun
'sb
!interpreter
::fun
))
1285 (let ((val (debug-var-value it frame
))) ; Ensure it's a function
1286 (when (typep val
'sb
!interpreter
:interpreted-function
)
1287 (%fun-name val
))))))) ; Get its name
1288 ((sb!c
::compiled-debug-fun-closure-save compiler-debug-fun
)
1289 (sb!impl
::closure-name
1290 (if (all-args-available-p frame
)
1291 (sub-access-debug-var-slot (frame-pointer frame
)
1293 (compiled-frame-escaped frame
))
1294 (sub-access-debug-var-slot (frame-pointer frame
) it
)))))))
1296 ;;; Return a DEBUG-FUN that represents debug information for FUN.
1297 (defun fun-debug-fun (fun)
1298 (declare (type function fun
))
1299 (let ((simple-fun (%fun-fun fun
)))
1300 (let* ((name (%simple-fun-name simple-fun
))
1301 (component (fun-code-header simple-fun
))
1304 (and (sb!c
::compiled-debug-fun-p x
)
1305 (eq (sb!c
::compiled-debug-fun-name x
) name
)
1306 (eq (sb!c
::compiled-debug-fun-kind x
) nil
)))
1307 (sb!c
::compiled-debug-info-fun-map
1308 (%code-debug-info component
)))))
1310 (make-compiled-debug-fun res component
)
1311 ;; KLUDGE: comment from CMU CL:
1312 ;; This used to be the non-interpreted branch, but
1313 ;; William wrote it to return the debug-fun of fun's XEP
1314 ;; instead of fun's debug-fun. The above code does this
1315 ;; more correctly, but it doesn't get or eliminate all
1316 ;; appropriate cases. It mostly works, and probably
1317 ;; works for all named functions anyway.
1319 (debug-fun-from-pc component
1320 (* (- (fun-word-offset simple-fun
)
1321 (code-header-words component
))
1322 sb
!vm
:n-word-bytes
))))))
1324 ;;; Return the kind of the function, which is one of :OPTIONAL, :MORE
1325 ;;; :EXTERNAL, :TOPLEVEL, :CLEANUP, or NIL.
1326 (defun debug-fun-kind (debug-fun)
1327 ;; FIXME: This "is one of" information should become part of the function
1328 ;; declamation, not just a doc string
1329 (etypecase debug-fun
1331 (sb!c
::compiled-debug-fun-kind
1332 (compiled-debug-fun-compiler-debug-fun debug-fun
)))
1336 ;;; Is there any variable information for DEBUG-FUN?
1337 (defun debug-var-info-available (debug-fun)
1338 (not (not (debug-fun-debug-vars debug-fun
))))
1340 ;;; Return a list of DEBUG-VARs in DEBUG-FUN having the same name
1341 ;;; and package as SYMBOL. If SYMBOL is uninterned, then this returns
1342 ;;; a list of DEBUG-VARs without package names and with the same name
1343 ;;; as symbol. The result of this function is limited to the
1344 ;;; availability of variable information in DEBUG-FUN; for
1345 ;;; example, possibly DEBUG-FUN only knows about its arguments.
1346 (defun debug-fun-symbol-vars (debug-fun symbol
)
1347 (let ((vars (ambiguous-debug-vars debug-fun
(symbol-name symbol
)))
1348 (package (and (symbol-package symbol
)
1349 (package-name (symbol-package symbol
)))))
1350 (delete-if (if (stringp package
)
1352 (let ((p (debug-var-package-name var
)))
1353 (or (not (stringp p
))
1354 (string/= p package
))))
1356 (stringp (debug-var-package-name var
))))
1359 ;;; Return a list of DEBUG-VARs in DEBUG-FUN whose names contain
1360 ;;; NAME-PREFIX-STRING as an initial substring. The result of this
1361 ;;; function is limited to the availability of variable information in
1362 ;;; debug-fun; for example, possibly debug-fun only knows
1363 ;;; about its arguments.
1364 (defun ambiguous-debug-vars (debug-fun name-prefix-string
)
1365 (declare (simple-string name-prefix-string
))
1366 (let ((variables (debug-fun-debug-vars debug-fun
)))
1367 (declare (type (or null simple-vector
) variables
))
1369 (let* ((len (length variables
))
1370 (prefix-len (length name-prefix-string
))
1371 (pos (find-var name-prefix-string variables len
))
1374 ;; Find names from pos to variable's len that contain prefix.
1375 (do ((i pos
(1+ i
)))
1377 (let* ((var (svref variables i
))
1378 (name (debug-var-symbol-name var
))
1379 (name-len (length name
)))
1380 (declare (simple-string name
))
1381 (when (/= (or (string/= name-prefix-string name
1382 :end1 prefix-len
:end2 name-len
)
1387 (setq res
(nreverse res
)))
1390 ;;; This returns a position in VARIABLES for one containing NAME as an
1391 ;;; initial substring. END is the length of VARIABLES if supplied.
1392 (defun find-var (name variables
&optional end
)
1393 (declare (simple-vector variables
)
1394 (simple-string name
))
1395 (let ((name-len (length name
)))
1396 (position name variables
1398 (let* ((y (debug-var-symbol-name y
))
1400 (declare (simple-string y
))
1401 (and (>= y-len name-len
)
1402 (string= x y
:end1 name-len
:end2 name-len
))))
1403 :end
(or end
(length variables
)))))
1405 ;;; Return a list representing the lambda-list for DEBUG-FUN. The
1406 ;;; list has the following structure:
1407 ;;; (required-var1 required-var2
1409 ;;; (:optional var3 suppliedp-var4)
1410 ;;; (:optional var5)
1412 ;;; (:rest var6) (:rest var7)
1414 ;;; (:keyword keyword-symbol var8 suppliedp-var9)
1415 ;;; (:keyword keyword-symbol var10)
1418 ;;; Each VARi is a DEBUG-VAR; however it may be the symbol :DELETED if
1419 ;;; it is unreferenced in DEBUG-FUN. This signals a
1420 ;;; LAMBDA-LIST-UNAVAILABLE condition when there is no argument list
1422 (defun debug-fun-lambda-list (debug-fun)
1423 (etypecase debug-fun
1424 (compiled-debug-fun (compiled-debug-fun-lambda-list debug-fun
))
1425 (bogus-debug-fun nil
)))
1427 ;;; Note: If this has to compute the lambda list, it caches it in DEBUG-FUN.
1428 (defun compiled-debug-fun-lambda-list (debug-fun)
1429 (let ((lambda-list (debug-fun-%lambda-list debug-fun
)))
1430 (cond ((eq lambda-list
:unparsed
)
1431 (multiple-value-bind (args argsp
)
1432 (parse-compiled-debug-fun-lambda-list debug-fun
)
1433 (setf (debug-fun-%lambda-list debug-fun
) args
)
1436 (debug-signal 'lambda-list-unavailable
1437 :debug-fun debug-fun
))))
1439 ((bogus-debug-fun-p debug-fun
)
1441 ((sb!c
::compiled-debug-fun-arguments
1442 (compiled-debug-fun-compiler-debug-fun debug-fun
))
1443 ;; If the packed information is there (whether empty or not) as
1444 ;; opposed to being nil, then returned our cached value (nil).
1447 ;; Our cached value is nil, and the packed lambda-list information
1448 ;; is nil, so we don't have anything available.
1449 (debug-signal 'lambda-list-unavailable
1450 :debug-fun debug-fun
)))))
1452 ;;; COMPILED-DEBUG-FUN-LAMBDA-LIST calls this when a
1453 ;;; COMPILED-DEBUG-FUN has no lambda list information cached. It
1454 ;;; returns the lambda list as the first value and whether there was
1455 ;;; any argument information as the second value. Therefore,
1456 ;;; (VALUES NIL T) means there were no arguments, but (VALUES NIL NIL)
1457 ;;; means there was no argument information.
1458 (defun parse-compiled-debug-fun-lambda-list (debug-fun)
1459 (let ((args (sb!c
::compiled-debug-fun-arguments
1460 (compiled-debug-fun-compiler-debug-fun debug-fun
))))
1465 (values (coerce (debug-fun-debug-vars debug-fun
) 'list
)
1468 (values (parse-compiled-debug-fun-lambda-list/args-available
1469 (debug-fun-debug-vars debug-fun
) args
)
1472 (defun parse-compiled-debug-fun-lambda-list/args-available
(vars args
)
1473 (declare (type (or null simple-vector
) vars
))
1479 (flet ((push-var (tag-and-info &optional var-count
)
1481 (append tag-and-info
1482 (loop :repeat var-count
:collect
1483 (compiled-debug-fun-lambda-list-var
1484 args
(incf i
) vars
)))
1487 (var-or-deleted (index-or-deleted)
1488 (if (eq index-or-deleted sb
!c
::debug-info-var-deleted
)
1490 (svref vars index-or-deleted
))))
1493 :for ele
= (aref args i
) :do
1495 ((eq ele sb
!c
::debug-info-var-optional
)
1497 ((eq ele sb
!c
::debug-info-var-rest
)
1498 (push-var '(:rest
) 1))
1499 ;; The next two args are the &MORE arg context and
1501 ((eq ele sb
!c
::debug-info-var-more
)
1502 (push-var '(:more
) 2))
1503 ;; SUPPLIED-P var immediately following keyword or
1504 ;; optional. Stick the extra var in the result element
1505 ;; representing the keyword or optional, which is the
1507 ((eq ele sb
!c
::debug-info-var-supplied-p
)
1508 (push-var (pop result
) 1))
1509 ;; The keyword of a keyword parameter. Store it so the next
1510 ;; element can be used to form a (:keyword KEYWORD VALUE)
1512 ((typep ele
'symbol
)
1514 ;; The previous element was the keyword of a keyword
1515 ;; parameter and is stored in KEYWORD. The current element
1516 ;; is the index of the value (or a deleted
1517 ;; marker). Construct and push the complete entry.
1519 (push-var (list :keyword keyword
(var-or-deleted ele
))))
1520 ;; We saw an optional marker, so the following non-symbols
1521 ;; are indexes (or deleted markers) indicating optional
1524 (push-var (list :optional
(var-or-deleted ele
))))
1525 ;; Deleted required, optional or keyword argument.
1526 ((eq ele sb
!c
::debug-info-var-deleted
)
1527 (push-var :deleted
))
1528 ;; Required arg at beginning of args array.
1530 (push-var (svref vars ele
))))
1532 :finally
(return (nreverse result
))))))
1534 ;;; This is used in COMPILED-DEBUG-FUN-LAMBDA-LIST.
1535 (defun compiled-debug-fun-lambda-list-var (args i vars
)
1536 (declare (type (simple-array * (*)) args
)
1537 (simple-vector vars
))
1538 (let ((ele (aref args i
)))
1539 (cond ((typep ele
'index
) (svref vars ele
))
1540 ((eq ele sb
!c
::debug-info-var-deleted
) :deleted
)
1541 (t (error "malformed arguments description")))))
1543 (defun compiled-debug-fun-debug-info (debug-fun)
1544 (%code-debug-info
(compiled-debug-fun-component debug-fun
)))
1546 ;;;; unpacking variable and basic block data
1548 ;;; The argument is a debug internals structure. This returns the
1549 ;;; DEBUG-BLOCKs for DEBUG-FUN, regardless of whether we have unpacked
1550 ;;; them yet. It signals a NO-DEBUG-BLOCKS condition if it can't
1551 ;;; return the blocks.
1552 (defun debug-fun-debug-blocks (debug-fun)
1553 (let ((blocks (debug-fun-blocks debug-fun
)))
1554 (cond ((eq blocks
:unparsed
)
1555 (setf (debug-fun-blocks debug-fun
)
1556 (parse-debug-blocks debug-fun
))
1557 (unless (debug-fun-blocks debug-fun
)
1558 (debug-signal 'no-debug-blocks
1559 :debug-fun debug-fun
))
1560 (debug-fun-blocks debug-fun
))
1563 (debug-signal 'no-debug-blocks
1564 :debug-fun debug-fun
)))))
1566 ;;; Return a SIMPLE-VECTOR of DEBUG-BLOCKs or NIL. NIL indicates there
1567 ;;; was no basic block information.
1568 (defun parse-debug-blocks (debug-fun)
1569 (etypecase debug-fun
1571 (parse-compiled-debug-blocks debug-fun
))
1573 (debug-signal 'no-debug-blocks
:debug-fun debug-fun
))))
1575 ;;; This does some of the work of PARSE-DEBUG-BLOCKS.
1576 (defun parse-compiled-debug-blocks (debug-fun)
1577 (macrolet ((aref+ (a i
) `(prog1 (aref ,a
,i
) (incf ,i
))))
1578 (let* ((var-count (length (debug-fun-debug-vars debug-fun
)))
1579 (compiler-debug-fun (compiled-debug-fun-compiler-debug-fun
1581 (blocks (or (sb!c
::compiled-debug-fun-blocks compiler-debug-fun
)
1582 (return-from parse-compiled-debug-blocks nil
)))
1583 ;; KLUDGE: 8 is a hard-wired constant in the compiler for the
1584 ;; element size of the packed binary representation of the
1586 (live-set-len (ceiling var-count
8))
1587 (elsewhere-pc (sb!c
::compiled-debug-fun-elsewhere-pc compiler-debug-fun
))
1589 (len (length blocks
))
1593 (block (make-compiled-debug-block))
1595 (flet ((new-block ()
1597 (setf (compiled-debug-block-code-locations block
)
1598 (coerce (nreverse (shiftf locations nil
))
1600 (compiled-debug-block-elsewhere-p block
)
1602 (push block result-blocks
)
1603 (setf block
(make-compiled-debug-block)))))
1608 (let* ((flags (aref+ blocks i
))
1609 (kind (svref sb
!c
::+compiled-code-location-kinds
+
1610 (ldb (byte 4 0) flags
)))
1612 (sb!c
:read-var-integerf blocks i
)))
1614 (if (logtest sb
!c
::compiled-code-location-zero-form-number flags
)
1616 (sb!c
:read-var-integerf blocks i
)))
1618 (if (logtest sb
!c
::compiled-code-location-live flags
)
1619 (sb!c
:read-packed-bit-vector live-set-len blocks i
)
1620 (make-array (* live-set-len
8) :element-type
'bit
)))
1622 (if (logtest sb
!c
::compiled-code-location-stepping flags
)
1623 (sb!c
:read-var-string blocks i
)
1626 (and (logtest sb
!c
::compiled-code-location-context flags
)
1627 (svref (sb!c
::compiled-debug-info-contexts
1628 (%code-debug-info
(compiled-debug-fun-component debug-fun
)))
1629 (sb!c
:read-var-integerf blocks i
)))))
1630 (when (or (memq kind
'(:block-start
:non-local-entry
))
1631 (and (not elsewhere-p
)
1633 (setf elsewhere-p t
)))
1635 (push (make-known-code-location
1637 form-number live-set kind
1640 (setf last-pc pc
))))
1641 (coerce (nreverse result-blocks
) 'simple-vector
))))
1643 ;;; The argument is a debug internals structure. This returns NIL if
1644 ;;; there is no variable information. It returns an empty
1645 ;;; simple-vector if there were no locals in the function. Otherwise
1646 ;;; it returns a SIMPLE-VECTOR of DEBUG-VARs.
1647 (defun debug-fun-debug-vars (debug-fun)
1648 (let ((vars (debug-fun-%debug-vars debug-fun
)))
1649 (if (eq vars
:unparsed
)
1650 (setf (debug-fun-%debug-vars debug-fun
)
1651 (etypecase debug-fun
1653 (parse-compiled-debug-vars debug-fun
))
1654 (bogus-debug-fun nil
)))
1657 ;;; VARS is the parsed variables for a minimal debug function. We need
1658 ;;; to assign names of the form ARG-NNN. We must pad with leading
1659 ;;; zeros, since the arguments must be in alphabetical order.
1660 (defun assign-minimal-var-names (vars)
1661 (declare (simple-vector vars
))
1662 (let* ((len (length vars
))
1663 (width (length (format nil
"~W" (1- len
)))))
1665 (without-package-locks
1666 (setf (compiled-debug-var-symbol (svref vars i
))
1667 (intern (format nil
"ARG-~V,'0D" width i
)
1668 ;; The cross-compiler won't dump literal package
1669 ;; references because the target package objects
1670 ;; aren't created until partway through
1671 ;; cold-init. In lieu of adding smarts to the
1672 ;; build framework to handle this, we use an
1673 ;; explicit load-time-value form.
1674 (load-time-value (find-package "SB!DEBUG"))))))))
1676 ;;; Parse the packed representation of DEBUG-VARs from
1677 ;;; DEBUG-FUN's SB!C::COMPILED-DEBUG-FUN, returning a vector
1678 ;;; of DEBUG-VARs, or NIL if there was no information to parse.
1679 (defun parse-compiled-debug-vars (debug-fun)
1680 (let* ((cdebug-fun (compiled-debug-fun-compiler-debug-fun
1682 (packed-vars (sb!c
::compiled-debug-fun-vars cdebug-fun
))
1683 (args-minimal (eq (sb!c
::compiled-debug-fun-arguments cdebug-fun
)
1687 (buffer (make-array 0 :fill-pointer
0 :adjustable t
)))
1688 ((>= i
(length packed-vars
))
1689 (let ((result (coerce buffer
'simple-vector
)))
1691 (assign-minimal-var-names result
))
1693 (flet ((geti () (prog1 (aref packed-vars i
) (incf i
))))
1694 (let* ((flags (geti))
1695 (minimal (logtest sb
!c
::compiled-debug-var-minimal-p flags
))
1696 (deleted (logtest sb
!c
::compiled-debug-var-deleted-p flags
))
1697 (more-context-p (logtest sb
!c
::compiled-debug-var-more-context-p flags
))
1698 (more-count-p (logtest sb
!c
::compiled-debug-var-more-count-p flags
))
1699 (indirect-p (logtest sb
!c
::compiled-debug-var-indirect-p flags
))
1700 (live (logtest sb
!c
::compiled-debug-var-environment-live
1702 (save (logtest sb
!c
::compiled-debug-var-save-loc-p flags
))
1703 (symbol (if (or more-count-p
1707 (id (if (logtest sb
!c
::compiled-debug-var-id-p flags
)
1710 (sc-offset (if deleted
0
1712 #!+64-bit
(ldb (byte 27 8) flags
)))
1713 (save-sc-offset (and save
1715 #!+64-bit
(ldb (byte 27 35) flags
)))
1716 (indirect-sc-offset (and indirect-p
1718 (aver (not (and args-minimal
(not minimal
))))
1719 (vector-push-extend (make-compiled-debug-var symbol
1725 (cond (more-context-p :more-context
)
1726 (more-count-p :more-count
)))
1731 ;;; If we're sure of whether code-location is known, return T or NIL.
1732 ;;; If we're :UNSURE, then try to fill in the code-location's slots.
1733 ;;; This determines whether there is any debug-block information, and
1734 ;;; if code-location is known.
1736 ;;; ??? IF this conses closures every time it's called, then break off the
1737 ;;; :UNSURE part to get the HANDLER-CASE into another function.
1738 (defun code-location-unknown-p (basic-code-location)
1739 (ecase (code-location-%unknown-p basic-code-location
)
1743 (setf (code-location-%unknown-p basic-code-location
)
1744 (handler-case (not (fill-in-code-location basic-code-location
))
1745 (no-debug-blocks () t
))))))
1747 ;;; Return the DEBUG-BLOCK containing code-location if it is available.
1748 ;;; Some debug policies inhibit debug-block information, and if none
1749 ;;; is available, then this signals a NO-DEBUG-BLOCKS condition.
1750 (defun code-location-debug-block (basic-code-location)
1751 (let ((block (code-location-%debug-block basic-code-location
)))
1752 (if (eq block
:unparsed
)
1753 (etypecase basic-code-location
1754 (compiled-code-location
1755 (compute-compiled-code-location-debug-block basic-code-location
))
1756 ;; (There used to be more cases back before sbcl-0.7.0, when
1757 ;; we did special tricks to debug the IR1 interpreter.)
1761 ;;; Store and return BASIC-CODE-LOCATION's debug-block. We determines
1762 ;;; the correct one using the code-location's pc. We use
1763 ;;; DEBUG-FUN-DEBUG-BLOCKS to return the cached block information
1764 ;;; or signal a NO-DEBUG-BLOCKS condition. The blocks are sorted by
1765 ;;; their first code-location's pc, in ascending order. Therefore, as
1766 ;;; soon as we find a block that starts with a pc greater than
1767 ;;; basic-code-location's pc, we know the previous block contains the
1768 ;;; pc. If we get to the last block, then the code-location is either
1769 ;;; in the second to last block or the last block, and we have to be
1770 ;;; careful in determining this since the last block could be code at
1771 ;;; the end of the function. We have to check for the last block being
1772 ;;; code first in order to see how to compare the code-location's pc.
1773 (defun compute-compiled-code-location-debug-block (basic-code-location)
1774 (let* ((pc (compiled-code-location-pc basic-code-location
))
1775 (debug-fun (code-location-debug-fun
1776 basic-code-location
))
1777 (blocks (debug-fun-debug-blocks debug-fun
))
1778 (len (length blocks
)))
1779 (declare (simple-vector blocks
))
1780 (setf (code-location-%debug-block basic-code-location
)
1786 (let ((last (svref blocks end
)))
1788 ((debug-block-elsewhere-p last
)
1790 (sb!c
::compiled-debug-fun-elsewhere-pc
1791 (compiled-debug-fun-compiler-debug-fun
1793 (svref blocks
(1- end
))
1796 (compiled-code-location-pc
1797 (svref (compiled-debug-block-code-locations last
)
1799 (svref blocks
(1- end
)))
1801 (declare (type index i end
))
1803 (compiled-code-location-pc
1804 (svref (compiled-debug-block-code-locations
1807 (return (svref blocks
(1- i
)))))))))
1809 ;;; Return the CODE-LOCATION's DEBUG-SOURCE.
1810 (defun code-location-debug-source (code-location)
1811 (let ((info (compiled-debug-fun-debug-info
1812 (code-location-debug-fun code-location
))))
1813 (or (sb!c
::debug-info-source info
)
1814 (debug-signal 'no-debug-blocks
:debug-fun
1815 (code-location-debug-fun code-location
)))))
1817 ;;; Returns the number of top level forms before the one containing
1818 ;;; CODE-LOCATION as seen by the compiler in some compilation unit. (A
1819 ;;; compilation unit is not necessarily a single file, see the section
1820 ;;; on debug-sources.)
1821 (defun code-location-toplevel-form-offset (code-location)
1822 (let ((di (compiled-debug-fun-debug-info
1823 (code-location-debug-fun code-location
))))
1824 (sb!c
::compiled-debug-info-tlf-number di
)))
1826 ;;; Return the number of the form corresponding to CODE-LOCATION. The
1827 ;;; form number is derived by a walking the subforms of a top level
1828 ;;; form in depth-first order.
1829 (defun code-location-form-number (code-location)
1830 (when (code-location-unknown-p code-location
)
1831 (error 'unknown-code-location
:code-location code-location
))
1832 (let ((form-num (code-location-%form-number code-location
)))
1833 (cond ((eq form-num
:unparsed
)
1834 (etypecase code-location
1835 (compiled-code-location
1836 (unless (fill-in-code-location code-location
)
1837 ;; This check should be unnecessary. We're missing
1838 ;; debug info the compiler should have dumped.
1839 (bug "unknown code location"))
1840 (code-location-%form-number code-location
))
1841 ;; (There used to be more cases back before sbcl-0.7.0,,
1842 ;; when we did special tricks to debug the IR1
1847 ;;; Return the kind of CODE-LOCATION, one of:
1848 ;;; :INTERPRETED, :UNKNOWN-RETURN, :KNOWN-RETURN, :INTERNAL-ERROR,
1849 ;;; :NON-LOCAL-EXIT, :BLOCK-START, :CALL-SITE, :SINGLE-VALUE-RETURN,
1850 ;;; :NON-LOCAL-ENTRY
1851 (defun code-location-kind (code-location)
1852 (when (code-location-unknown-p code-location
)
1853 (error 'unknown-code-location
:code-location code-location
))
1854 (etypecase code-location
1855 (compiled-code-location
1856 (let ((kind (compiled-code-location-kind code-location
)))
1857 (cond ((not (eq kind
:unparsed
)) kind
)
1858 ((not (fill-in-code-location code-location
))
1859 ;; This check should be unnecessary. We're missing
1860 ;; debug info the compiler should have dumped.
1861 (bug "unknown code location"))
1863 (compiled-code-location-kind code-location
)))))
1864 ;; (There used to be more cases back before sbcl-0.7.0,,
1865 ;; when we did special tricks to debug the IR1
1869 ;;; This returns CODE-LOCATION's live-set if it is available. If
1870 ;;; there is no debug-block information, this returns NIL.
1871 (defun compiled-code-location-live-set (code-location)
1872 (if (code-location-unknown-p code-location
)
1874 (let ((live-set (compiled-code-location-%live-set code-location
)))
1875 (fill-in-code-location code-location
)
1876 (cond ((eq live-set
:unparsed
)
1877 (unless (fill-in-code-location code-location
)
1878 ;; This check should be unnecessary. We're missing
1879 ;; debug info the compiler should have dumped.
1881 ;; FIXME: This error and comment happen over and over again.
1882 ;; Make them a shared function.
1883 (bug "unknown code location"))
1884 (compiled-code-location-%live-set code-location
))
1887 (defun code-location-context (code-location)
1888 (unless (code-location-unknown-p code-location
)
1889 (let ((context (compiled-code-location-context code-location
)))
1890 (cond ((eq context
:unparsed
)
1891 (etypecase code-location
1892 (compiled-code-location
1893 (unless (fill-in-code-location code-location
)
1894 (bug "unknown code location"))
1895 (compiled-code-location-context code-location
))))
1898 (defun error-context ()
1899 (let ((frame sb
!debug
:*stack-top-hint
*))
1901 (code-location-context (frame-code-location frame
)))))
1903 (defun decode-arithmetic-error-operands (context)
1904 (let* ((alien-context (sb!alien
:sap-alien context
(* os-context-t
)))
1905 (fp (int-sap (context-register alien-context
1906 sb
!vm
::cfp-offset
)))
1907 (sb!debug
:*stack-top-hint
* (find-interrupted-frame))
1908 (error-context (error-context)))
1910 (values (car error-context
)
1911 (loop for x in
(cdr error-context
)
1912 collect
(if (integerp x
)
1913 (sub-access-debug-var-slot
1917 ;;; true if OBJ1 and OBJ2 are the same place in the code
1918 (defun code-location= (obj1 obj2
)
1920 (compiled-code-location
1922 (compiled-code-location
1923 (and (eq (code-location-debug-fun obj1
)
1924 (code-location-debug-fun obj2
))
1925 (sub-compiled-code-location= obj1 obj2
)))
1926 ;; (There used to be more cases back before sbcl-0.7.0,,
1927 ;; when we did special tricks to debug the IR1
1930 ;; (There used to be more cases back before sbcl-0.7.0,,
1931 ;; when we did special tricks to debug IR1-interpreted code.)
1933 (defun sub-compiled-code-location= (obj1 obj2
)
1934 (= (compiled-code-location-pc obj1
)
1935 (compiled-code-location-pc obj2
)))
1937 ;;; Fill in CODE-LOCATION's :UNPARSED slots, returning T or NIL
1938 ;;; depending on whether the code-location was known in its
1939 ;;; DEBUG-FUN's debug-block information. This may signal a
1940 ;;; NO-DEBUG-BLOCKS condition due to DEBUG-FUN-DEBUG-BLOCKS, and
1941 ;;; it assumes the %UNKNOWN-P slot is already set or going to be set.
1942 (defun fill-in-code-location (code-location)
1943 (declare (type compiled-code-location code-location
))
1944 (let* ((debug-fun (code-location-debug-fun code-location
))
1945 (blocks (debug-fun-debug-blocks debug-fun
))
1947 (declare (simple-vector blocks
))
1948 (dotimes (i (length blocks
) nil
)
1949 (let* ((block (svref blocks i
))
1950 (locations (compiled-debug-block-code-locations block
)))
1951 (declare (simple-vector locations
))
1952 (dotimes (j (length locations
))
1953 (let ((loc (svref locations j
)))
1954 (when (sub-compiled-code-location= code-location loc
)
1957 ;; There may be multiple locations in multiple blocks at a given PC, prefer
1958 ;; the :internal-error ones.
1959 (when (eq (compiled-code-location-kind loc
) :internal-error
)
1963 (setf (code-location-%debug-block code-location
)
1964 (code-location-%debug-block found
))
1965 (setf (code-location-%form-number code-location
)
1966 (code-location-%form-number found
))
1967 (setf (compiled-code-location-%live-set code-location
)
1968 (compiled-code-location-%live-set found
))
1969 (setf (compiled-code-location-kind code-location
)
1970 (compiled-code-location-kind found
))
1971 (setf (compiled-code-location-step-info code-location
)
1972 (compiled-code-location-step-info found
))
1973 (setf (compiled-code-location-context code-location
)
1974 (compiled-code-location-context found
))
1977 ;;;; operations on DEBUG-BLOCKs
1979 ;;; Execute FORMS in a context with CODE-VAR bound to each
1980 ;;; CODE-LOCATION in DEBUG-BLOCK, and return the value of RESULT.
1981 (defmacro do-debug-block-locations
((code-var debug-block
&optional result
)
1983 (let ((code-locations (gensym))
1985 `(let ((,code-locations
(debug-block-code-locations ,debug-block
)))
1986 (declare (simple-vector ,code-locations
))
1987 (dotimes (,i
(length ,code-locations
) ,result
)
1988 (let ((,code-var
(svref ,code-locations
,i
)))
1991 ;;; Return the name of the function represented by DEBUG-FUN.
1992 ;;; This may be a string or a cons; do not assume it is a symbol.
1993 (defun debug-block-fun-name (debug-block)
1994 (etypecase debug-block
1995 (compiled-debug-block
1996 (let ((code-locs (compiled-debug-block-code-locations debug-block
)))
1997 (declare (simple-vector code-locs
))
1998 (if (zerop (length code-locs
))
1999 "??? Can't get name of debug-block's function."
2001 (code-location-debug-fun (svref code-locs
0))))))
2002 ;; (There used to be more cases back before sbcl-0.7.0, when we
2003 ;; did special tricks to debug the IR1 interpreter.)
2006 (defun debug-block-code-locations (debug-block)
2007 (etypecase debug-block
2008 (compiled-debug-block
2009 (compiled-debug-block-code-locations debug-block
))
2010 ;; (There used to be more cases back before sbcl-0.7.0, when we
2011 ;; did special tricks to debug the IR1 interpreter.)
2014 ;;;; operations on debug variables
2016 (defun debug-var-symbol-name (debug-var)
2017 (symbol-name (debug-var-symbol debug-var
)))
2019 ;;; FIXME: Make sure that this isn't called anywhere that it wouldn't
2020 ;;; be acceptable to have NIL returned, or that it's only called on
2021 ;;; DEBUG-VARs whose symbols have non-NIL packages.
2022 (defun debug-var-package-name (debug-var)
2023 (package-name (symbol-package (debug-var-symbol debug-var
))))
2025 ;;; Return the value stored for DEBUG-VAR in frame, or if the value is
2026 ;;; not :VALID, then signal an INVALID-VALUE error.
2027 (defun debug-var-valid-value (debug-var frame
)
2028 (unless (eq (debug-var-validity debug-var
(frame-code-location frame
))
2030 (error 'invalid-value
:debug-var debug-var
:frame frame
))
2031 (debug-var-value debug-var frame
))
2033 ;;; Returns the value stored for DEBUG-VAR in frame. The value may be
2034 ;;; invalid. This is SETFable.
2035 (defun debug-var-value (debug-var frame
)
2036 (aver (typep frame
'compiled-frame
))
2037 (let ((res (access-compiled-debug-var-slot debug-var frame
)))
2038 (if (indirect-value-cell-p res
)
2039 (value-cell-ref res
)
2042 ;;; This returns what is stored for the variable represented by
2043 ;;; DEBUG-VAR relative to the FRAME. This may be an indirect value
2044 ;;; cell if the variable is both closed over and set.
2045 (defun access-compiled-debug-var-slot (debug-var frame
)
2046 (let ((escaped (compiled-frame-escaped frame
)))
2047 (cond ((compiled-debug-var-indirect-sc-offset debug-var
)
2048 (sub-access-debug-var-slot
2049 ;; Indirect are accessed through a frame pointer of the parent.
2051 (sub-access-debug-var-slot
2052 (frame-pointer frame
)
2054 (compiled-debug-var-sc-offset debug-var
)
2056 (compiled-debug-var-save-sc-offset debug-var
)
2057 (compiled-debug-var-sc-offset debug-var
)))
2059 (compiled-debug-var-indirect-sc-offset debug-var
)
2062 (sub-access-debug-var-slot
2063 (frame-pointer frame
)
2064 (compiled-debug-var-sc-offset debug-var
)
2067 (sub-access-debug-var-slot
2068 (frame-pointer frame
)
2069 (or (compiled-debug-var-save-sc-offset debug-var
)
2070 (compiled-debug-var-sc-offset debug-var
)))))))
2072 ;;; a helper function for working with possibly-invalid values:
2073 ;;; Do (%MAKE-LISP-OBJ VAL) only if the value looks valid.
2075 ;;; (Such values can arise in registers on machines with conservative
2076 ;;; GC, and might also arise in debug variable locations when
2077 ;;; those variables are invalid.)
2079 ;;; NOTE: this function is not GC-safe in the slightest when creating
2080 ;;; a pointer to an object in dynamic space. If a GC occurs between
2081 ;;; the start of the call to VALID-LISP-POINTER-P and the end of
2082 ;;; %MAKE-LISP-OBJ then the object could move before the boxed pointer
2083 ;;; is constructed. This can happen on CHENEYGC if an asynchronous
2084 ;;; interrupt occurs within the window. This can happen on GENCGC
2085 ;;; under the same circumstances, but is more likely due to all GENCGC
2086 ;;; platforms supporting threaded operation. This is somewhat
2087 ;;; mitigated on x86oids due to the conservative stack and interrupt
2088 ;;; context "scavenging" on such platforms, but there still may be a
2089 ;;; vulnerable window.
2090 (defun make-lisp-obj (val &optional
(errorp t
))
2091 (macrolet ((maybe-tag-tramp (x)
2094 (* sb
!vm
:n-word-bytes sb
!vm
:simple-fun-code-offset
))
2095 sb
!vm
:fun-pointer-lowtag
)
2100 (zerop (logand val sb
!vm
:fixnum-tag-mask
))
2101 ;; immediate single float, 64-bit only
2103 (= (logand val
#xff
) sb
!vm
:single-float-widetag
)
2105 (and (zerop (logandc2 val
#x1fffffff
)) ; Top bits zero
2106 (= (logand val
#xff
) sb
!vm
:character-widetag
)) ; char tag
2108 (= val sb
!vm
:unbound-marker-widetag
)
2110 (not (zerop (valid-lisp-pointer-p (int-sap val
)))))
2111 (values (%make-lisp-obj val
) t
)
2113 (error "~S is not a valid argument to ~S"
2115 (values (make-unprintable-object (format nil
"invalid object #x~X" val
))
2118 (defun sub-access-debug-var-slot (fp sc-offset
&optional escaped
)
2119 ;; NOTE: The long-float support in here is obviously decayed. When
2120 ;; the x86oid and non-x86oid versions of this function were unified,
2121 ;; the behavior of long-floats was preserved, which only served to
2122 ;; highlight its brokenness.
2123 (macrolet ((with-escaped-value ((var) &body forms
)
2125 (let ((,var
(sb!vm
:context-register
2127 (sb!c
:sc-offset-offset sc-offset
))))
2129 :invalid-value-for-unescaped-register-storage
))
2130 (escaped-float-value (format)
2132 (sb!vm
:context-float-register
2134 (sb!c
:sc-offset-offset sc-offset
) ',format
)
2135 :invalid-value-for-unescaped-register-storage
))
2136 (with-nfp ((var) &body body
)
2137 ;; x86oids have no separate number stack, so dummy it
2139 #!+c-stack-is-control-stack
2142 #!-c-stack-is-control-stack
2143 `(let ((,var
(if escaped
2145 (sb!vm
:context-register escaped
2148 (sap-ref-sap fp
(* nfp-save-offset
2149 sb
!vm
:n-word-bytes
))
2151 (sb!vm
::make-number-stack-pointer
2152 (sap-ref-32 fp
(* nfp-save-offset
2153 sb
!vm
:n-word-bytes
))))))
2155 (number-stack-offset (&optional
(offset 0))
2157 `(+ (sb!vm
::frame-byte-offset
(sb!c
:sc-offset-offset sc-offset
))
2160 `(+ (* (sb!c
:sc-offset-offset sc-offset
) sb
!vm
:n-word-bytes
)
2162 (ecase (sb!c
:sc-offset-scn sc-offset
)
2163 ((#.sb
!vm
:any-reg-sc-number
2164 #.sb
!vm
:descriptor-reg-sc-number
)
2166 (with-escaped-value (val)
2167 (values (make-lisp-obj (mask-field (byte #.sb
!vm
:n-word-bits
0) val
) nil
)))))
2168 (#.sb
!vm
:character-reg-sc-number
2169 (with-escaped-value (val)
2171 (#.sb
!vm
:sap-reg-sc-number
2172 (with-escaped-value (val)
2174 (#.sb
!vm
:signed-reg-sc-number
2175 (with-escaped-value (val)
2176 (if (logbitp (1- sb
!vm
:n-word-bits
) val
)
2177 (logior val
(ash -
1 sb
!vm
:n-word-bits
))
2179 (#.sb
!vm
:unsigned-reg-sc-number
2180 (with-escaped-value (val)
2183 (#.sb
!vm
:non-descriptor-reg-sc-number
2184 (error "Local non-descriptor register access?"))
2186 (#.sb
!vm
:interior-reg-sc-number
2187 (error "Local interior register access?"))
2188 (#.sb
!vm
:single-reg-sc-number
2189 (escaped-float-value single-float
))
2190 (#.sb
!vm
:double-reg-sc-number
2191 (escaped-float-value double-float
))
2193 (#.sb
!vm
:long-reg-sc-number
2194 (escaped-float-value long-float
))
2195 (#.sb
!vm
:complex-single-reg-sc-number
2196 (escaped-float-value complex-single-float
))
2197 (#.sb
!vm
:complex-double-reg-sc-number
2198 (escaped-float-value complex-double-float
))
2200 (#.sb
!vm
:complex-long-reg-sc-number
2201 (escaped-float-value sb
!kernel
::complex-long-float
))
2202 (#.sb
!vm
:single-stack-sc-number
2204 (sap-ref-single nfp
(number-stack-offset))))
2205 (#.sb
!vm
:double-stack-sc-number
2207 (sap-ref-double nfp
(number-stack-offset))))
2209 (#.sb
!vm
:long-stack-sc-number
2211 (sap-ref-long nfp
(number-stack-offset))))
2212 (#.sb
!vm
:complex-single-stack-sc-number
2215 (sap-ref-single nfp
(number-stack-offset))
2216 (sap-ref-single nfp
(number-stack-offset 4)))))
2217 (#.sb
!vm
:complex-double-stack-sc-number
2220 (sap-ref-double nfp
(number-stack-offset))
2221 (sap-ref-double nfp
(number-stack-offset 8)))))
2223 (#.sb
!vm
:complex-long-stack-sc-number
2226 (sap-ref-long nfp
(number-stack-offset))
2228 (number-stack-offset #!+sparc
4
2229 #!+(or x86 x86-64
) 3)))))
2230 (#.sb
!vm
:control-stack-sc-number
2231 (stack-ref fp
(sb!c
:sc-offset-offset sc-offset
)))
2232 (#.sb
!vm
:character-stack-sc-number
2234 (code-char (sap-ref-word nfp
(number-stack-offset)))))
2235 (#.sb
!vm
:unsigned-stack-sc-number
2237 (sap-ref-word nfp
(number-stack-offset))))
2238 (#.sb
!vm
:signed-stack-sc-number
2240 (signed-sap-ref-word nfp
(number-stack-offset))))
2241 (#.sb
!vm
:sap-stack-sc-number
2243 (sap-ref-sap nfp
(number-stack-offset))))
2244 (#.constant-sc-number
2247 (component-from-component-ptr
2248 (component-ptr-from-pc
2249 (sb!vm
:context-pc escaped
)))
2250 (sb!c
:sc-offset-offset sc-offset
))
2251 :invalid-value-for-unescaped-register-storage
)))))
2253 ;;; This stores value as the value of DEBUG-VAR in FRAME. In the
2254 ;;; COMPILED-DEBUG-VAR case, access the current value to determine if
2255 ;;; it is an indirect value cell. This occurs when the variable is
2256 ;;; both closed over and set.
2257 (defun %set-debug-var-value
(debug-var frame new-value
)
2258 (aver (typep frame
'compiled-frame
))
2259 (let ((old-value (access-compiled-debug-var-slot debug-var frame
)))
2260 (if (indirect-value-cell-p old-value
)
2261 (value-cell-set old-value new-value
)
2262 (set-compiled-debug-var-slot debug-var frame new-value
)))
2265 ;;; This stores VALUE for the variable represented by debug-var
2266 ;;; relative to the frame. This assumes the location directly contains
2267 ;;; the variable's value; that is, there is no indirect value cell
2268 ;;; currently there in case the variable is both closed over and set.
2269 (defun set-compiled-debug-var-slot (debug-var frame value
)
2270 (let ((escaped (compiled-frame-escaped frame
)))
2272 (sub-set-debug-var-slot (frame-pointer frame
)
2273 (compiled-debug-var-sc-offset debug-var
)
2275 (sub-set-debug-var-slot
2276 (frame-pointer frame
)
2277 (or (compiled-debug-var-save-sc-offset debug-var
)
2278 (compiled-debug-var-sc-offset debug-var
))
2281 (defun sub-set-debug-var-slot (fp sc-offset value
&optional escaped
)
2282 ;; Like sub-access-debug-var-slot, this is the unification of two
2283 ;; divergent copy-pasted functions. The astute reviewer will notice
2284 ;; that long-floats are messed up here as well, that x86oids
2285 ;; apparently don't support accessing float values that are in
2286 ;; registers, and that non-x86oids store the real part of a float
2287 ;; for both the real and imaginary parts of a complex on the stack
2288 ;; (but not in registers, oddly enough). Some research has
2289 ;; indicated that the different forms of THE used for validating the
2290 ;; type of complex float components between x86oid and non-x86oid
2291 ;; systems are only significant in the case of using a non-complex
2292 ;; number as input (as the non-x86oid case effectively converts
2293 ;; non-complex numbers to complex ones and the x86oid case will
2294 ;; error out). That said, the error message from entering a value
2295 ;; of the wrong type will be slightly easier to understand on x86oid
2297 (macrolet ((set-escaped-value (val)
2299 (setf (sb!vm
:context-register
2301 (sb!c
:sc-offset-offset sc-offset
))
2304 (set-escaped-float-value (format val
)
2306 (setf (sb!vm
:context-float-register
2308 (sb!c
:sc-offset-offset sc-offset
)
2312 (with-nfp ((var) &body body
)
2313 ;; x86oids have no separate number stack, so dummy it
2319 `(let ((,var
(if escaped
2321 (sb!vm
:context-register escaped
2326 sb
!vm
:n-word-bytes
))
2328 (sb!vm
::make-number-stack-pointer
2331 sb
!vm
:n-word-bytes
))))))
2333 (number-stack-offset (&optional
(offset 0))
2335 `(+ (sb!vm
::frame-byte-offset
(sb!c
:sc-offset-offset sc-offset
))
2338 `(+ (* (sb!c
:sc-offset-offset sc-offset
) sb
!vm
:n-word-bytes
)
2340 (ecase (sb!c
:sc-offset-scn sc-offset
)
2341 ((#.sb
!vm
:any-reg-sc-number
2342 #.sb
!vm
:descriptor-reg-sc-number
)
2345 (get-lisp-obj-address value
))))
2346 (#.sb
!vm
:character-reg-sc-number
2347 (set-escaped-value (char-code value
)))
2348 (#.sb
!vm
:sap-reg-sc-number
2349 (set-escaped-value (sap-int value
)))
2350 (#.sb
!vm
:signed-reg-sc-number
2351 (set-escaped-value (logand value
(1- (ash 1 sb
!vm
:n-word-bits
)))))
2352 (#.sb
!vm
:unsigned-reg-sc-number
2353 (set-escaped-value value
))
2355 (#.sb
!vm
:non-descriptor-reg-sc-number
2356 (error "Local non-descriptor register access?"))
2358 (#.sb
!vm
:interior-reg-sc-number
2359 (error "Local interior register access?"))
2360 (#.sb
!vm
:single-reg-sc-number
2361 #!-
(or x86 x86-64
) ;; don't have escaped floats.
2362 (set-escaped-float-value single-float value
))
2363 (#.sb
!vm
:double-reg-sc-number
2364 (set-escaped-float-value double-float value
))
2366 (#.sb
!vm
:long-reg-sc-number
2367 (set-escaped-float-value long-float value
))
2368 (#.sb
!vm
:complex-single-reg-sc-number
2369 (set-escaped-float-value complex-single-float value
))
2370 (#.sb
!vm
:complex-double-reg-sc-number
2371 (set-escaped-float-value complex-double-float value
))
2373 (#.sb
!vm
:complex-long-reg-sc-number
2374 (set-escaped-float-value complex-long-float
))
2375 (#.sb
!vm
:single-stack-sc-number
2377 (setf (sap-ref-single nfp
(number-stack-offset))
2378 (the single-float value
))))
2379 (#.sb
!vm
:double-stack-sc-number
2381 (setf (sap-ref-double nfp
(number-stack-offset))
2382 (the double-float value
))))
2384 (#.sb
!vm
:long-stack-sc-number
2386 (setf (sap-ref-long nfp
(number-stack-offset))
2387 (the long-float value
))))
2388 (#.sb
!vm
:complex-single-stack-sc-number
2390 (setf (sap-ref-single nfp
(number-stack-offset))
2392 (realpart (the (complex single-float
) value
))
2394 (the single-float
(realpart value
)))
2395 (setf (sap-ref-single nfp
(number-stack-offset 4))
2397 (imagpart (the (complex single-float
) value
))
2399 (the single-float
(realpart value
)))))
2400 (#.sb
!vm
:complex-double-stack-sc-number
2402 (setf (sap-ref-double nfp
(number-stack-offset))
2404 (realpart (the (complex double-float
) value
))
2406 (the double-float
(realpart value
)))
2407 (setf (sap-ref-double nfp
(number-stack-offset 8))
2409 (imagpart (the (complex double-float
) value
))
2411 (the double-float
(realpart value
)))))
2413 (#.sb
!vm
:complex-long-stack-sc-number
2416 nfp
(number-stack-offset))
2418 (realpart (the (complex long-float
) value
))
2420 (the long-float
(realpart value
)))
2422 nfp
(number-stack-offset #!+sparc
4
2423 #!+(or x86 x86-64
) 3))
2425 (imagpart (the (complex long-float
) value
))
2427 (the long-float
(realpart value
)))))
2428 (#.sb
!vm
:control-stack-sc-number
2429 (setf (stack-ref fp
(sb!c
:sc-offset-offset sc-offset
)) value
))
2430 (#.sb
!vm
:character-stack-sc-number
2432 (setf (sap-ref-word nfp
(number-stack-offset 0))
2433 (char-code (the character value
)))))
2434 (#.sb
!vm
:unsigned-stack-sc-number
2436 (setf (sap-ref-word nfp
(number-stack-offset 0)) (the word value
))))
2437 (#.sb
!vm
:signed-stack-sc-number
2439 (setf (signed-sap-ref-word nfp
(number-stack-offset))
2440 (the signed-word value
))))
2441 (#.sb
!vm
:sap-stack-sc-number
2443 (setf (sap-ref-sap nfp
(number-stack-offset))
2444 (the system-area-pointer value
)))))))
2446 ;;; The method for setting and accessing COMPILED-DEBUG-VAR values use
2447 ;;; this to determine if the value stored is the actual value or an
2448 ;;; indirection cell.
2449 (defun indirect-value-cell-p (x)
2450 (and (%other-pointer-p x
)
2451 (eql (%other-pointer-widetag x
) sb
!vm
:value-cell-widetag
)))
2453 ;;; Return three values reflecting the validity of DEBUG-VAR's value
2454 ;;; at BASIC-CODE-LOCATION:
2455 ;;; :VALID The value is known to be available.
2456 ;;; :INVALID The value is known to be unavailable.
2457 ;;; :UNKNOWN The value's availability is unknown.
2459 ;;; If the variable is always alive, then it is valid. If the
2460 ;;; code-location is unknown, then the variable's validity is
2461 ;;; :unknown. Once we've called CODE-LOCATION-UNKNOWN-P, we know the
2462 ;;; live-set information has been cached in the code-location.
2463 (defun debug-var-validity (debug-var basic-code-location
)
2464 (compiled-debug-var-validity debug-var basic-code-location
))
2466 (defun debug-var-info (debug-var)
2467 (compiled-debug-var-info debug-var
))
2469 ;;; This is the method for DEBUG-VAR-VALIDITY for COMPILED-DEBUG-VARs.
2470 ;;; For safety, make sure basic-code-location is what we think.
2471 (defun compiled-debug-var-validity (debug-var basic-code-location
)
2472 (declare (type compiled-code-location basic-code-location
))
2473 (cond ((debug-var-alive-p debug-var
)
2474 (let ((debug-fun (code-location-debug-fun basic-code-location
)))
2475 (if (>= (compiled-code-location-pc basic-code-location
)
2476 (sb!c
::compiled-debug-fun-start-pc
2477 (compiled-debug-fun-compiler-debug-fun debug-fun
)))
2480 ((code-location-unknown-p basic-code-location
) :unknown
)
2482 (let ((pos (position debug-var
2483 (debug-fun-debug-vars
2484 (code-location-debug-fun
2485 basic-code-location
)))))
2487 (error 'unknown-debug-var
2488 :debug-var debug-var
2490 (code-location-debug-fun basic-code-location
)))
2491 ;; There must be live-set info since basic-code-location is known.
2492 (if (zerop (sbit (compiled-code-location-live-set
2493 basic-code-location
)
2500 ;;; This code produces and uses what we call source-paths. A
2501 ;;; source-path is a list whose first element is a form number as
2502 ;;; returned by CODE-LOCATION-FORM-NUMBER and whose last element is a
2503 ;;; top level form number as returned by
2504 ;;; CODE-LOCATION-TOPLEVEL-FORM-NUMBER. The elements from the last to
2505 ;;; the first, exclusively, are the numbered subforms into which to
2506 ;;; descend. For example:
2508 ;;; (let ((a (aref x 3)))
2510 ;;; The call to AREF in this example is form number 5. Assuming this
2511 ;;; DEFUN is the 11'th top level form, the source-path for the AREF
2512 ;;; call is as follows:
2514 ;;; Given the DEFUN, 3 gets you the LET, 1 gets you the bindings, 0
2515 ;;; gets the first binding, and 1 gets the AREF form.
2517 ;;; This returns a table mapping form numbers to source-paths. A
2518 ;;; source-path indicates a descent into the TOPLEVEL-FORM form,
2519 ;;; going directly to the subform corressponding to the form number.
2521 ;;; The vector elements are in the same format as the compiler's
2522 ;;; NODE-SOURCE-PATH; that is, the first element is the form number and
2523 ;;; the last is the TOPLEVEL-FORM number.
2525 ;;; This should be synchronized with SB-C::SUB-FIND-SOURCE-PATHS
2526 (defun form-number-translations (form tlf-number
)
2528 (translations (make-array 12 :fill-pointer
0 :adjustable t
)))
2529 (labels ((translate1 (form path
)
2530 (unless (member form seen
)
2532 (vector-push-extend (cons (fill-pointer translations
) path
)
2537 (declare (fixnum pos
))
2540 (when (atom subform
) (return))
2541 (let ((fm (car subform
)))
2542 (when (sb!int
:comma-p fm
)
2543 (setf fm
(sb!int
:comma-expr fm
)))
2545 (translate1 fm
(cons pos path
)))
2547 ;; Don't look into quoted constants.
2550 (setq subform
(cdr subform
))
2551 (when (eq subform trail
) (return)))))
2555 (setq trail
(cdr trail
))))))))
2556 (translate1 form
(list tlf-number
)))
2557 (coerce translations
'simple-vector
)))
2559 ;;; FORM is a top level form, and path is a source-path into it. This
2560 ;;; returns the form indicated by the source-path. Context is the
2561 ;;; number of enclosing forms to return instead of directly returning
2562 ;;; the source-path form. When context is non-zero, the form returned
2563 ;;; contains a marker, #:****HERE****, immediately before the form
2564 ;;; indicated by path.
2565 (defun source-path-context (form path context
)
2566 (declare (type unsigned-byte context
))
2567 ;; Get to the form indicated by path or the enclosing form indicated
2568 ;; by context and path.
2569 (let ((path (reverse (butlast (cdr path
)))))
2570 (dotimes (i (- (length path
) context
))
2571 (let ((index (first path
)))
2572 (unless (and (listp form
) (< index
(length form
)))
2573 (error "Source path no longer exists."))
2574 (setq form
(elt form index
))
2575 (setq path
(rest path
))))
2576 ;; Recursively rebuild the source form resulting from the above
2577 ;; descent, copying the beginning of each subform up to the next
2578 ;; subform we descend into according to path. At the bottom of the
2579 ;; recursion, we return the form indicated by path preceded by our
2580 ;; marker, and this gets spliced into the resulting list structure
2581 ;; on the way back up.
2582 (labels ((frob (form path level
)
2583 (if (or (zerop level
) (null path
))
2586 `(#:***here
*** ,form
))
2587 (let ((n (first path
)))
2588 (unless (and (listp form
) (< n
(length form
)))
2589 (error "Source path no longer exists."))
2590 (let ((res (frob (elt form n
) (rest path
) (1- level
))))
2591 (nconc (subseq form
0 n
)
2592 (cons res
(nthcdr (1+ n
) form
))))))))
2593 (frob form path context
))))
2595 ;;; Given a code location, return the associated form-number
2596 ;;; translations and the actual top level form.
2597 (defun get-toplevel-form (location)
2598 (let ((d-source (code-location-debug-source location
)))
2599 (let* ((offset (code-location-toplevel-form-offset location
))
2601 (cond ((debug-source-form d-source
)
2602 (debug-source-form d-source
))
2603 ((debug-source-namestring d-source
)
2604 (get-file-toplevel-form location
))
2605 (t (bug "Don't know how to use a DEBUG-SOURCE without ~
2606 a namestring or a form.")))))
2607 (values (form-number-translations res offset
) res
))))
2609 ;;; To suppress the read-time evaluation #. macro during source read,
2610 ;;; *READTABLE* is modified.
2612 ;;; FIXME: This breaks #+#.(cl:if ...) Maybe we need a SAFE-READ-EVAL, which
2613 ;;; this code can use for side- effect free #. calls?
2615 ;;; FIXME: This also knows nothing of custom readtables. The assumption
2616 ;;; is that the current readtable is a decent approximation for what
2617 ;;; we want, but that's lossy.
2618 (defun safe-readtable ()
2619 (let ((rt (copy-readtable)))
2620 (set-dispatch-macro-character
2621 #\
# #\.
(lambda (stream sub-char
&rest rest
)
2622 (declare (ignore rest sub-char
))
2623 (let ((token (read stream t nil t
)))
2624 (format nil
"#.~S" token
)))
2628 ;;; Locate the source file (if it still exists) and grab the top level
2629 ;;; form. If the file is modified, we use the top level form offset
2630 ;;; instead of the recorded character offset.
2631 (defun get-file-toplevel-form (location)
2632 (let* ((d-source (code-location-debug-source location
))
2633 (di (compiled-debug-fun-debug-info
2634 (code-location-debug-fun location
)))
2635 (tlf-offset (sb!c
::compiled-debug-info-tlf-number di
))
2636 (char-offset (sb!c
::compiled-debug-info-char-offset di
))
2637 (namestring (debug-source-namestring d-source
)))
2638 ;; FIXME: External format?
2639 (with-open-file (f namestring
:if-does-not-exist nil
)
2641 (let ((*readtable
* (safe-readtable)))
2642 (cond ((eql (debug-source-created d-source
) (file-write-date f
))
2643 (file-position f char-offset
))
2646 "~%; File has been modified since compilation:~%; ~A~@
2647 ; Using form offset instead of character position.~%"
2649 (let ((*read-suppress
* t
))
2650 (loop repeat tlf-offset
2654 ;;;; PREPROCESS-FOR-EVAL
2656 ;;; Return a function of one argument that evaluates form in the
2657 ;;; lexical context of the BASIC-CODE-LOCATION LOC, or signal a
2658 ;;; NO-DEBUG-VARS condition when the LOC's DEBUG-FUN has no
2659 ;;; DEBUG-VAR information available.
2661 ;;; The returned function takes the frame to get values from as its
2662 ;;; argument, and it returns the values of FORM. The returned function
2663 ;;; can signal the following conditions: INVALID-VALUE,
2664 ;;; AMBIGUOUS-VAR-NAME, and FRAME-FUN-MISMATCH.
2665 (defun preprocess-for-eval (form loc
)
2666 (declare (type code-location loc
))
2667 (let ((n-frame (gensym))
2668 (fun (code-location-debug-fun loc
))
2671 (unless (debug-var-info-available fun
)
2672 (debug-signal 'no-debug-vars
:debug-fun fun
))
2673 (sb!int
:collect
((binds)
2675 (do-debug-fun-vars (var fun
)
2676 (let ((validity (debug-var-validity var loc
)))
2677 (unless (eq validity
:invalid
)
2678 (case (debug-var-info var
)
2680 (setf more-context var
))
2682 (setf more-count var
))
2684 (let* ((sym (debug-var-symbol var
))
2685 (found (assoc sym
(binds))))
2688 (setf (second found
) :ambiguous
))
2690 (binds (list sym validity var
))))))))))
2691 (when (and more-context more-count
)
2692 (let ((more (assoc 'sb
!debug
::more
(binds))))
2694 (setf (second more
) :ambiguous
)
2695 (binds (list 'sb
!debug
::more
:more more-context more-count
)))))
2696 (dolist (bind (binds))
2697 (let ((name (first bind
))
2699 (unless (eq (info :variable
:kind name
) :special
)
2700 (ecase (second bind
)
2702 (specs `(,name
(debug-var-value ',var
,n-frame
))))
2704 (let ((count-var (fourth bind
)))
2705 (specs `(,name
(multiple-value-list
2706 (sb!c
:%more-arg-values
(debug-var-value ',var
,n-frame
)
2708 (debug-var-value ',count-var
,n-frame
)))))))
2710 (specs `(,name
(debug-signal 'invalid-value
2714 (specs `(,name
(debug-signal 'ambiguous-var-name
2716 :frame
,n-frame
))))))))
2717 ;; Process the symbol macros outside of the function to avoid
2718 ;; all those symbol-macrolets from showing in the sources if
2719 ;; there is a problem evaluating this form
2720 (let ((res (let ((sb!c
:*lexenv
* (make-null-lexenv)))
2721 (sb!c
::funcall-in-symbol-macrolet-lexenv
2723 (lambda (&optional vars
)
2724 (declare (ignore vars
))
2725 (eval-in-lexenv `(lambda (,n-frame
)
2726 (declare (ignorable ,n-frame
))
2731 ;; This prevents these functions from being used in any
2732 ;; location other than a function return location, so maybe
2733 ;; this should only check whether FRAME's DEBUG-FUN is the
2735 (unless (code-location= (frame-code-location frame
) loc
)
2736 (debug-signal 'frame-fun-mismatch
2737 :code-location loc
:form form
:frame frame
))
2738 (funcall res frame
))))))
2742 (defun eval-in-frame (frame form
)
2743 (declare (type frame frame
))
2744 "Evaluate FORM in the lexical context of FRAME's current code location,
2745 returning the results of the evaluation."
2746 (funcall (preprocess-for-eval form
(frame-code-location frame
)) frame
))
2750 ;;;; user-visible interface
2752 ;;; Create and return a breakpoint. When program execution encounters
2753 ;;; the breakpoint, the system calls HOOK-FUN. HOOK-FUN takes the
2754 ;;; current frame for the function in which the program is running and
2755 ;;; the breakpoint object.
2757 ;;; WHAT and KIND determine where in a function the system invokes
2758 ;;; HOOK-FUN. WHAT is either a code-location or a DEBUG-FUN. KIND is
2759 ;;; one of :CODE-LOCATION, :FUN-START, or :FUN-END. Since the starts
2760 ;;; and ends of functions may not have code-locations representing
2761 ;;; them, designate these places by supplying WHAT as a DEBUG-FUN and
2762 ;;; KIND indicating the :FUN-START or :FUN-END. When WHAT is a
2763 ;;; DEBUG-FUN and kind is :FUN-END, then HOOK-FUN must take two
2764 ;;; additional arguments, a list of values returned by the function
2765 ;;; and a FUN-END-COOKIE.
2767 ;;; INFO is information supplied by and used by the user.
2769 ;;; FUN-END-COOKIE is a function. To implement :FUN-END
2770 ;;; breakpoints, the system uses starter breakpoints to establish the
2771 ;;; :FUN-END breakpoint for each invocation of the function. Upon
2772 ;;; each entry, the system creates a unique cookie to identify the
2773 ;;; invocation, and when the user supplies a function for this
2774 ;;; argument, the system invokes it on the frame and the cookie. The
2775 ;;; system later invokes the :FUN-END breakpoint hook on the same
2776 ;;; cookie. The user may save the cookie for comparison in the hook
2779 ;;; Signal an error if WHAT is an unknown code-location.
2780 (defun make-breakpoint (hook-fun what
2781 &key
(kind :code-location
) info fun-end-cookie
)
2784 (when (code-location-unknown-p what
)
2785 (error "cannot make a breakpoint at an unknown code location: ~S"
2787 (aver (eq kind
:code-location
))
2788 (let ((bpt (%make-breakpoint hook-fun what kind info
)))
2790 (compiled-code-location
2791 ;; This slot is filled in due to calling CODE-LOCATION-UNKNOWN-P.
2792 (when (eq (compiled-code-location-kind what
) :unknown-return
)
2793 (let ((other-bpt (%make-breakpoint hook-fun what
2794 :unknown-return-partner
2796 (setf (breakpoint-unknown-return-partner bpt
) other-bpt
)
2797 (setf (breakpoint-unknown-return-partner other-bpt
) bpt
))))
2798 ;; (There used to be more cases back before sbcl-0.7.0,,
2799 ;; when we did special tricks to debug the IR1
2806 (%make-breakpoint hook-fun what kind info
))
2808 (unless (eq (sb!c
::compiled-debug-fun-returns
2809 (compiled-debug-fun-compiler-debug-fun what
))
2811 (error ":FUN-END breakpoints are currently unsupported ~
2812 for the known return convention."))
2814 (let* ((bpt (%make-breakpoint hook-fun what kind info
))
2815 (starter (compiled-debug-fun-end-starter what
)))
2817 (setf starter
(%make-breakpoint
#'list what
:fun-start nil
))
2818 (setf (breakpoint-hook-fun starter
)
2819 (fun-end-starter-hook starter what
))
2820 (setf (compiled-debug-fun-end-starter what
) starter
))
2821 (setf (breakpoint-start-helper bpt
) starter
)
2822 (push bpt
(breakpoint-%info starter
))
2823 (setf (breakpoint-cookie-fun bpt
) fun-end-cookie
)
2826 ;;; These are unique objects created upon entry into a function by a
2827 ;;; :FUN-END breakpoint's starter hook. These are only created
2828 ;;; when users supply :FUN-END-COOKIE to MAKE-BREAKPOINT. Also,
2829 ;;; the :FUN-END breakpoint's hook is called on the same cookie
2830 ;;; when it is created.
2831 (defstruct (fun-end-cookie
2832 (:print-object
(lambda (obj str
)
2833 (print-unreadable-object (obj str
:type t
))))
2834 (:constructor make-fun-end-cookie
(bogus-lra debug-fun
))
2836 ;; a pointer to the bogus-lra created for :FUN-END breakpoints
2837 (bogus-lra nil
:read-only t
)
2838 ;; the DEBUG-FUN associated with this cookie
2839 (debug-fun nil
:read-only t
))
2841 ;;; This maps bogus-lra-components to cookies, so that
2842 ;;; HANDLE-FUN-END-BREAKPOINT can find the appropriate cookie for the
2843 ;;; breakpoint hook.
2844 (defvar *fun-end-cookies
* (make-hash-table :test
'eq
:synchronized t
))
2846 ;;; This returns a hook function for the start helper breakpoint
2847 ;;; associated with a :FUN-END breakpoint. The returned function
2848 ;;; makes a fake LRA that all returns go through, and this piece of
2849 ;;; fake code actually breaks. Upon return from the break, the code
2850 ;;; provides the returnee with any values. Since the returned function
2851 ;;; effectively activates FUN-END-BPT on each entry to DEBUG-FUN's
2852 ;;; function, we must establish breakpoint-data about FUN-END-BPT.
2853 (defun fun-end-starter-hook (starter-bpt debug-fun
)
2854 (declare (type breakpoint starter-bpt
)
2855 (type compiled-debug-fun debug-fun
))
2856 (lambda (frame breakpoint
)
2857 (declare (ignore breakpoint
)
2859 (let ((lra-sc-offset
2860 #!-fp-and-pc-standard-save
2861 (sb!c
::compiled-debug-fun-return-pc
2862 (compiled-debug-fun-compiler-debug-fun debug-fun
))
2863 #!+fp-and-pc-standard-save
2864 sb
!c
:return-pc-passing-offset
))
2865 (multiple-value-bind (lra component offset
)
2867 (get-context-value frame
2870 (setf (get-context-value frame
2874 (let ((end-bpts (breakpoint-%info starter-bpt
)))
2875 (let ((data (breakpoint-data component offset
)))
2876 (setf (breakpoint-data-breakpoints data
) end-bpts
)
2877 (dolist (bpt end-bpts
)
2878 (setf (breakpoint-internal-data bpt
) data
)))
2879 (let ((cookie (make-fun-end-cookie lra debug-fun
)))
2880 (setf (gethash component
*fun-end-cookies
*) cookie
)
2881 (dolist (bpt end-bpts
)
2882 (let ((fun (breakpoint-cookie-fun bpt
)))
2883 (when fun
(funcall fun frame cookie
))))))))))
2885 ;;; This takes a FUN-END-COOKIE and a frame, and it returns
2886 ;;; whether the cookie is still valid. A cookie becomes invalid when
2887 ;;; the frame that established the cookie has exited. Sometimes cookie
2888 ;;; holders are unaware of cookie invalidation because their
2889 ;;; :FUN-END breakpoint hooks didn't run due to THROW'ing.
2891 ;;; This takes a frame as an efficiency hack since the user probably
2892 ;;; has a frame object in hand when using this routine, and it saves
2893 ;;; repeated parsing of the stack and consing when asking whether a
2894 ;;; series of cookies is valid.
2895 (defun fun-end-cookie-valid-p (frame cookie
)
2896 (let ((lra (fun-end-cookie-bogus-lra cookie
))
2898 #!-fp-and-pc-standard-save
2899 (sb!c
::compiled-debug-fun-return-pc
2900 (compiled-debug-fun-compiler-debug-fun
2901 (fun-end-cookie-debug-fun cookie
)))
2902 #!+fp-and-pc-standard-save
2903 sb
!c
:return-pc-passing-offset
))
2904 (do ((frame frame
(frame-down frame
)))
2906 (when (and (compiled-frame-p frame
)
2907 (#!-
(or x86 x86-64
) eq
#!+(or x86 x86-64
) sap
=
2909 (get-context-value frame lra-save-offset lra-sc-offset
)))
2912 ;;;; ACTIVATE-BREAKPOINT
2914 ;;; Cause the system to invoke the breakpoint's hook function until
2915 ;;; the next call to DEACTIVATE-BREAKPOINT or DELETE-BREAKPOINT. The
2916 ;;; system invokes breakpoint hook functions in the opposite order
2917 ;;; that you activate them.
2918 (defun activate-breakpoint (breakpoint)
2919 (when (eq (breakpoint-status breakpoint
) :deleted
)
2920 (error "cannot activate a deleted breakpoint: ~S" breakpoint
))
2921 (unless (eq (breakpoint-status breakpoint
) :active
)
2922 (ecase (breakpoint-kind breakpoint
)
2924 (let ((loc (breakpoint-what breakpoint
)))
2926 (compiled-code-location
2927 (activate-compiled-code-location-breakpoint breakpoint
)
2928 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
2930 (activate-compiled-code-location-breakpoint other
))))
2931 ;; (There used to be more cases back before sbcl-0.7.0, when
2932 ;; we did special tricks to debug the IR1 interpreter.)
2935 (etypecase (breakpoint-what breakpoint
)
2937 (activate-compiled-fun-start-breakpoint breakpoint
))
2938 ;; (There used to be more cases back before sbcl-0.7.0, when
2939 ;; we did special tricks to debug the IR1 interpreter.)
2942 (etypecase (breakpoint-what breakpoint
)
2944 (let ((starter (breakpoint-start-helper breakpoint
)))
2945 (unless (eq (breakpoint-status starter
) :active
)
2946 ;; may already be active by some other :FUN-END breakpoint
2947 (activate-compiled-fun-start-breakpoint starter
)))
2948 (setf (breakpoint-status breakpoint
) :active
))
2949 ;; (There used to be more cases back before sbcl-0.7.0, when
2950 ;; we did special tricks to debug the IR1 interpreter.)
2954 (defun activate-compiled-code-location-breakpoint (breakpoint)
2955 (declare (type breakpoint breakpoint
))
2956 (let ((loc (breakpoint-what breakpoint
)))
2957 (declare (type compiled-code-location loc
))
2958 (sub-activate-breakpoint
2960 (breakpoint-data (compiled-debug-fun-component
2961 (code-location-debug-fun loc
))
2962 (+ (compiled-code-location-pc loc
)
2963 (if (or (eq (breakpoint-kind breakpoint
)
2964 :unknown-return-partner
)
2965 (eq (compiled-code-location-kind loc
)
2966 :single-value-return
))
2967 sb
!vm
:single-value-return-byte-offset
2970 (defun activate-compiled-fun-start-breakpoint (breakpoint)
2971 (declare (type breakpoint breakpoint
))
2972 (let ((debug-fun (breakpoint-what breakpoint
)))
2973 (sub-activate-breakpoint
2975 (breakpoint-data (compiled-debug-fun-component debug-fun
)
2976 (sb!c
::compiled-debug-fun-start-pc
2977 (compiled-debug-fun-compiler-debug-fun
2980 (defun sub-activate-breakpoint (breakpoint data
)
2981 (declare (type breakpoint breakpoint
)
2982 (type breakpoint-data data
))
2983 (setf (breakpoint-status breakpoint
) :active
)
2985 (unless (breakpoint-data-breakpoints data
)
2986 (setf (breakpoint-data-instruction data
)
2988 (breakpoint-install (get-lisp-obj-address
2989 (breakpoint-data-component data
))
2990 (breakpoint-data-offset data
)))))
2991 (setf (breakpoint-data-breakpoints data
)
2992 (append (breakpoint-data-breakpoints data
) (list breakpoint
)))
2993 (setf (breakpoint-internal-data breakpoint
) data
)))
2995 ;;;; DEACTIVATE-BREAKPOINT
2997 ;;; Stop the system from invoking the breakpoint's hook function.
2998 (defun deactivate-breakpoint (breakpoint)
2999 (when (eq (breakpoint-status breakpoint
) :active
)
3001 (let ((loc (breakpoint-what breakpoint
)))
3003 ((or compiled-code-location compiled-debug-fun
)
3004 (deactivate-compiled-breakpoint breakpoint
)
3005 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
3007 (deactivate-compiled-breakpoint other
))))
3008 ;; (There used to be more cases back before sbcl-0.7.0, when
3009 ;; we did special tricks to debug the IR1 interpreter.)
3013 (defun deactivate-compiled-breakpoint (breakpoint)
3014 (if (eq (breakpoint-kind breakpoint
) :fun-end
)
3015 (let ((starter (breakpoint-start-helper breakpoint
)))
3016 (unless (find-if (lambda (bpt)
3017 (and (not (eq bpt breakpoint
))
3018 (eq (breakpoint-status bpt
) :active
)))
3019 (breakpoint-%info starter
))
3020 (deactivate-compiled-breakpoint starter
)))
3021 (let* ((data (breakpoint-internal-data breakpoint
))
3022 (bpts (delete breakpoint
(breakpoint-data-breakpoints data
))))
3023 (setf (breakpoint-internal-data breakpoint
) nil
)
3024 (setf (breakpoint-data-breakpoints data
) bpts
)
3027 (breakpoint-remove (get-lisp-obj-address
3028 (breakpoint-data-component data
))
3029 (breakpoint-data-offset data
)
3030 (breakpoint-data-instruction data
)))
3031 (delete-breakpoint-data data
))))
3032 (setf (breakpoint-status breakpoint
) :inactive
)
3035 ;;;; BREAKPOINT-INFO
3037 ;;; Return the user-maintained info associated with breakpoint. This
3039 (defun breakpoint-info (breakpoint)
3040 (breakpoint-%info breakpoint
))
3041 (defun %set-breakpoint-info
(breakpoint value
)
3042 (setf (breakpoint-%info breakpoint
) value
)
3043 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
3045 (setf (breakpoint-%info other
) value
))))
3047 ;;;; BREAKPOINT-ACTIVE-P and DELETE-BREAKPOINT
3049 (defun breakpoint-active-p (breakpoint)
3050 (ecase (breakpoint-status breakpoint
)
3052 ((:inactive
:deleted
) nil
)))
3054 ;;; Free system storage and remove computational overhead associated
3055 ;;; with breakpoint. After calling this, breakpoint is completely
3056 ;;; impotent and can never become active again.
3057 (defun delete-breakpoint (breakpoint)
3058 (let ((status (breakpoint-status breakpoint
)))
3059 (unless (eq status
:deleted
)
3060 (when (eq status
:active
)
3061 (deactivate-breakpoint breakpoint
))
3062 (setf (breakpoint-status breakpoint
) :deleted
)
3063 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
3065 (setf (breakpoint-status other
) :deleted
)))
3066 (when (eq (breakpoint-kind breakpoint
) :fun-end
)
3067 (let* ((starter (breakpoint-start-helper breakpoint
))
3068 (breakpoints (delete breakpoint
3069 (the list
(breakpoint-info starter
)))))
3070 (setf (breakpoint-info starter
) breakpoints
)
3072 (delete-breakpoint starter
)
3073 (setf (compiled-debug-fun-end-starter
3074 (breakpoint-what breakpoint
))
3078 ;;;; C call out stubs
3080 ;;; This actually installs the break instruction in the component. It
3081 ;;; returns the overwritten bits. You must call this in a context in
3082 ;;; which GC is disabled, so that Lisp doesn't move objects around
3083 ;;; that C is pointing to.
3084 (sb!alien
:define-alien-routine
"breakpoint_install" sb
!alien
:unsigned-int
3085 (code-obj sb
!alien
:unsigned
)
3086 (pc-offset sb
!alien
:int
))
3088 ;;; This removes the break instruction and replaces the original
3089 ;;; instruction. You must call this in a context in which GC is disabled
3090 ;;; so Lisp doesn't move objects around that C is pointing to.
3091 (sb!alien
:define-alien-routine
"breakpoint_remove" sb
!alien
:void
3092 (code-obj sb
!alien
:unsigned
)
3093 (pc-offset sb
!alien
:int
)
3094 (old-inst sb
!alien
:unsigned-int
))
3096 (sb!alien
:define-alien-routine
"breakpoint_do_displaced_inst" sb
!alien
:void
3097 (scp (* os-context-t
))
3098 (orig-inst sb
!alien
:unsigned-int
))
3100 ;;;; breakpoint handlers (layer between C and exported interface)
3102 ;;; This maps components to a mapping of offsets to BREAKPOINT-DATAs.
3103 (defvar *component-breakpoint-offsets
* (make-hash-table :test
'eq
:synchronized t
))
3105 ;;; This returns the BREAKPOINT-DATA object associated with component cross
3106 ;;; offset. If none exists, this makes one, installs it, and returns it.
3107 (defun breakpoint-data (component offset
&optional
(create t
))
3108 (flet ((install-breakpoint-data ()
3110 (let ((data (make-breakpoint-data component offset
)))
3111 (push (cons offset data
)
3112 (gethash component
*component-breakpoint-offsets
*))
3114 (let ((offsets (gethash component
*component-breakpoint-offsets
*)))
3116 (let ((data (assoc offset offsets
)))
3119 (install-breakpoint-data)))
3120 (install-breakpoint-data)))))
3122 ;;; We use this when there are no longer any active breakpoints
3123 ;;; corresponding to DATA.
3124 (defun delete-breakpoint-data (data)
3125 ;; Again, this looks brittle. Is there no danger of being interrupted
3127 (let* ((component (breakpoint-data-component data
))
3128 (offsets (delete (breakpoint-data-offset data
)
3129 (gethash component
*component-breakpoint-offsets
*)
3132 (setf (gethash component
*component-breakpoint-offsets
*) offsets
)
3133 (remhash component
*component-breakpoint-offsets
*)))
3136 ;;; The C handler for interrupts calls this when it has a
3137 ;;; debugging-tool break instruction. This does *not* handle all
3138 ;;; breaks; for example, it does not handle breaks for internal
3140 (defun handle-breakpoint (offset component signal-context
)
3141 (let ((data (breakpoint-data component offset nil
)))
3143 (error "unknown breakpoint in ~S at offset ~S"
3144 (debug-fun-name (debug-fun-from-pc component offset
))
3146 (let ((breakpoints (breakpoint-data-breakpoints data
)))
3147 (if (or (null breakpoints
)
3148 (eq (breakpoint-kind (car breakpoints
)) :fun-end
))
3149 (handle-fun-end-breakpoint-aux breakpoints data signal-context
)
3150 (handle-breakpoint-aux breakpoints data
3151 offset component signal-context
)))))
3153 ;;; This holds breakpoint-datas while invoking the breakpoint hooks
3154 ;;; associated with that particular component and location. While they
3155 ;;; are executing, if we hit the location again, we ignore the
3156 ;;; breakpoint to avoid infinite recursion. fun-end breakpoints
3157 ;;; must work differently since the breakpoint-data is unique for each
3159 (defvar *executing-breakpoint-hooks
* nil
)
3161 ;;; This handles code-location and DEBUG-FUN :FUN-START
3163 (defun handle-breakpoint-aux (breakpoints data offset component signal-context
)
3165 (bug "breakpoint that nobody wants"))
3166 (unless (member data
*executing-breakpoint-hooks
*)
3167 (let ((*executing-breakpoint-hooks
* (cons data
3168 *executing-breakpoint-hooks
*)))
3169 (invoke-breakpoint-hooks breakpoints signal-context
)))
3170 ;; At this point breakpoints may not hold the same list as
3171 ;; BREAKPOINT-DATA-BREAKPOINTS since invoking hooks may have allowed
3172 ;; a breakpoint deactivation. In fact, if all breakpoints were
3173 ;; deactivated then data is invalid since it was deleted and so the
3174 ;; correct one must be looked up if it is to be used. If there are
3175 ;; no more breakpoints active at this location, then the normal
3176 ;; instruction has been put back, and we do not need to
3177 ;; DO-DISPLACED-INST.
3178 (setf data
(breakpoint-data component offset nil
))
3179 (when (and data
(breakpoint-data-breakpoints data
))
3180 ;; The breakpoint is still active, so we need to execute the
3181 ;; displaced instruction and leave the breakpoint instruction
3182 ;; behind. The best way to do this is different on each machine,
3183 ;; so we just leave it up to the C code.
3184 (breakpoint-do-displaced-inst signal-context
3185 (breakpoint-data-instruction data
))
3186 ;; Some platforms have no usable sigreturn() call. If your
3187 ;; implementation of arch_do_displaced_inst() _does_ sigreturn(),
3188 ;; it's polite to warn here
3189 #!+(and sparc solaris
)
3190 (error "BREAKPOINT-DO-DISPLACED-INST returned?")))
3192 (defun invoke-breakpoint-hooks (breakpoints signal-context
)
3193 (let* ((frame (signal-context-frame signal-context
)))
3194 (dolist (bpt breakpoints
)
3195 (funcall (breakpoint-hook-fun bpt
)
3197 ;; If this is an :UNKNOWN-RETURN-PARTNER, then pass the
3198 ;; hook function the original breakpoint, so that users
3199 ;; aren't forced to confront the fact that some
3200 ;; breakpoints really are two.
3201 (if (eq (breakpoint-kind bpt
) :unknown-return-partner
)
3202 (breakpoint-unknown-return-partner bpt
)
3205 (defun signal-context-frame (signal-context)
3208 (declare (optimize (inhibit-warnings 3)))
3209 (sb!alien
:sap-alien signal-context
(* os-context-t
))))
3210 (cfp (int-sap (sb!vm
:context-register scp sb
!vm
::cfp-offset
))))
3211 (compute-calling-frame cfp
3212 ;; KLUDGE: This argument is ignored on
3213 ;; x86oids in this scenario, but is
3214 ;; declared to be a SAP.
3215 #!+(or x86 x86-64
) (sb!vm
:context-pc scp
)
3216 #!-
(or x86 x86-64
) nil
3219 (defun handle-fun-end-breakpoint (offset component context
)
3220 (let ((data (breakpoint-data component offset nil
)))
3222 (error "unknown breakpoint in ~S at offset ~S"
3223 (debug-fun-name (debug-fun-from-pc component offset
))
3225 (let ((breakpoints (breakpoint-data-breakpoints data
)))
3227 (aver (eq (breakpoint-kind (car breakpoints
)) :fun-end
))
3228 (handle-fun-end-breakpoint-aux breakpoints data context
)))))
3230 ;;; Either HANDLE-BREAKPOINT calls this for :FUN-END breakpoints
3231 ;;; [old C code] or HANDLE-FUN-END-BREAKPOINT calls this directly
3233 (defun handle-fun-end-breakpoint-aux (breakpoints data signal-context
)
3234 ;; FIXME: This looks brittle: what if we are interrupted somewhere
3235 ;; here? ...or do we have interrupts disabled here?
3236 (delete-breakpoint-data data
)
3239 (declare (optimize (inhibit-warnings 3)))
3240 (sb!alien
:sap-alien signal-context
(* os-context-t
))))
3241 (frame (signal-context-frame signal-context
))
3242 (component (breakpoint-data-component data
))
3243 (cookie (gethash component
*fun-end-cookies
*)))
3244 (remhash component
*fun-end-cookies
*)
3245 (dolist (bpt breakpoints
)
3246 (funcall (breakpoint-hook-fun bpt
)
3248 (get-fun-end-breakpoint-values scp
)
3251 (defun get-fun-end-breakpoint-values (scp)
3252 (let ((ocfp (int-sap (sb!vm
:context-register
3254 #!-
(or x86 x86-64
) sb
!vm
::ocfp-offset
3255 #!+(or x86 x86-64
) sb
!vm
::ebx-offset
)))
3256 (nargs (make-lisp-obj
3257 (sb!vm
:context-register scp sb
!vm
::nargs-offset
)))
3258 (reg-arg-offsets '#.sb
!vm
::*register-arg-offsets
*)
3261 (dotimes (arg-num nargs
)
3262 (push (if reg-arg-offsets
3264 (sb!vm
:context-register scp
(pop reg-arg-offsets
)))
3265 (stack-ref ocfp
(+ arg-num
3266 #!+(or x86 x86-64
) sb
!vm
::sp-
>fp-offset
)))
3268 (nreverse results
)))
3270 ;;;; MAKE-BOGUS-LRA (used for :FUN-END breakpoints)
3272 (defconstant bogus-lra-constants
3273 #!-
(or x86-64 x86
) 1
3275 ;; One more for a fixup vector
3278 ;;; Make a bogus LRA object that signals a breakpoint trap when
3279 ;;; returned to. If the breakpoint trap handler returns, REAL-LRA is
3280 ;;; returned to. Three values are returned: the bogus LRA object, the
3281 ;;; code component it is part of, and the PC offset for the trap
3283 (defun make-bogus-lra (real-lra)
3285 ;; These are really code labels, not variables: but this way we get
3287 (let* ((src-start (static-foreign-symbol-sap "fun_end_breakpoint_guts"))
3288 (src-end (static-foreign-symbol-sap "fun_end_breakpoint_end"))
3289 (trap-loc (static-foreign-symbol-sap "fun_end_breakpoint_trap"))
3290 (length (sap- src-end src-start
))
3292 (sb!c
:allocate-code-object
#!+immobile-code nil
3293 bogus-lra-constants length
))
3294 (dst-start (code-instructions code-object
)))
3295 (declare (type system-area-pointer
3296 src-start src-end dst-start trap-loc
)
3297 (type index length
))
3298 (setf (%code-debug-info code-object
) :bogus-lra
)
3300 (setf (code-header-ref code-object real-lra-slot
) real-lra
3301 ;; Set up the widetag and header of LRA
3302 ;; The header contains the same thing as the code object header,
3303 ;; the number of boxed words, which include slots and
3304 ;; constants and it has to be double word aligned.
3306 ;; It used to be a part of the fun_end_breakpoint_guts
3307 ;; but its position and value depend on the offsets
3308 ;; and alignment of code object slots.
3309 (sap-ref-word dst-start
(- sb
!vm
:n-word-bits
))
3310 (+ sb
!vm
:return-pc-widetag
3311 (logandc2 (+ code-constants-offset
3316 (multiple-value-bind (offset code
) (compute-lra-data-from-pc real-lra
)
3317 (setf (code-header-ref code-object real-lra-slot
) code
)
3318 (setf (code-header-ref code-object
(1+ real-lra-slot
)) offset
))
3319 (system-area-ub8-copy src-start
0 dst-start
0 length
)
3321 (sb!vm
:sanctify-for-execution code-object
)
3323 (values dst-start code-object
(sap- trap-loc src-start
))
3325 (let ((new-lra (make-lisp-obj (+ (sap-int dst-start
)
3326 sb
!vm
:other-pointer-lowtag
))))
3327 ;; We used to set the header value of the LRA here to the
3328 ;; offset from the enclosing component to the LRA header, but
3329 ;; MAKE-LISP-OBJ actually checks the value before we get a
3330 ;; chance to set it, so it's now done in arch-assem.S.
3331 (values new-lra code-object
(sap- trap-loc src-start
))))))
3335 ;;; This appears here because it cannot go with the DEBUG-FUN
3336 ;;; interface since DO-DEBUG-BLOCK-LOCATIONS isn't defined until after
3337 ;;; the DEBUG-FUN routines.
3339 ;;; Return a code-location before the body of a function and after all
3340 ;;; the arguments are in place; or if that location can't be
3341 ;;; determined due to a lack of debug information, return NIL.
3342 (defun debug-fun-start-location (debug-fun)
3343 (etypecase debug-fun
3345 (code-location-from-pc debug-fun
3346 (sb!c
::compiled-debug-fun-start-pc
3347 (compiled-debug-fun-compiler-debug-fun
3350 ;; (There used to be more cases back before sbcl-0.7.0, when
3351 ;; we did special tricks to debug the IR1 interpreter.)
3355 ;;;; Single-stepping
3357 ;;; The single-stepper works by inserting conditional trap instructions
3358 ;;; into the generated code (see src/compiler/*/call.lisp), currently:
3360 ;;; 1) Before the code generated for a function call that was
3361 ;;; translated to a VOP
3362 ;;; 2) Just before the call instruction for a full call
3364 ;;; In both cases, the trap will only be executed if stepping has been
3365 ;;; enabled, in which case it'll ultimately be handled by
3366 ;;; HANDLE-SINGLE-STEP-TRAP, which will either signal a stepping condition,
3367 ;;; or replace the function that's about to be called with a wrapper
3368 ;;; which will signal the condition.
3370 (defun handle-single-step-trap (kind callee-register-offset
)
3371 (let ((context (nth-interrupt-context (1- *free-interrupt-context-index
*))))
3372 ;; The following calls must get tail-call eliminated for
3373 ;; *STEP-FRAME* to get set correctly on non-x86.
3374 (if (= kind single-step-before-trap
)
3375 (handle-single-step-before-trap context
)
3376 (handle-single-step-around-trap context callee-register-offset
))))
3378 (defvar *step-frame
* nil
)
3380 (defun handle-single-step-before-trap (context)
3381 (let ((step-info (single-step-info-from-context context
)))
3382 ;; If there was not enough debug information available, there's no
3383 ;; sense in signaling the condition.
3387 (signal-context-frame (sb!alien
::alien-sap context
))
3389 ;; KLUDGE: Use the first non-foreign frame as the
3390 ;; *STACK-TOP-HINT*. Getting the frame from the signal
3391 ;; context as on x86 would be cleaner, but
3392 ;; SIGNAL-CONTEXT-FRAME doesn't seem seem to work at all
3394 (loop with frame
= (frame-down (top-frame))
3396 for dfun
= (frame-debug-fun frame
)
3397 do
(when (typep dfun
'compiled-debug-fun
)
3399 do
(setf frame
(frame-down frame
)))))
3400 (sb!impl
::step-form step-info
3401 ;; We could theoretically store information in
3402 ;; the debug-info about to determine the
3403 ;; arguments here, but for now let's just pass
3407 ;;; This function will replace the fdefn / function that was in the
3408 ;;; register at CALLEE-REGISTER-OFFSET with a wrapper function. To
3409 ;;; ensure that the full call will use the wrapper instead of the
3410 ;;; original, conditional trap must be emitted before the fdefn /
3411 ;;; function is converted into a raw address.
3412 (defun handle-single-step-around-trap (context callee-register-offset
)
3413 ;; Fetch the function / fdefn we're about to call from the
3414 ;; appropriate register.
3416 (cond #!+immobile-space
3417 ((eql (sap-ref-8 (context-pc context
) 0) #xB8
) ; MOV EAX,imm
3418 ;; FIXME: this ought to go in {target}-vm.lisp as
3419 ;; something like GET-FDEFN-FOR-SINGLE-STEP
3420 (let ((jmp-target (sap-ref-32 (context-pc context
) 1)))
3422 (+ jmp-target
(- (ash word-shift fdefn-raw-addr-slot
))
3423 other-pointer-lowtag
))))
3425 (context-register context callee-register-offset
)))))
3426 (step-info (single-step-info-from-context context
)))
3427 ;; If there was not enough debug information available, there's no
3428 ;; sense in signaling the condition.
3430 (return-from handle-single-step-around-trap
))
3431 (let* ((fun (lambda (&rest args
)
3433 (apply (typecase callee
3434 (fdefn (fdefn-fun callee
))
3437 ;; Signal a step condition
3439 (let ((*step-frame
* (frame-down (top-frame))))
3440 (sb!impl
::step-form step-info args
))))
3441 ;; And proceed based on its return value.
3443 ;; STEP-INTO was selected. Use *STEP-OUT* to
3444 ;; let the stepper know that selecting the
3445 ;; STEP-OUT restart is valid inside this
3446 (let ((sb!impl
::*step-out
* :maybe
))
3447 ;; Pass the return values of the call to
3448 ;; STEP-VALUES, which will signal a
3449 ;; condition with them in the VALUES slot.
3451 (multiple-value-call #'sb
!impl
::step-values
3454 ;; If the user selected the STEP-OUT
3455 ;; restart during the call, resume
3457 (when (eq sb
!impl
::*step-out
* t
)
3458 (sb!impl
::enable-stepping
))))
3459 ;; STEP-NEXT / CONTINUE / OUT selected:
3460 ;; Disable the stepper for the duration of
3462 (sb!impl
::with-stepping-disabled
3464 (new-callee (etypecase callee
3466 (let ((fdefn (make-fdefn (gensym))))
3467 (setf (fdefn-fun fdefn
) fun
)
3470 ;; And then store the wrapper in the same place.
3471 (with-pinned-objects (new-callee)
3472 ;; %SET-CONTEXT-REGISTER is a function, so the address of
3473 ;; NEW-CALLEE gets converted to a fixnum before passing, which
3474 ;; won't keep NEW-CALLEE pinned down. Once it's inside
3475 ;; CONTEXT, which is registered in thread->interrupt_contexts,
3476 ;; it will properly point to NEW-CALLEE.
3479 ((fdefn-p callee
) ; as above, should be in {target}-vm.lisp
3480 ;; Don't store the FDEFN in RAX, but the address of the raw_addr slot.
3481 (setf (context-register context callee-register-offset
)
3482 (+ (get-lisp-obj-address new-callee
)
3483 (- other-pointer-lowtag
)
3484 (ash word-shift fdefn-raw-addr-slot
)))
3485 ;; And skip over the MOV EAX, imm instruction.
3486 (sb!vm
::incf-context-pc context
5))
3488 (setf (context-register context callee-register-offset
)
3489 (get-lisp-obj-address new-callee
))))))))
3491 ;;; Given a signal context, fetch the step-info that's been stored in
3492 ;;; the debug info at the trap point.
3493 (defun single-step-info-from-context (context)
3494 (multiple-value-bind (pc-offset code
)
3495 (compute-lra-data-from-pc (context-pc context
))
3496 (let* ((debug-fun (debug-fun-from-pc code pc-offset
))
3497 (location (code-location-from-pc debug-fun
3502 (fill-in-code-location location
)
3503 (code-location-debug-source location
)
3504 (compiled-code-location-step-info location
))
3508 ;;; Return the frame that triggered a single-step condition. Used to
3509 ;;; provide a *STACK-TOP-HINT*.
3510 (defun find-stepped-frame ()
3514 ;;;; fetching errorful function name
3516 ;;; This flag is used to prevent infinite recursive lossage when
3517 ;;; we can't find the caller for some reason.
3518 (defvar *finding-frame
* nil
)
3520 (defun find-caller-frame ()
3521 (unless *finding-frame
*
3523 (let* ((*finding-frame
* t
)
3524 (frame (frame-down (frame-down (top-frame)))))
3525 (flush-frames-above frame
)
3527 ((or error debug-condition
) ()))))
3529 (defun find-interrupted-frame ()
3530 (when (plusp *free-interrupt-context-index
*)
3532 (signal-context-frame
3534 (nth-interrupt-context (1- *free-interrupt-context-index
*))))
3535 ((or error debug-condition
) ()))))
3537 (defun find-caller-of-named-frame (name)
3538 (unless *finding-frame
*
3540 (let ((*finding-frame
* t
))
3541 (do ((frame (top-frame) (frame-down frame
)))
3543 (when (and (compiled-frame-p frame
)
3544 (eq name
(debug-fun-name
3545 (frame-debug-fun frame
))))
3546 (let ((caller (frame-down frame
)))
3547 (flush-frames-above caller
)
3549 ((or error debug-condition
) ()))))