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 (defstruct (sb-c::core-debug-source
(:pure t
)
17 (:include debug-source
))
18 ;; Compilation to memory stores each toplevel form given to %COMPILE.
19 ;; That form can generate multiple functions, and those functions can
20 ;; be in one or more code components. They all point at the same form.
22 (function nil
:read-only t
))
24 ;;; FIXME: There are an awful lot of package prefixes in this code.
25 ;;; Couldn't we have SB-DI use the SB-C and SB-VM packages?
29 ;;;; The interface to building debugging tools signals conditions that
30 ;;;; prevent it from adhering to its contract. These are
31 ;;;; serious-conditions because the program using the interface must
32 ;;;; handle them before it can correctly continue execution. These
33 ;;;; debugging conditions are not errors since it is no fault of the
34 ;;;; programmers that the conditions occur. The interface does not
35 ;;;; provide for programs to detect these situations other than
36 ;;;; calling a routine that detects them and signals a condition. For
37 ;;;; example, programmers call A which may fail to return successfully
38 ;;;; due to a lack of debug information, and there is no B the they
39 ;;;; could have called to realize A would fail. It is not an error to
40 ;;;; have called A, but it is an error for the program to then ignore
41 ;;;; the signal generated by A since it cannot continue without A's
42 ;;;; correctly returning a value or performing some operation.
44 ;;;; Use DEBUG-SIGNAL to signal these conditions.
46 (define-condition debug-condition
(serious-condition)
49 "All DEBUG-CONDITIONs inherit from this type. These are serious conditions
50 that must be handled, but they are not programmer errors."))
52 (define-condition no-debug-fun-returns
(debug-condition)
53 ((debug-fun :reader no-debug-fun-returns-debug-fun
56 "The system could not return values from a frame with DEBUG-FUN since
57 it lacked information about returning values.")
58 (:report
(lambda (condition stream
)
59 (let ((fun (debug-fun-fun
60 (no-debug-fun-returns-debug-fun condition
))))
62 "~&Cannot return values from ~:[frame~;~:*~S~] since ~
63 the debug information lacks details about returning ~
67 (define-condition no-debug-blocks
(debug-condition)
68 ((debug-fun :reader no-debug-blocks-debug-fun
70 (:documentation
"The debug-fun has no debug-block information.")
71 (:report
(lambda (condition stream
)
72 (format stream
"~&~S has no debug-block information."
73 (no-debug-blocks-debug-fun condition
)))))
75 (define-condition no-debug-vars
(debug-condition)
76 ((debug-fun :reader no-debug-vars-debug-fun
78 (:documentation
"The DEBUG-FUN has no DEBUG-VAR information.")
79 (:report
(lambda (condition stream
)
80 (format stream
"~&~S has no debug variable information."
81 (no-debug-vars-debug-fun condition
)))))
83 (define-condition lambda-list-unavailable
(debug-condition)
84 ((debug-fun :reader lambda-list-unavailable-debug-fun
87 "The DEBUG-FUN has no lambda list since argument DEBUG-VARs are
89 (:report
(lambda (condition stream
)
90 (format stream
"~&~S has no lambda-list information available."
91 (lambda-list-unavailable-debug-fun condition
)))))
93 (define-condition invalid-value
(debug-condition)
94 ((debug-var :reader invalid-value-debug-var
:initarg
:debug-var
)
95 (frame :reader invalid-value-frame
:initarg
:frame
))
96 (:report
(lambda (condition stream
)
97 (format stream
"~&~S has :invalid or :unknown value in ~S."
98 (invalid-value-debug-var condition
)
99 (invalid-value-frame condition
)))))
101 (define-condition ambiguous-var-name
(debug-condition)
102 ((name :reader ambiguous-var-name-name
:initarg
:name
)
103 (frame :reader ambiguous-var-name-frame
:initarg
:frame
))
104 (:report
(lambda (condition stream
)
105 (format stream
"~&~S names more than one valid variable in ~S."
106 (ambiguous-var-name-name condition
)
107 (ambiguous-var-name-frame condition
)))))
109 ;;;; errors and DEBUG-SIGNAL
111 ;;; The debug-internals code tries to signal all programmer errors as
112 ;;; subtypes of DEBUG-ERROR. There are calls to ERROR signalling
113 ;;; SIMPLE-ERRORs, but these dummy checks in the code and shouldn't
116 ;;; While under development, this code also signals errors in code
117 ;;; branches that remain unimplemented.
119 (define-condition debug-error
(error) ()
121 "All programmer errors from using the interface for building debugging
122 tools inherit from this type."))
124 (define-condition unhandled-debug-condition
(debug-error)
125 ((condition :reader unhandled-debug-condition-condition
:initarg
:condition
))
126 (:report
(lambda (condition stream
)
127 (format stream
"~&unhandled DEBUG-CONDITION:~%~A"
128 (unhandled-debug-condition-condition condition
)))))
130 (define-condition unknown-code-location
(debug-error)
131 ((code-location :reader unknown-code-location-code-location
132 :initarg
:code-location
))
133 (:report
(lambda (condition stream
)
134 (format stream
"~&invalid use of an unknown code-location: ~S"
135 (unknown-code-location-code-location condition
)))))
137 (define-condition unknown-debug-var
(debug-error)
138 ((debug-var :reader unknown-debug-var-debug-var
:initarg
:debug-var
)
139 (debug-fun :reader unknown-debug-var-debug-fun
140 :initarg
:debug-fun
))
141 (:report
(lambda (condition stream
)
142 (format stream
"~&~S is not in ~S."
143 (unknown-debug-var-debug-var condition
)
144 (unknown-debug-var-debug-fun condition
)))))
146 (define-condition invalid-control-stack-pointer
(debug-error)
148 (:report
(lambda (condition stream
)
149 (declare (ignore condition
))
151 (write-string "invalid control stack pointer" stream
))))
153 (define-condition frame-fun-mismatch
(debug-error)
154 ((code-location :reader frame-fun-mismatch-code-location
155 :initarg
:code-location
)
156 (frame :reader frame-fun-mismatch-frame
:initarg
:frame
)
157 (form :reader frame-fun-mismatch-form
:initarg
:form
))
158 (:report
(lambda (condition stream
)
161 "~&Form was preprocessed for ~S,~% but called on ~S:~% ~S"
162 (frame-fun-mismatch-code-location condition
)
163 (frame-fun-mismatch-frame condition
)
164 (frame-fun-mismatch-form condition
)))))
166 ;;; This signals debug-conditions. If they go unhandled, then signal
167 ;;; an UNHANDLED-DEBUG-CONDITION error.
169 ;;; ??? Get SIGNAL in the right package!
170 (defmacro debug-signal
(datum &rest arguments
)
171 `(let ((condition (make-condition ,datum
,@arguments
)))
173 (error 'unhandled-debug-condition
:condition condition
)))
177 ;;;; Most of these structures model information stored in internal
178 ;;;; data structures created by the compiler. Whenever comments
179 ;;;; preface an object or type with "compiler", they refer to the
180 ;;;; internal compiler thing, not to the object or type with the same
181 ;;;; name in the "SB-DI" package.
185 ;;; These exist for caching data stored in packed binary form in
186 ;;; compiler DEBUG-FUNs.
187 (defstruct (debug-var (:constructor nil
)
189 ;; string name of the variable.
190 (name (missing-arg) :type simple-string
)
191 ;; package containing the variable. NIL when the variable's name is
193 (package nil
:type
(or null package
))
194 ;; a unique integer identification relative to other variables with the same
196 (id 0 :type index
:read-only t
)
197 ;; Does the variable always have a valid value?
198 (alive-p nil
:type boolean
:read-only t
))
199 (defmethod print-object ((debug-var debug-var
) stream
)
200 (print-unreadable-object (debug-var stream
:type t
:identity t
)
203 (sb-xc:package-name
(debug-var-package debug-var
))
204 (debug-var-name debug-var
)
205 (debug-var-id debug-var
))))
207 (setf (documentation 'debug-var-id
'function
)
208 "Return the integer that makes DEBUG-VAR's name and package unique
209 with respect to other DEBUG-VARs in the same function.")
211 (defstruct (compiled-debug-var
213 (:constructor make-compiled-debug-var
214 (name package id alive-p
215 sc
+offset save-sc
+offset indirect-sc
+offset
))
217 ;; storage class and offset (unexported)
218 (sc+offset nil
:type sb-c
:sc
+offset
:read-only t
)
219 ;; storage class and offset when saved somewhere
220 (save-sc+offset nil
:type
(or sb-c
:sc
+offset null
) :read-only t
)
221 ;; For indirect closures the fp of the parent frame is stored in the
222 ;; normal SC+OFFSETs above, and this has the offset into the frame
223 (indirect-sc+offset nil
:type
(or sb-c
:sc
+offset null
) :read-only t
))
227 ;;; These exist for caching data stored in packed binary form in
228 ;;; compiler DEBUG-FUNs. There should only be one DEBUG-FUN in existence
229 ;;; for any function; that is, all CODE-LOCATIONs and other objects
230 ;;; that reference DEBUG-FUNs point to unique objects. This is
231 ;;; due to the overhead in cached information.
233 (defstruct (debug-fun (:constructor nil
)
235 ;; some representation of the function arguments. See
236 ;; DEBUG-FUN-LAMBDA-LIST.
237 ;; NOTE: must parse vars before parsing arg list stuff.
238 (%lambda-list
:unparsed
)
239 ;; cached DEBUG-VARS information (unexported).
240 ;; These are sorted by their name.
241 (%debug-vars
:unparsed
:type
(or simple-vector null
(member :unparsed
)))
242 ;; cached debug-block information. This is NIL when we have tried to
243 ;; parse the packed binary info, but none is available.
244 (blocks :unparsed
:type
(or simple-vector null
(member :unparsed
)))
245 ;; the actual function if available
246 (%function
:unparsed
:type
(or null function
(member :unparsed
))))
247 (defmethod print-object ((obj debug-fun
) stream
)
248 (print-unreadable-object (obj stream
:type t
)
249 (prin1 (debug-fun-name obj
) stream
)))
251 (defstruct (bogus-debug-fun
253 (:constructor make-bogus-debug-fun
260 (%name nil
:read-only t
))
264 ;;; These exist for caching data stored in packed binary form in compiler
266 (defstruct (debug-block (:constructor nil
)
268 ;; This indicates whether the block is a special glob of code shared
269 ;; by various functions and tucked away elsewhere in a component.
270 ;; This kind of block has no start code-location. This slot is in
271 ;; all debug-blocks since it is an exported interface.
272 (elsewhere-p nil
:type boolean
))
273 (defmethod print-object ((obj debug-block
) str
)
274 (print-unreadable-object (obj str
:type t
)
275 (prin1 (debug-block-fun-name obj
) str
)))
277 (setf (documentation 'debug-block-elsewhere-p
'function
)
278 "Return whether debug-block represents elsewhere code.")
280 (defstruct (compiled-debug-block (:include debug-block
)
282 ;; code-location information for the block
283 (code-locations #() :type simple-vector
))
285 (defstruct (code-location (:constructor nil
)
287 ;; the DEBUG-FUN containing this CODE-LOCATION
288 (debug-fun nil
:type debug-fun
:read-only t
)
289 ;; This is initially :UNSURE. Upon first trying to access an
290 ;; :UNPARSED slot, if the data is unavailable, then this becomes T,
291 ;; and the code-location is unknown. If the data is available, this
292 ;; becomes NIL, a known location. We can't use a separate type
293 ;; code-location for this since we must return code-locations before
294 ;; we can tell whether they're known or unknown. For example, when
295 ;; parsing the stack, we don't want to unpack all the variables and
296 ;; blocks just to make frames.
297 (%unknown-p
:unsure
:type
(member t nil
:unsure
))
298 ;; the DEBUG-BLOCK containing CODE-LOCATION. XXX Possibly toss this
299 ;; out and just find it in the blocks cache in DEBUG-FUN.
300 (%debug-block
:unparsed
:type
(or debug-block
(member :unparsed
)))
301 ;; This is the number of forms processed by the compiler or loader
302 ;; before the top level form containing this code-location.
303 (%tlf-offset
:unparsed
:type
(or index
(member :unparsed
)))
304 ;; This is the depth-first number of the node that begins
305 ;; code-location within its top level form.
306 (%form-number
:unparsed
:type
(or index
(member :unparsed
))))
310 ;;; These represent call frames on the stack.
311 (defstruct (frame (:constructor nil
)
313 ;; the next frame up, or NIL when top frame
314 ;; KLUDGE - (OR NULL FRAME), and not (OR FRAME NULL), because PARSE-1-DSD
315 ;; warns; we're so bad at understanding recursive structure.
316 (up nil
:type
(or null frame
))
317 ;; the previous frame down, or NIL when the bottom frame. Before
318 ;; computing the next frame down, this slot holds the frame pointer
319 ;; to the control stack for the given frame. This lets us get the
320 ;; next frame down and the return-pc for that frame.
321 (%down
:unparsed
:type
(or (member nil
:unparsed
) frame
))
322 ;; the DEBUG-FUN for the function whose call this frame represents
323 (debug-fun nil
:type debug-fun
:read-only t
)
324 ;; the CODE-LOCATION where the frame's DEBUG-FUN will continue
325 ;; running when program execution returns to this frame. If someone
326 ;; interrupted this frame, the result could be an unknown
328 (code-location nil
:type code-location
:read-only t
)
329 ;; an a-list of catch-tags to code-locations
330 (%catches
:unparsed
:type
(or list
(member :unparsed
)))
331 ;; pointer to frame on control stack (unexported)
332 (pointer nil
:read-only t
)
333 ;; This is the frame's number for prompt printing. Top is zero.
334 (number 0 :type index
))
336 (defstruct (compiled-frame
338 (:constructor make-compiled-frame
339 (pointer up debug-fun code-location number
342 ;; This indicates whether someone interrupted the frame.
343 ;; (unexported). If escaped, this is a pointer to the state that was
344 ;; saved when we were interrupted, an os_context_t, i.e. the third
345 ;; argument to an SA_SIGACTION-style signal handler.
346 (escaped nil
:read-only t
))
347 (defmethod print-object ((obj compiled-frame
) str
)
348 (print-unreadable-object (obj str
:type t
)
350 "~S~:[~;, interrupted~]"
351 (debug-fun-name (frame-debug-fun obj
))
352 (compiled-frame-escaped obj
))))
357 ;;; This is an internal structure that manages information about a
358 ;;; breakpoint locations. See *COMPONENT-BREAKPOINT-OFFSETS*.
359 (defstruct (breakpoint-data (:constructor make-breakpoint-data
362 ;; This is the component in which the breakpoint lies.
363 (component nil
:read-only t
)
364 ;; This is the byte offset into the component.
365 (offset nil
:type index
:read-only t
)
366 ;; The original instruction replaced by the breakpoint.
367 (instruction nil
:type
(or null word
))
368 ;; A list of user breakpoints at this location.
369 (breakpoints nil
:type list
))
370 (defmethod print-object ((obj breakpoint-data
) str
)
371 (print-unreadable-object (obj str
:type t
)
372 (format str
"~S at ~S"
374 (debug-fun-from-pc (breakpoint-data-component obj
)
375 (breakpoint-data-offset obj
)))
376 (breakpoint-data-offset obj
))))
378 (defstruct (breakpoint (:constructor %make-breakpoint
379 (hook-fun what kind %info
))
381 ;; This is the function invoked when execution encounters the
382 ;; breakpoint. It takes a frame, the breakpoint, and optionally a
383 ;; list of values. Values are supplied for :FUN-END breakpoints as
384 ;; values to return for the function containing the breakpoint.
385 ;; :FUN-END breakpoint hook functions also take a cookie argument.
386 ;; See the COOKIE-FUN slot.
387 (hook-fun (required-arg) :type function
)
388 ;; CODE-LOCATION or DEBUG-FUN
389 (what nil
:type
(or code-location debug-fun
) :read-only t
)
390 ;; :CODE-LOCATION, :FUN-START, or :FUN-END for that kind
391 ;; of breakpoint. :UNKNOWN-RETURN-PARTNER if this is the partner of
392 ;; a :code-location breakpoint at an :UNKNOWN-RETURN code-location.
393 (kind nil
:type
(member :code-location
:fun-start
:fun-end
394 :unknown-return-partner
)
396 ;; Status helps the user and the implementation.
397 (status :inactive
:type
(member :active
:inactive
:deleted
))
398 ;; This is a backpointer to a breakpoint-data.
399 (internal-data nil
:type
(or null breakpoint-data
))
400 ;; With code-locations whose type is :UNKNOWN-RETURN, there are
401 ;; really two breakpoints: one at the multiple-value entry point,
402 ;; and one at the single-value entry point. This slot holds the
403 ;; breakpoint for the other one, or NIL if this isn't at an
404 ;; :UNKNOWN-RETURN code location.
405 (unknown-return-partner nil
:type
(or null breakpoint
))
406 ;; :FUN-END breakpoints use a breakpoint at the :FUN-START
407 ;; to establish the end breakpoint upon function entry. We do this
408 ;; by frobbing the LRA to jump to a special piece of code that
409 ;; breaks and provides the return values for the returnee. This slot
410 ;; points to the start breakpoint, so we can activate, deactivate,
412 (start-helper nil
:type
(or null breakpoint
))
413 ;; This is a hook users supply to get a dynamically unique cookie
414 ;; for identifying :FUN-END breakpoint executions. That is, if
415 ;; there is one :FUN-END breakpoint, but there may be multiple
416 ;; pending calls of its function on the stack. This function takes
417 ;; the cookie, and the hook function takes the cookie too.
418 (cookie-fun nil
:type
(or null function
))
419 ;; This slot users can set with whatever information they find useful.
421 (defmethod print-object ((obj breakpoint
) str
)
422 (let ((what (breakpoint-what obj
)))
423 (print-unreadable-object (obj str
:type t
)
428 (debug-fun (debug-fun-name what
)))
431 (debug-fun (breakpoint-kind obj
)))))))
433 (defmacro with-weak-cache
((temp global
) &body body
)
434 `(let ((,temp
(or ,global
437 (make-hash-table :test
'eq
440 ;; double-checked idiom has to ensure that no other CPU
441 ;; can see a just-made hash-table until all the slots of
442 ;; the instance are definitely published before the
443 ;; global var points to it.
444 (sb-thread:barrier
(:write
))
445 (or (cas ,global nil new
) new
)))))
448 (defstruct (compiled-debug-fun
450 (:constructor %make-compiled-debug-fun
451 (compiler-debug-fun component
))
453 ;; compiler's dumped DEBUG-FUN information (unexported)
454 (compiler-debug-fun nil
:type sb-c
::compiled-debug-fun
456 ;; code object (unexported).
457 (component nil
:read-only t
)
458 ;; the :FUN-START breakpoint (if any) used to facilitate
459 ;; function end breakpoints
460 (end-starter nil
:type
(or null breakpoint
)))
462 ;;; This maps SB-C::COMPILED-DEBUG-FUNs to SB-DI::COMPILED-DEBUG-FUNs, so we
463 ;;; can get at cached stuff and not duplicate COMPILED-DEBUG-FUN
465 (define-load-time-global *compiled-debug-funs
* nil
)
467 ;;; Make a SB-DI::COMPILED-DEBUG-FUN for a SB-C::COMPILED-DEBUG-FUN and its
468 ;;; component. This maps the latter to the former in
469 ;;; *COMPILED-DEBUG-FUNS*. If there already is a COMPILED-DEBUG-FUN,
470 ;;; then this returns it from *COMPILED-DEBUG-FUNS*.
471 (defun make-compiled-debug-fun (compiler-debug-fun component
)
472 (with-weak-cache (ht *compiled-debug-funs
*)
473 (or (gethash compiler-debug-fun ht
)
474 (setf (gethash compiler-debug-fun ht
)
475 (%make-compiled-debug-fun compiler-debug-fun component
)))))
480 (defmethod print-object ((obj code-location
) str
)
481 (print-unreadable-object (obj str
:type t
)
482 (prin1 (debug-fun-name (code-location-debug-fun obj
))
485 (defstruct (compiled-code-location
486 (:include code-location
)
487 (:constructor make-known-code-location
488 (pc debug-fun %debug-block %tlf-offset %form-number
489 %live-set kind step-info context
&aux
(%unknown-p nil
)))
490 (:constructor make-compiled-code-location
(pc debug-fun
))
492 ;; an index into DEBUG-FUN's component slot
493 (pc nil
:type index
:read-only t
)
494 ;; a bit-vector indexed by a variable's position in
495 ;; DEBUG-FUN-DEBUG-VARS indicating whether the variable has a
496 ;; valid value at this code-location. (unexported).
497 (%live-set
:unparsed
:type
(or simple-bit-vector
(member :unparsed
)))
498 ;; (unexported) To see SB-C::LOCATION-KIND, do
499 ;; (SB-KERNEL:TYPEXPAND 'SB-C::LOCATION-KIND).
500 (kind :unparsed
:type
(or (member :unparsed
) sb-c
::location-kind
))
501 (step-info :unparsed
:type
(or (member :unparsed
) simple-string
))
506 ;;; This is used in FIND-ESCAPED-FRAME and with the "breakpoint return" objects
507 ;;; and LRAs used for :FUN-END breakpoints. When a code object's
508 ;;; debug-info slot is :BPT-LRA, then the REAL-LRA-SLOT contains the
509 ;;; real location to continue executing, as opposed to the intermediary object
510 ;;; which appeared in some frame's LRA location.
511 ;;; NB: If you change change REAL-LRA-SLOT, then you must also change
512 ;;; "#define REAL_LRA_SLOT" in breakpoint.c. These have unfortunately
513 ;;; different values, because this slot is relative to the object base
514 ;;; address, whereas the one in C is an index into code->constants.
515 (defconstant bpt-lra-boxed-nwords
516 ;; * For non-x86: a single boxed constant holds the true LRA.
517 ;; Additionally, MIPS gets a boxed slot for the cookie
518 ;; that formerly went in a weak hash-table.
519 ;; * For x86[-64]: one boxed constant holds the code object to which
520 ;; to return, one holds the displacement into that object,
521 ;; and one holds the cookie
522 (+ code-constants-offset
2 #+(or x86-64 x86
) 1))
523 (defconstant real-lra-slot code-constants-offset
)
524 (defconstant cookie-slot
(+ code-constants-offset
1 #+(or x86 x86-64
) 1))
526 (declaim (inline control-stack-pointer-valid-p
))
527 (defun control-stack-pointer-valid-p (x &optional
(aligned t
))
528 (declare (type system-area-pointer x
))
529 (let* (#-stack-grows-downward-not-upward
531 (descriptor-sap *control-stack-start
*))
532 #+stack-grows-downward-not-upward
534 (descriptor-sap *control-stack-end
*)))
535 #-stack-grows-downward-not-upward
536 (and (sap< x
(current-sp))
537 (sap<= control-stack-start x
)
538 (or (not aligned
) (zerop (logand (sap-int x
)
539 (1- (ash 1 word-shift
))))))
540 #+stack-grows-downward-not-upward
541 (and (sap>= x
(current-sp))
542 (sap> control-stack-end x
)
543 (or (not aligned
) (zerop (logand (sap-int x
)
544 (1- (ash 1 word-shift
))))))))
546 (declaim (inline valid-tagged-pointer-p
))
547 (sb-alien:define-alien-routine
("lisp_valid_tagged_pointer_p" valid-tagged-pointer-p
)
549 (pointer system-area-pointer
))
551 ;;; There are many opportunities for things to go wrong when searching
552 ;;; the heap for a code component. One possible problem occurs when
553 ;;; component_ptr_from_pc() searches for a code component on a page which
554 ;;; gets partially evacuated on x86[-64]. Suppose it contains pinned code
555 ;;; preceded by some objects that got forwarded. The scan performed by
556 ;;; gc_search_space could be interrupted in the middle, and resume execution
557 ;;; looking at a forwarding pointer, which gets the fatal "no size function".
558 ;;; Morover, excess delay between finding an object and creating a Lisp
559 ;;; descriptor introduces additional potential for error.
560 ;;; So we do two things to mitigate that problem:
561 ;;; (1) use unsafe %MAKE-LISP-OBJ, since we've already determined
562 ;;; where the code object starts with certainty, and we don't need
563 ;;; yet another search to test validity of the address.
564 ;;; (2) wrap the calls in WITH-CODE-PAGES-PINNED.
566 ;;; Here's a concrete example, assuming the following objects exists:
567 ;;; 0x8000: vector header |
568 ;;; 0x8008: vector length | object 1
569 ;;; 0x8010: vector contents |
571 ;;; 0x8100: code object | object 2
573 ;;; thread A is backtracing, and currently in component_ptr_to_pc(),
574 ;;; looking at 0x8000. Suppose the code is pinned, and that a garbage collection
575 ;;; will partially evacuate the page, and that partial evacuation zero-fills
576 ;;; the unused ranges (which it no longer does). Consider these schedules:
578 ;;; Thread A Thread B
579 ;;; -------- --------
580 ;;; read header @ 0x8000
581 ;;; GC happens. zero-fill from 0x8000:0x8100
582 ;;; read length @ 0x8008 => 0
583 ;;; (skip to next object)
584 ;;; read header @ 0x8010 => junk
586 ;;; In this schedule, thread A reads a word which is not a valid object header.
588 ;;; But partial evacution no longer zeros the freed subranges - instead it writes
589 ;;; an unboxed array header so that only two words are touched per unused subrange.
590 ;;; This causes a different problem: The array may appear to contain forwarding
591 ;;; pointers to live objects that were moved off the page, and those pointers
592 ;;; appear to be embedded in the unboxed array.
594 ;;; Use of WITHOUT-GCING is unfortunate - it's always preferable to
595 ;;; try to pin individual objects - but to do better we would have to
596 ;;; implement page-wide hazard pointers informing GC not to do anything
597 ;;; to any object on a specified page.
599 ;;; On top of the considerations about dynamic space, there is a further issue
600 ;;; with allocation of immobile code. The allocator creates transient inconsistent
601 ;;; states when it reuses holes. Even if the header could be written atomically,
602 ;;; there can be junk in the remaining bytes of the hole that gets rewritten as
603 ;;; a smaller hole. It's evident that acquiring the allocator mutex works around
604 ;;; that glitch, as without such precaution, 'compiler.pure.lisp' would routinely
605 ;;; crash when run in multiple threads. A better fix would be to preseve invariants
606 ;;; at all times when allocating, both for the new hole that results from the hole
607 ;;; that gets cut down to size, and for the new object per se. Example:
608 ;;; | hole ............................ | 1 Kb
609 ;;; ^ new-object here ^ smaller hole starts here
612 ;;; We first need to atomically write the header of the smaller hole
613 ;;; (which can't even be seen until the new object header is written).
614 ;;; This establishes that there won't be an inconsistent state.
615 ;;; Then we need to atomically write the new object header.
616 ;;; I suspect that both atomic writes should use double-wide CAS,
617 ;;; because if the object header is written using lispword-sized writes,
618 ;;; then the object can be sized wrong, and in this case it does cause problems
619 ;;; because the remaining bytes are not zero-filled. The allocator is similar
620 ;;; to malloc() in that regard.
622 (defun code-header-from-pc (pc)
623 (with-code-pages-pinned (:dynamic
)
625 ;; FIXME: It's accessing *dynspace-codeblob-tree*, which
626 ;; isn't gc-safe when done from C (especially on the
627 ;; precise gc backends).
629 (sb-alien:alien-funcall
630 (sb-alien:extern-alien
"lisp_component_ptr_from_pc"
631 (function sb-alien
:unsigned system-area-pointer
))
633 (system-area-pointer pc
)
634 (word (int-sap pc
)))))))
635 (unless (= base-ptr
0) (%make-lisp-obj
(logior base-ptr other-pointer-lowtag
))))))
637 ;;;; (OR X86 X86-64) support
642 (defun compute-lra-data-from-pc (pc)
643 (declare (type system-area-pointer pc
))
644 ;; While theoretically we should inhibit GC any time we search the heap,
645 ;; in practice this function can only be called for code that is somewhere
646 ;; on the stack, and therefore conservatively pinned.
647 (let ((code (code-header-from-pc pc
)))
648 (values (if code
(sap- pc
(code-instructions code
)) nil
)
651 ;;; Check for a valid return address - it could be any valid C/Lisp
654 ;;; XXX Could be a little smarter.
655 (declaim (inline ra-pointer-valid-p
))
656 (defun ra-pointer-valid-p (ra)
657 (declare (type system-area-pointer ra
))
659 ;; not the first page (which is unmapped)
661 ;; FIXME: Where is this documented? Is it really true of every CPU
662 ;; architecture? Is it even necessarily true in current SBCL?
663 (>= (sap-int ra
) 4096)
664 ;; not a Lisp stack pointer
665 (not (control-stack-pointer-valid-p ra
))))
667 ;;; Try to find a valid previous stack. This is complex on the x86 as
668 ;;; it can jump between C and Lisp frames. To help find a valid frame
669 ;;; it searches backwards.
671 ;;; XXX Should probably check whether it has reached the bottom of the
674 ;;; XXX Should handle interrupted frames, both Lisp and C. At present
675 ;;; it manages to find a fp trail, see linux hack below.
676 (declaim (maybe-inline x86-call-context
))
677 (defun x86-call-context (fp)
678 (declare (type system-area-pointer fp
))
679 (let ((ocfp (sap-ref-sap fp
(sb-vm::frame-byte-offset ocfp-save-offset
)))
680 (ra (sap-ref-sap fp
(sb-vm::frame-byte-offset return-pc-save-offset
))))
681 (if (and (control-stack-pointer-valid-p fp
)
683 (control-stack-pointer-valid-p ocfp
)
684 (ra-pointer-valid-p ra
))
686 (values nil
(int-sap 0) (int-sap 0)))))
690 ;;; Return the top frame of the control stack as it was before calling
693 (/noshow0
"entering TOP-FRAME")
694 (compute-calling-frame (descriptor-sap (%caller-frame
))
698 ;;; Flush all of the frames above FRAME, and renumber all the frames
700 (defun flush-frames-above (frame)
701 (setf (frame-up frame
) nil
)
702 (do ((number 0 (1+ number
))
703 (frame frame
(frame-%down frame
)))
704 ((not (frame-p frame
)))
705 (setf (frame-number frame
) number
)))
708 (defun find-saved-frame-down (fp up-frame
)
709 (multiple-value-bind (saved-fp saved-pc
)
710 (find-saved-fp-and-pc fp
)
712 (compute-calling-frame saved-fp saved-pc up-frame t
))))
714 #+c-stack-is-control-stack
716 (defun walk-binding-stack (symbol function
)
718 (tls-index (symbol-tls-index symbol
))
721 (sap-ref-lispobj (sb-thread::current-thread-sap
) tls-index
)
723 (symbol-value symbol
)))
724 ;; This is slightly dangerous - the right thing would be
725 ;; to access using SAP-REF-WORD and compare like a few lines below.
726 ;; Why does #-sb-thread even check for this at all?
727 (unless (eql (get-lisp-obj-address current-value
) no-tls-value-marker
)
728 (funcall function current-value
)
729 (loop for start
= (descriptor-sap *binding-stack-start
*)
730 for pointer
= (descriptor-sap sb-vm
::*binding-stack-pointer
*)
731 then
(sap+ pointer
(* n-word-bytes -
2))
732 while
(sap> pointer start
)
734 #+sb-thread
(eq (sap-ref-word pointer
(* n-word-bytes -
1)) tls-index
)
735 #-sb-thread
(eq (sap-ref-lispobj pointer
(* n-word-bytes -
1)) symbol
)
736 do
(unless (or #+sb-thread
737 (= (sap-ref-word pointer
(* n-word-bytes -
2)) no-tls-value-marker
))
739 (sap-ref-lispobj pointer
740 (* n-word-bytes -
2))))))))
742 (defun find-saved-fp-and-pc (fp)
745 'sb-alien-internals
:*saved-fp
*
748 (let* ((saved-fp (descriptor-sap x
))
749 (caller-fp (sap-ref-sap saved-fp
750 (sb-vm::frame-byte-offset
752 (when (#+stack-grows-downward-not-upward
754 #-stack-grows-downward-not-upward
757 (return (values caller-fp
758 (sap-ref-sap saved-fp
759 (sb-vm::frame-byte-offset
760 return-pc-save-offset
)))))))))))
763 (defun return-pc-offset-for-location (debug-fun location
)
764 (declare (ignorable debug-fun location
))
765 #+fp-and-pc-standard-save
766 sb-c
:return-pc-passing-offset
767 #-fp-and-pc-standard-save
770 (let ((c-d-f (compiled-debug-fun-compiler-debug-fun debug-fun
))
771 (pc-offset (compiled-code-location-pc location
)))
772 (if (>= pc-offset
(sb-c::compiled-debug-fun-lra-saved-pc c-d-f
))
773 (sb-c::compiled-debug-fun-return-pc c-d-f
)
774 (sb-c::compiled-debug-fun-return-pc-pass c-d-f
))))
776 ;; No handy backend (or compiler) defined constant for this one,
777 ;; so construct it here and now.
778 (sb-c:make-sc
+offset control-stack-sc-number
#-riscv lra-save-offset
#+riscv sb-vm
::ra-save-offset
))))
780 (defun old-fp-offset-for-location (debug-fun location
)
781 (declare (ignorable debug-fun location
))
782 #+fp-and-pc-standard-save
783 sb-c
:old-fp-passing-offset
784 #-fp-and-pc-standard-save
787 (let ((c-d-f (compiled-debug-fun-compiler-debug-fun debug-fun
))
788 (pc-offset (compiled-code-location-pc location
)))
789 (if (>= pc-offset
(sb-c::compiled-debug-fun-cfp-saved-pc c-d-f
))
790 (sb-c::compiled-debug-fun-old-fp c-d-f
)
791 sb-c
:old-fp-passing-offset
)))
793 ;; No handy backend (or compiler) defined constant for this one,
794 ;; so construct it here and now.
795 (sb-c:make-sc
+offset control-stack-sc-number ocfp-save-offset
))))
797 (defun frame-saved-cfp (frame debug-fun
)
798 (sub-access-debug-var-slot
799 (frame-pointer frame
)
800 (old-fp-offset-for-location debug-fun
(frame-code-location frame
))
801 (compiled-frame-escaped frame
)))
803 (defun frame-saved-lra (frame debug-fun
)
804 (sub-access-debug-var-slot
805 (frame-pointer frame
)
806 (return-pc-offset-for-location debug-fun
(frame-code-location frame
))
807 (compiled-frame-escaped frame
)))
809 (defun (setf frame-saved-lra
) (new-lra frame debug-fun
)
810 (sub-set-debug-var-slot
811 (frame-pointer frame
)
812 (return-pc-offset-for-location debug-fun
(frame-code-location frame
))
814 (compiled-frame-escaped frame
))
817 ;;; Return the frame immediately below FRAME on the stack; or when
818 ;;; FRAME is the bottom of the stack, return NIL.
819 (defun frame-down (frame)
820 (/noshow0
"entering FRAME-DOWN")
821 ;; We have to access the old-fp and return-pc out of frame and pass
822 ;; them to COMPUTE-CALLING-FRAME.
823 (let ((down (frame-%down frame
)))
824 (if (eq down
:unparsed
)
825 (let ((debug-fun (frame-debug-fun frame
)))
826 (/noshow0
"in DOWN :UNPARSED case")
827 (setf (frame-%down frame
)
829 ((or compiled-debug-fun
830 #-
(or x86 x86-64
) bogus-debug-fun
)
831 (compute-calling-frame
832 (descriptor-sap (frame-saved-cfp frame debug-fun
))
833 (frame-saved-lra frame debug-fun
)
837 (let ((fp (frame-pointer frame
)))
838 (when (control-stack-pointer-valid-p fp
)
839 (multiple-value-bind (ok ra ofp
) (x86-call-context fp
)
841 (compute-calling-frame ofp ra frame
)
842 (find-saved-frame-down fp frame
)))))))))
845 (defun foreign-function-backtrace-name (sap)
846 (let ((name (sap-foreign-symbol sap
)))
848 (format nil
"foreign function: ~A" name
)
849 (format nil
"foreign function: #x~X" (sap-int sap
)))))
851 ;;; This returns a frame for the one existing in time immediately
852 ;;; prior to the frame referenced by current-fp. This is current-fp's
853 ;;; caller or the next frame down the control stack. If there is no
854 ;;; down frame, this returns NIL for the bottom of the stack. UP-FRAME
855 ;;; is the up link for the resulting frame object, and it is null when
856 ;;; we call this to get the top of the stack.
858 ;;; The current frame contains the pointer to the temporally previous
859 ;;; frame we want, and the current frame contains the pc at which we
860 ;;; will continue executing upon returning to that previous frame.
862 ;;; Note: Sometimes LRA is actually a fixnum. This happens when lisp
863 ;;; calls into C. In this case, the code object is stored on the stack
864 ;;; after the LRA, and the LRA is the word offset.
865 #-
(or x86 x86-64 arm64 riscv
)
866 (defun compute-calling-frame (caller lra up-frame
&optional savedp
)
867 (declare (type system-area-pointer caller
)
869 (/noshow0
"entering COMPUTE-CALLING-FRAME")
870 (when (control-stack-pointer-valid-p caller
)
872 (multiple-value-bind (code pc-offset escaped
)
874 (multiple-value-bind (word-offset code
)
876 (let ((fp (frame-pointer up-frame
)))
878 (let ((code (stack-ref fp
(1+ lra-save-offset
))))
881 (%make-lisp-obj
(logior (ash code n-fixnum-tag-bits
)
882 other-pointer-lowtag
)))))
883 (values (get-header-data lra
)
884 (lra-code-header lra
)))
887 (* (1+ (- word-offset
(code-header-words code
)))
890 (values :foreign-function
893 (find-escaped-frame caller
))
894 (if (and (code-component-p code
)
895 (eq (%code-debug-info code
) :bpt-lra
))
896 (let ((real-lra (code-header-ref code real-lra-slot
)))
897 (compute-calling-frame caller real-lra up-frame
))
898 (let ((d-fun (case code
900 (make-bogus-debug-fun
901 "undefined function"))
903 (make-bogus-debug-fun
904 (foreign-function-backtrace-name
905 (int-sap (get-lisp-obj-address lra
)))))
907 (make-bogus-debug-fun
908 "bogus stack frame"))
910 (debug-fun-from-pc code pc-offset
)))))
911 (/noshow0
"returning MAKE-COMPILED-FRAME from COMPUTE-CALLING-FRAME")
912 (make-compiled-frame caller up-frame d-fun
913 (code-location-from-pc d-fun pc-offset
915 (if up-frame
(1+ (frame-number up-frame
)) 0)
918 (defun compute-calling-frame (caller ra up-frame
&optional savedp
)
919 (declare (type system-area-pointer caller
)
921 (when (control-stack-pointer-valid-p caller
)
922 (multiple-value-bind (code pc-offset escaped
)
924 (let* ((ra-sap (int-sap (ash ra n-fixnum-tag-bits
)))
925 (code (code-header-from-pc ra-sap
)))
928 (sap- ra-sap
(code-instructions code
))
930 (find-escaped-frame caller
))
931 (if (and (code-component-p code
)
932 (eq (%code-debug-info code
) :bpt-lra
))
933 (let ((real-lra (code-header-ref code real-lra-slot
)))
934 (compute-calling-frame caller real-lra up-frame
))
935 (let ((d-fun (case code
937 (make-bogus-debug-fun
938 "undefined function"))
940 (make-bogus-debug-fun
941 (foreign-function-backtrace-name
942 (int-sap (get-lisp-obj-address ra
)))))
944 (make-bogus-debug-fun
945 "bogus stack frame"))
947 (debug-fun-from-pc code pc-offset escaped
)))))
948 (make-compiled-frame caller up-frame d-fun
949 (code-location-from-pc d-fun pc-offset
951 (if up-frame
(1+ (frame-number up-frame
)) 0)
954 (defun compute-calling-frame (caller ra up-frame
&optional savedp
)
955 (declare (type system-area-pointer caller ra
))
956 (/noshow0
"entering COMPUTE-CALLING-FRAME")
957 (when (control-stack-pointer-valid-p caller
)
959 ;; First check for an escaped frame.
960 (multiple-value-bind (code pc-offset escaped off-stack
)
961 (find-escaped-frame caller
)
964 ;; If it's escaped it may be a function end breakpoint trap.
965 (when (and (code-component-p code
)
966 (eq (%code-debug-info code
) :bpt-lra
))
967 ;; If :bpt-lra grab the real lra.
968 (setq pc-offset
(code-header-ref code
(1+ real-lra-slot
)))
969 (setq code
(code-header-ref code real-lra-slot
))
972 (multiple-value-setq (pc-offset code
)
973 (compute-lra-data-from-pc ra
))
975 (setf code
:foreign-function
977 (let ((d-fun (case code
979 (make-bogus-debug-fun
980 "undefined function"))
982 (make-bogus-debug-fun
983 (foreign-function-backtrace-name ra
)))
985 (make-bogus-debug-fun
986 "bogus stack frame"))
988 (debug-fun-from-pc code pc-offset escaped
)))))
989 (/noshow0
"returning MAKE-COMPILED-FRAME from COMPUTE-CALLING-FRAME")
990 (make-compiled-frame caller up-frame d-fun
991 (code-location-from-pc d-fun pc-offset
993 (if up-frame
(1+ (frame-number up-frame
)) 0)
994 ;; If we have an interrupt-context that's not on
995 ;; our stack at all, and we're computing the
996 ;; from from a saved FP, we're probably looking
997 ;; at an interrupted syscall.
998 (or escaped
(and savedp off-stack
)))))))
1000 (defun nth-interrupt-context (n)
1001 (declare (muffle-conditions compiler-note
))
1002 (declare (type (mod #.max-interrupts
) n
)
1003 (optimize (speed 3) (safety 0)))
1004 (let ((tls-words (ash (sb-alien:extern-alien
"dynamic_values_bytes"
1005 (sb-alien:unsigned
32))
1007 (sb-alien:sap-alien
(sb-vm::current-thread-offset-sap
(+ tls-words n
))
1010 (defun catch-runaway-unwind (block)
1011 (declare (ignorable block
))
1012 #-
(and win32 x86
) ;; uses SEH
1013 (let ((target (sap-ref-sap (descriptor-sap block
)
1014 (* unwind-block-uwp-slot n-word-bytes
))))
1015 (loop for uwp
= (descriptor-sap sb-vm
::*current-unwind-protect-block
*)
1016 then
(sap-ref-sap uwp
(* unwind-block-uwp-slot n-word-bytes
))
1017 until
(zerop (sap-int uwp
))
1018 thereis
(sap= target uwp
)
1020 (let* ((pc (sap-ref-sap (descriptor-sap block
)
1021 (* unwind-block-entry-pc-slot n-word-bytes
)))
1022 (code (code-header-from-pc pc
))
1026 (multiple-value-bind (offset valid
) (code-pc-offset pc code
)
1028 (let ((debug-fun (debug-fun-from-pc code offset nil
)))
1029 (and (compiled-debug-fun-p debug-fun
)
1030 (debug-fun-name debug-fun
)))))
1032 (error 'simple-control-error
1034 "Attempt to RETURN-FROM a block or GO to a tag that no longer exists~@[ in ~s~]"
1035 :format-arguments
(list fun-name
))))))
1037 (defun code-pc-offset (pc code
)
1038 (declare (type code-component code
))
1039 ;; We wrap WITH-PINNED-OBJECTS around CODE, but in truth this can go wrong if the
1040 ;; code was transported after taking a PC and before getting here. i.e. there is
1041 ;; nothing to be gained by arranging that while we calculate CODE-INSTRUCTIONS
1042 ;; the code can't move if it already moved.
1043 ;; The precisely GCed backends would be a lot more correct with respect to
1044 ;; debug-related stuff if we just never move code that is on-stack.
1045 (let ((pc-offset (with-pinned-objects (code)
1046 (sap- pc
(code-instructions code
))))
1047 (code-size (%code-text-size code
)))
1048 (values pc-offset
(<= 0 pc-offset code-size
) code-size
)))
1050 (defun context-code-pc-offset (context code
)
1051 (code-pc-offset (context-pc context
) code
))
1053 (defun find-escaped-frame (frame-pointer)
1054 (declare (type system-area-pointer frame-pointer
))
1055 (/noshow0
"entering FIND-ESCAPED-FRAME")
1056 (dotimes (index *free-interrupt-context-index
* (values nil
0 nil
))
1057 (let* ((context (nth-interrupt-context index
))
1058 (cfp (int-sap (context-register context sb-vm
::cfp-offset
))))
1059 (/noshow0
"got CONTEXT")
1061 (unless (control-stack-pointer-valid-p cfp
)
1062 (return (values nil nil nil t
)))
1063 (when (sap= frame-pointer cfp
)
1064 (with-code-pages-pinned (:dynamic
)
1065 (return (escaped-frame-from-context context
)))))))
1068 (defun escaped-frame-from-context (context)
1069 (declare (type (sb-alien:alien
(* os-context-t
)) context
))
1071 (let ((code (code-object-from-context context
)))
1072 (/noshow0
"got CODE")
1074 ;; KLUDGE: Detect undefined functions by a range-check
1075 ;; against the trampoline address and the following
1076 ;; function in the runtime.
1077 (return (values code
0 context
)))
1078 (multiple-value-bind
1080 (context-code-pc-offset context code
)
1082 ;; We were in an assembly routine. Therefore, use the
1085 ;; FIXME: Should this be WARN or ERROR or what?
1086 (format t
"** pc-offset ~S not in code obj ~S?~%"
1088 (/noshow0
"returning from FIND-ESCAPED-FRAME")
1090 (values code pc-offset context
))))))
1093 (defun escaped-frame-from-context (context)
1094 (declare (type (sb-alien:alien
(* os-context-t
)) context
))
1096 (let ((code (code-object-from-context context
)))
1097 (/noshow0
"got CODE")
1098 (when (symbolp code
)
1099 (return (values code
0 context
)))
1100 (multiple-value-bind
1101 (pc-offset valid-p code-size
)
1102 (context-code-pc-offset context code
)
1104 ;; We were in an assembly routine.
1105 (multiple-value-bind (new-pc-offset computed-return
)
1106 (find-pc-from-assembly-fun code context
)
1107 (setf pc-offset new-pc-offset
)
1108 (unless (<= 0 pc-offset code-size
)
1110 "Set PC-OFFSET to zero and continue backtrace."
1113 "~@<PC-OFFSET (~D) not in code object. Frame details:~
1114 ~2I~:@_PC: #X~X~:@_CODE: ~S~:@_CODE FUN: ~S~:@_LRA: ~
1115 #X~X~:@_COMPUTED RETURN: #X~X.~:>"
1118 (sap-int (context-pc context
))
1120 (%code-entry-point code
0)
1121 #-
(or riscv arm arm64
)
1122 (context-register context sb-vm
::lra-offset
)
1124 (context-register context sb-vm
::ra-offset
)
1126 (stack-ref (int-sap (context-register context
1130 ;; We failed to pinpoint where PC is, but set
1131 ;; pc-offset to 0 to keep the backtrace from
1133 (setf pc-offset
0))))
1134 (/noshow0
"returning from FIND-ESCAPED-FRAME")
1136 (if (eq (%code-debug-info code
) :bpt-lra
)
1137 (let ((real-lra (code-header-ref code real-lra-slot
)))
1138 (values (lra-code-header real-lra
)
1139 (get-header-data real-lra
)
1141 (values code pc-offset context
)))))))
1144 (defun find-pc-from-assembly-fun (code scp
)
1145 "Finds the PC for the return from an assembly routine properly.
1146 For some architectures (such as PPC) this will not be the $LRA
1148 (with-pinned-objects (code)
1149 (let ((return-machine-address (sb-vm::return-machine-address scp
))
1150 (code-header-len (* (code-header-words code
) n-word-bytes
)))
1151 (values (- return-machine-address
1152 (- (get-lisp-obj-address code
) other-pointer-lowtag
)
1154 return-machine-address
))))
1156 ;;; Find the code object corresponding to the object represented by
1157 ;;; bits and return it. We assume bogus functions correspond to the
1158 ;;; undefined-function.
1159 #+(or x86 x86-64 arm64
)
1160 (defun code-object-from-context (context)
1161 (declare (type (sb-alien:alien
(* os-context-t
)) context
))
1162 (code-header-from-pc (context-pc context
)))
1164 #-
(or x86 x86-64 arm64
)
1165 (defun code-object-from-context (context)
1166 (declare (type (sb-alien:alien
(* os-context-t
)) context
))
1167 ;; The GC constraint on the program counter on precisely-scavenged
1168 ;; backends is that it partakes of the interior-pointer nature.
1169 ;; Which means that it may be within the scope of an object other
1170 ;; than that pointed to by reg_CODE / $CODE. This is necessarily
1171 ;; the case during function call and return: whichever the outbound
1172 ;; function is has reg_CODE set up for itself, and the inbound
1173 ;; function cannot have reg_CODE set up until after the program
1174 ;; counter is within its body, otherwise a badly timed signal can
1175 ;; mess things up entirely. In practical terms, this means that we
1176 ;; need to do the same sort of pairing of interior pointers that the
1177 ;; GC does these days (see scavenge_interrupt_context() in
1178 ;; gc-common.c for details), but limiting to "things that can be
1179 ;; code objects". -- AB, 2018-Jan-11
1181 ;; Oh, and as of this writing, AFAIK, the only precisely-scavenged
1182 ;; backends that are actually interrupt-safe around function calls
1183 ;; are PPC, ARM64, and probably ARM. PPC and ARM64 because they
1184 ;; have thread support, and GC load testing on PPC is how this
1185 ;; constraint was found in the first place. Probably ARM because I
1186 ;; wrote the bulk of the ARM backend well after I fixed function
1187 ;; calling on PPC and rewrote scavenge_interrupt_context() so that
1188 ;; things behaved reliably. -- AB, 2018-Jan-11
1189 (flet ((normalize-candidate (object)
1190 ;; Unlike with the prior implementation, we cannot presume
1191 ;; that a FUNCTION is amenable to FUN-CODE-HEADER (it might
1192 ;; be a closure, and that is unlikely to be at all useful).
1193 ;; Fortunately, WIDETAG-OF comes up with sane values for
1194 ;; all object types, and we can pick off the SIMPLE-FUN
1195 ;; case easily enough.
1196 (let ((widetag (widetag-of object
)))
1197 (cond ((= widetag code-header-widetag
)
1200 ((= widetag return-pc-widetag
)
1201 (lra-code-header object
))
1202 ((= widetag simple-fun-widetag
)
1203 (or (fun-code-header object
)
1204 :undefined-function
))
1207 (dolist (boxed-reg-offset sb-vm
::boxed-regs
1208 ;; If we can't actually pair the PC then we presume that
1209 ;; we're in an assembly-routine and that reg_CODE is, in
1210 ;; fact, the right thing to use... And that it will do
1211 ;; no harm to return it here anyway even if it isn't.
1212 (normalize-candidate
1214 (let ((code (context-register context sb-vm
::code-offset
)))
1215 (%make-lisp-obj
(if (logtest lowtag-mask code
)
1217 (logior code other-pointer-lowtag
))))
1219 (boxed-context-register context sb-vm
::code-offset
)))
1221 (normalize-candidate
1222 (boxed-context-register context boxed-reg-offset
))))
1223 (when (and (not (symbolp candidate
)) ;; NIL or :UNDEFINED-FUNCTION
1224 (nth-value 1 (context-code-pc-offset context candidate
)))
1225 (return candidate
))))))
1227 ;;;; frame utilities
1229 (defun compiled-debug-fun-from-pc (debug-info pc
&optional escaped
)
1230 (let* ((fun-map (get-debug-info-fun-map debug-info
))
1231 (len (length fun-map
)))
1232 (declare (type simple-vector fun-map
))
1236 (first-elsewhere-pc (sb-c::compiled-debug-fun-elsewhere-pc
1239 (if escaped
;; See the comment below
1240 (>= pc first-elsewhere-pc
)
1241 (> pc first-elsewhere-pc
))))
1242 (declare (type index i
))
1245 (let ((next-pc (if elsewhere-p
1246 (sb-c::compiled-debug-fun-elsewhere-pc
1247 (svref fun-map
(1+ i
)))
1248 (svref fun-map i
))))
1251 ;; Non-escaped frame means that this frame calls something.
1252 ;; And the PC points to where something should return.
1253 ;; The return adress may be in the next
1254 ;; function, e.g. in local tail calls the
1255 ;; function will be entered just after the
1257 ;; See debug.impure.lisp/:local-tail-call for a test-case
1259 (return (svref fun-map
(1- i
))))
1262 ;;; This returns a COMPILED-DEBUG-FUN for COMPONENT and PC. We fetch the
1263 ;;; SB-C::DEBUG-INFO and run down its FUN-MAP to get a
1264 ;;; SB-C::COMPILED-DEBUG-FUN from the PC. The result only needs to
1265 ;;; reference the COMPONENT, for function constants, and the
1266 ;;; SB-C::COMPILED-DEBUG-FUN.
1267 (defun debug-fun-from-pc (component pc
&optional
(escaped t
))
1268 (let ((info (%code-debug-info component
)))
1270 (sb-c::compiled-debug-info
1271 (make-compiled-debug-fun (compiled-debug-fun-from-pc info pc escaped
) component
))
1272 ((or hash-table
(cons hash-table
)) ; interrupted in an assembler routine
1273 (let ((routine (dohash ((name pc-range
) (if (listp info
) (car info
) info
))
1274 (when (<= (car pc-range
) pc
(cadr pc-range
))
1276 (make-bogus-debug-fun (cond ((not routine
)
1277 "no debug information for frame")
1278 ((memq routine
'(sb-vm::undefined-tramp
1279 sb-vm
::undefined-alien-tramp
))
1280 "undefined function")
1283 (make-bogus-debug-fun "function end breakpoint")))))
1285 ;;; This returns a code-location for the COMPILED-DEBUG-FUN,
1286 ;;; DEBUG-FUN, and the pc into its code vector. If we stopped at a
1287 ;;; breakpoint, find the CODE-LOCATION for that breakpoint. Otherwise,
1288 ;;; make an :UNSURE code location, so it can be filled in when we
1289 ;;; figure out what is going on.
1290 (defun code-location-from-pc (debug-fun pc escaped
)
1291 (or (and (compiled-debug-fun-p debug-fun
)
1293 (let ((data (breakpoint-data
1294 (compiled-debug-fun-component debug-fun
)
1296 (when (and data
(breakpoint-data-breakpoints data
))
1297 (let ((what (breakpoint-what
1298 (first (breakpoint-data-breakpoints data
)))))
1299 (when (compiled-code-location-p what
)
1301 (make-compiled-code-location pc debug-fun
)))
1303 ;;; Return an alist mapping catch tags to CODE-LOCATIONs. These are
1304 ;;; CODE-LOCATIONs at which execution would continue with frame as the
1305 ;;; top frame if someone threw to the corresponding tag.
1306 (defun frame-catches (frame)
1307 (let ((catch (descriptor-sap *current-catch-block
*))
1308 (reversed-result nil
)
1309 (fp (frame-pointer frame
)))
1310 (labels ((catch-ref (slot)
1311 (sap-ref-lispobj catch
(* slot n-word-bytes
)))
1312 #-
(or x86 x86-64 arm64 riscv
)
1313 (catch-entry-offset ()
1314 (let* ((lra (catch-ref catch-block-entry-pc-slot
))
1315 (component (catch-ref catch-block-code-slot
))
1317 (component (%make-lisp-obj
(logior (ash component n-fixnum-tag-bits
)
1318 other-pointer-lowtag
))))
1319 (* (- (1+ (get-header-data lra
))
1320 (code-header-words component
))
1322 #+(or x86 x86-64 arm64 riscv
)
1323 (catch-entry-offset ()
1324 (let* ((ra (sap-ref-sap
1325 catch
(* catch-block-entry-pc-slot
1328 (catch-ref catch-block-code-slot
)
1329 #+(or x86 x86-64 arm64
)
1330 (code-header-from-pc ra
)))
1332 (- (get-lisp-obj-address component
)
1333 other-pointer-lowtag
)
1334 (* (code-header-words component
)
1336 (declare (inline catch-ref catch-entry-offset
))
1338 until
(zerop (sap-int catch
))
1339 finally
(return (nreverse reversed-result
))
1342 (catch-ref catch-block-cfp-slot
)))
1343 (push (cons (catch-ref catch-block-tag-slot
)
1344 (make-compiled-code-location
1345 (catch-entry-offset) (frame-debug-fun frame
)))
1349 (catch-ref catch-block-previous-catch-slot
)))))))
1351 ;;; Modify the value of the OLD-TAG catches in FRAME to NEW-TAG
1352 (defun replace-frame-catch-tag (frame old-tag new-tag
)
1353 (let ((catch (descriptor-sap *current-catch-block
*))
1354 (fp (frame-pointer frame
)))
1355 (labels ((catch-ref (slot)
1356 (sap-ref-lispobj catch
(* slot n-word-bytes
)))
1357 ((setf catch-ref
) (value slot
)
1358 (setf (sap-ref-lispobj catch
(* slot n-word-bytes
))
1360 (declare (inline catch-ref
(setf catch-ref
)))
1362 until
(zerop (sap-int catch
))
1365 (catch-ref catch-block-cfp-slot
)))
1366 (let ((current-tag (catch-ref catch-block-tag-slot
)))
1367 (when (eq current-tag old-tag
)
1368 (setf (catch-ref catch-block-tag-slot
) new-tag
))))
1371 (catch-ref catch-block-previous-catch-slot
)))))))
1375 ;;;; operations on DEBUG-FUNs
1377 ;;; Execute the forms in a context with BLOCK-VAR bound to each
1378 ;;; DEBUG-BLOCK in DEBUG-FUN successively. Result is an optional
1379 ;;; form to execute for return values, and DO-DEBUG-FUN-BLOCKS
1380 ;;; returns nil if there is no result form. This signals a
1381 ;;; NO-DEBUG-BLOCKS condition when the DEBUG-FUN lacks
1382 ;;; DEBUG-BLOCK information.
1383 (defmacro do-debug-fun-blocks
((block-var debug-fun
&optional result
)
1385 (let ((blocks (gensym))
1387 `(let ((,blocks
(debug-fun-debug-blocks ,debug-fun
)))
1388 (declare (simple-vector ,blocks
))
1389 (dotimes (,i
(length ,blocks
) ,result
)
1390 (let ((,block-var
(svref ,blocks
,i
)))
1393 ;;; Execute body in a context with VAR bound to each DEBUG-VAR in
1394 ;;; DEBUG-FUN. This returns the value of executing result (defaults to
1395 ;;; nil). This may iterate over only some of DEBUG-FUN's variables or
1396 ;;; none depending on debug policy; for example, possibly the
1397 ;;; compilation only preserved argument information.
1398 (defmacro do-debug-fun-vars
((var debug-fun
&optional result
) &body body
)
1399 (let ((vars (gensym))
1401 `(let ((,vars
(debug-fun-debug-vars ,debug-fun
)))
1402 (declare (type (or null simple-vector
) ,vars
))
1404 (dotimes (,i
(length ,vars
) ,result
)
1405 (let ((,var
(aref ,vars
,i
)))
1409 ;;; Compute byte offset of FUNCTION into CODE-INSTRUCTIONS of its code,
1410 ;;; which is the byte offset from the base of its code
1411 ;;; minus the number of bytes in the boxed portion of its code header.
1412 (defun function-start-pc-offset (function)
1413 (let* ((fun (%fun-fun function
))
1414 (code (fun-code-header fun
)))
1415 (- (%fun-code-offset fun
)
1416 (* (code-header-words code
) n-word-bytes
))))
1418 ;;; Return the object of type FUNCTION associated with the DEBUG-FUN,
1419 ;;; or NIL if the function is unavailable or is non-existent as a user
1420 ;;; callable function object.
1421 (defun debug-fun-fun (debug-fun)
1422 (let ((cached-value (debug-fun-%function debug-fun
)))
1423 (if (eq cached-value
:unparsed
)
1424 (setf (debug-fun-%function debug-fun
)
1425 (etypecase debug-fun
1428 (loop with component
= (compiled-debug-fun-component debug-fun
)
1429 with start-pc
= (sb-c::compiled-debug-fun-start-pc
1430 (compiled-debug-fun-compiler-debug-fun debug-fun
))
1431 for i below
(code-n-entries component
)
1432 for entry
= (%code-entry-point component i
)
1433 while
(> start-pc
(function-start-pc-offset entry
))
1434 do
(setf result entry
))
1436 (bogus-debug-fun nil
)))
1439 ;;; Return the name of the function represented by DEBUG-FUN. This may
1440 ;;; be a string or a cons; do not assume it is a symbol.
1441 (defun debug-fun-name (debug-fun &optional
(pretty t
))
1442 (declare (type debug-fun debug-fun
) (ignorable pretty
))
1443 (etypecase debug-fun
1445 (let ((name (sb-c::compiled-debug-fun-name
1446 (compiled-debug-fun-compiler-debug-fun debug-fun
))))
1447 ;; Frames named (.EVAL. special-operator) should show the operator name
1448 ;; in backtraces, but if the debugger needs to detect that the frame is
1449 ;; interpreted for other purposes, it can specify PRETTY = NIL.
1451 ((and (typep name
'(cons (eql sb-interpreter
::.eval.
)))
1453 (if (singleton-p (cdr name
)) (cadr name
) (cdr name
)))
1456 (bogus-debug-fun-%name debug-fun
))))
1458 (defun interrupted-frame-error (frame)
1459 (declare (special sb-kernel
::*current-internal-error
*))
1460 (when (and (compiled-frame-p frame
)
1461 (compiled-frame-escaped frame
)
1462 sb-kernel
::*current-internal-error
*
1463 (array-in-bounds-p sb-c
:+backend-internal-errors
+
1464 sb-kernel
::*current-internal-error
*))
1465 (cadr (svref sb-c
:+backend-internal-errors
+
1466 sb-kernel
::*current-internal-error
*))))
1468 (defun all-args-available-p (frame)
1469 (let ((error (interrupted-frame-error frame
))
1470 (df (frame-debug-fun frame
)))
1471 (or (and (eq error
'invalid-arg-count-error
)
1472 (eq (debug-fun-kind df
) :external
))
1473 (and (eq error
'undefined-fun-error
)
1474 (bogus-debug-fun-p df
)))))
1476 ;; Return the name of the closure, if named, otherwise nil.
1477 (defun debug-fun-closure-name (debug-fun frame
)
1478 (unless (typep debug-fun
'compiled-debug-fun
)
1479 (return-from debug-fun-closure-name nil
))
1480 (let ((compiler-debug-fun (compiled-debug-fun-compiler-debug-fun debug-fun
)))
1482 ;; Frames named (.APPLY. something) are interpreted function applicators.
1483 ;; Show them as the name of the interpreted function being applied.
1485 ((let ((name (sb-c::compiled-debug-fun-name compiler-debug-fun
)))
1486 (when (typep name
'(cons (eql sb-interpreter
::.apply.
)))
1487 ;; Find a variable named FUN.
1488 (awhen (car (debug-fun-symbol-vars debug-fun
'sb-interpreter
::fun
))
1489 (let ((val (debug-var-value it frame
))) ; Ensure it's a function
1490 (when (typep val
'interpreted-function
)
1491 (%fun-name val
))))))) ; Get its name
1492 ((sb-c::compiled-debug-fun-closure-save compiler-debug-fun
)
1494 (if (all-args-available-p frame
)
1495 (sub-access-debug-var-slot (frame-pointer frame
)
1497 (compiled-frame-escaped frame
))
1498 (sub-access-debug-var-slot (frame-pointer frame
) it
)))))))
1500 ;;; Return a DEBUG-FUN that represents debug information for FUN.
1501 (defun fun-debug-fun (fun &key local-name
)
1502 (declare (type function fun
))
1503 (let ((simple-fun (%fun-fun fun
)))
1504 (let* ((name (or local-name
(%simple-fun-name simple-fun
)))
1505 (component (fun-code-header simple-fun
))
1508 (and (sb-c::compiled-debug-fun-p x
)
1509 (equal (sb-c::compiled-debug-fun-name x
) name
)
1510 (eq (sb-c::compiled-debug-fun-kind x
) nil
)))
1511 (get-debug-info-fun-map
1512 (%code-debug-info component
)))))
1514 (make-compiled-debug-fun res component
))
1516 ;; KLUDGE: comment from CMU CL:
1517 ;; This used to be the non-interpreted branch, but
1518 ;; William wrote it to return the debug-fun of fun's XEP
1519 ;; instead of fun's debug-fun. The above code does this
1520 ;; more correctly, but it doesn't get or eliminate all
1521 ;; appropriate cases. It mostly works, and probably
1522 ;; works for all named functions anyway.
1524 (debug-fun-from-pc component
1525 (function-start-pc-offset simple-fun
)))))))
1527 ;;; Return the kind of the function, which is one of :OPTIONAL, :MORE
1528 ;;; :EXTERNAL, :TOPLEVEL, :CLEANUP, or NIL.
1529 (defun debug-fun-kind (debug-fun)
1530 ;; FIXME: This "is one of" information should become part of the function
1531 ;; declamation, not just a doc string
1532 (etypecase debug-fun
1534 (sb-c::compiled-debug-fun-kind
1535 (compiled-debug-fun-compiler-debug-fun debug-fun
)))
1539 ;;; Is there any variable information for DEBUG-FUN?
1540 (defun debug-var-info-available (debug-fun)
1541 (not (not (debug-fun-debug-vars debug-fun
))))
1543 ;;; Return a list of DEBUG-VARs in DEBUG-FUN having the same name
1544 ;;; and package as SYMBOL. If SYMBOL is uninterned, then this returns
1545 ;;; a list of DEBUG-VARs without package names and with the same name
1546 ;;; as symbol. The result of this function is limited to the
1547 ;;; availability of variable information in DEBUG-FUN; for
1548 ;;; example, possibly DEBUG-FUN only knows about its arguments.
1549 (defun debug-fun-symbol-vars (debug-fun symbol
)
1550 (let ((vars (ambiguous-debug-vars debug-fun
(symbol-name symbol
)))
1551 (package (and (sb-xc:symbol-package symbol
)
1552 (sb-xc:package-name
(sb-xc:symbol-package symbol
)))))
1553 (delete-if (if (stringp package
)
1555 (let ((p (sb-xc:package-name
(debug-var-package var
))))
1556 (or (not (stringp p
))
1557 (string/= p package
))))
1559 (stringp (sb-xc:package-name
(debug-var-package var
)))))
1562 ;;; Return a list of DEBUG-VARs in DEBUG-FUN whose names contain
1563 ;;; NAME-PREFIX-STRING as an initial substring. The result of this
1564 ;;; function is limited to the availability of variable information in
1565 ;;; debug-fun; for example, possibly debug-fun only knows
1566 ;;; about its arguments.
1567 (defun ambiguous-debug-vars (debug-fun name-prefix-string
)
1568 (declare (simple-string name-prefix-string
))
1569 (let ((variables (debug-fun-debug-vars debug-fun
)))
1570 (declare (type (or null simple-vector
) variables
))
1572 (let* ((len (length variables
))
1573 (prefix-len (length name-prefix-string
))
1574 (pos (find-var name-prefix-string variables len
))
1577 ;; Find names from pos to variable's len that contain prefix.
1578 (do ((i pos
(1+ i
)))
1580 (let* ((var (svref variables i
))
1581 (name (debug-var-name var
))
1582 (name-len (length name
)))
1583 (declare (simple-string name
))
1584 (when (/= (or (string/= name-prefix-string name
1585 :end1 prefix-len
:end2 name-len
)
1590 (setq res
(nreverse res
)))
1593 ;;; This returns a position in VARIABLES for one containing NAME as an
1594 ;;; initial substring. END is the length of VARIABLES if supplied.
1595 (defun find-var (name variables
&optional end
)
1596 (declare (simple-vector variables
)
1597 (simple-string name
))
1598 (let ((name-len (length name
)))
1599 (position name variables
1601 (let* ((y (debug-var-name y
))
1603 (declare (simple-string y
))
1604 (and (>= y-len name-len
)
1605 (string= x y
:end1 name-len
:end2 name-len
))))
1606 :end
(or end
(length variables
)))))
1608 ;;; Return a list representing the lambda-list for DEBUG-FUN. The
1609 ;;; list has the following structure:
1610 ;;; (required-var1 required-var2
1612 ;;; (:optional var3 suppliedp-var4)
1613 ;;; (:optional var5)
1615 ;;; (:rest var6) (:rest var7)
1617 ;;; (:keyword keyword-symbol var8 suppliedp-var9)
1618 ;;; (:keyword keyword-symbol var10)
1621 ;;; Each VARi is a DEBUG-VAR; however it may be the symbol :DELETED if
1622 ;;; it is unreferenced in DEBUG-FUN. This signals a
1623 ;;; LAMBDA-LIST-UNAVAILABLE condition when there is no argument list
1625 (defun debug-fun-lambda-list (debug-fun)
1626 (etypecase debug-fun
1627 (compiled-debug-fun (compiled-debug-fun-lambda-list debug-fun
))
1628 (bogus-debug-fun nil
)))
1630 ;;; Return the MORE-CONTEXT and MORE-COUNT vars of a DEBUG-FUN.
1631 (defun debug-fun-more-args (debug-fun)
1632 (dolist (spec (debug-fun-lambda-list debug-fun
) nil
)
1633 (when (and (listp spec
)
1634 (eq (first spec
) :more
))
1635 (return (values (second spec
) (third spec
))))))
1637 ;;; Note: If this has to compute the lambda list, it caches it in DEBUG-FUN.
1638 (defun compiled-debug-fun-lambda-list (debug-fun)
1639 (let ((lambda-list (debug-fun-%lambda-list debug-fun
)))
1640 (cond ((eq lambda-list
:unparsed
)
1641 (multiple-value-bind (args argsp
)
1642 (parse-compiled-debug-fun-lambda-list debug-fun
)
1643 (setf (debug-fun-%lambda-list debug-fun
) args
)
1646 (debug-signal 'lambda-list-unavailable
1647 :debug-fun debug-fun
))))
1649 ((bogus-debug-fun-p debug-fun
)
1651 ((sb-c::compiled-debug-fun-arguments
1652 (compiled-debug-fun-compiler-debug-fun debug-fun
))
1653 ;; If the packed information is there (whether empty or not) as
1654 ;; opposed to being nil, then returned our cached value (nil).
1657 ;; Our cached value is nil, and the packed lambda-list information
1658 ;; is nil, so we don't have anything available.
1659 (debug-signal 'lambda-list-unavailable
1660 :debug-fun debug-fun
)))))
1662 ;;; A compact "vector" is either the element itself or a vector
1663 (defun compact-vector-ref (vector index
)
1664 (declare (index index
))
1667 (svref vector index
))
1669 (aver (zerop index
))
1672 (aref vector index
))
1674 (aver (zerop index
))
1677 (defun compact-vector-length (vector)
1686 (defun parse-compiled-debug-fun-lambda-list/args-available
(vars args
)
1687 (declare (type (or null simple-vector
) vars
))
1693 (flet ((push-var (tag-and-info &optional var-count
)
1695 (sys-tlab-append tag-and-info
1696 (loop :repeat var-count
:collect
1697 (compiled-debug-fun-lambda-list-var
1698 args
(incf i
) vars
)))
1701 (var-or-deleted (index-or-deleted)
1702 (if (eq index-or-deleted
'sb-c
::deleted
)
1704 (svref vars index-or-deleted
))))
1708 (let ((ele (aref args i
)))
1710 ((eq ele
'sb-c
::optional-args
)
1712 ((eq ele
'sb-c
::rest-arg
)
1713 (push-var '(:rest
) 1))
1714 ;; The next two args are the &MORE arg context and
1716 ((eq ele
'sb-c
::more-arg
)
1717 (push-var '(:more
) 2))
1718 ;; SUPPLIED-P var immediately following keyword or
1719 ;; optional. Stick the extra var in the result element
1720 ;; representing the keyword or optional, which is the
1722 ((eq ele
'sb-c
::supplied-p
)
1723 (push-var (pop result
) 1))
1724 ;; The keyword of a keyword parameter. Store it so the next
1725 ;; element can be used to form a (:keyword KEYWORD VALUE)
1727 ((typep ele
'(and symbol
(not (eql sb-c
::deleted
))))
1729 ;; The previous element was the keyword of a keyword
1730 ;; parameter and is stored in KEYWORD. The current element
1731 ;; is the index of the value (or a deleted
1732 ;; marker). Construct and push the complete entry.
1734 (push-var (list :keyword keyword
(var-or-deleted ele
))))
1735 ;; We saw an optional marker, so the following non-symbols
1736 ;; are indexes (or deleted markers) indicating optional
1739 (push-var (list :optional
(var-or-deleted ele
))))
1740 ;; Deleted required, optional or keyword argument.
1741 ((eq ele
'sb-c
::deleted
)
1742 (push-var :deleted
))
1743 ;; Required arg at beginning of args array.
1745 (push-var (svref vars ele
))))
1747 finally
(return (nreverse result
))))))
1749 ;;; This is used in COMPILED-DEBUG-FUN-LAMBDA-LIST.
1750 (defun compiled-debug-fun-lambda-list-var (args i vars
)
1751 (declare (type (simple-array * (*)) args
)
1752 (simple-vector vars
))
1753 (let ((ele (aref args i
)))
1754 (cond ((typep ele
'index
) (svref vars ele
))
1755 ((eq ele
'sb-c
::deleted
) :deleted
)
1756 (t (error "malformed arguments description")))))
1758 (defun compiled-debug-fun-debug-info (debug-fun)
1759 (%code-debug-info
(compiled-debug-fun-component debug-fun
)))
1761 ;;;; unpacking variable and basic block data
1763 ;;; The argument is a debug internals structure. This returns the
1764 ;;; DEBUG-BLOCKs for DEBUG-FUN, regardless of whether we have unpacked
1765 ;;; them yet. It signals a NO-DEBUG-BLOCKS condition if it can't
1766 ;;; return the blocks.
1767 (defun debug-fun-debug-blocks (debug-fun)
1768 (let ((blocks (debug-fun-blocks debug-fun
)))
1769 (when (eq blocks
:unparsed
)
1770 (let* ((new (parse-debug-blocks debug-fun
))
1771 (old (cas (debug-fun-blocks debug-fun
) :unparsed new
)))
1772 (setq blocks
(if (eq old
:unparsed
) new old
))))
1774 (debug-signal 'no-debug-blocks
:debug-fun debug-fun
))))
1776 ;;; Return a SIMPLE-VECTOR of DEBUG-BLOCKs or NIL. NIL indicates there
1777 ;;; was no basic block information.
1778 (defun parse-debug-blocks (debug-fun)
1779 (etypecase debug-fun
1781 (let ((parsed (parse-compiled-debug-blocks debug-fun
)))
1782 (if (equalp parsed
#())
1783 (debug-signal 'no-debug-blocks
:debug-fun debug-fun
)
1786 (debug-signal 'no-debug-blocks
:debug-fun debug-fun
))))
1788 ;;; This does some of the work of PARSE-DEBUG-BLOCKS.
1789 (defun parse-compiled-debug-blocks (debug-fun)
1790 (macrolet ((aref+ (a i
) `(prog1 (aref ,a
,i
) (incf ,i
))))
1791 (let* ((var-count (length (debug-fun-debug-vars debug-fun
)))
1792 (compiler-debug-fun (compiled-debug-fun-compiler-debug-fun
1795 (let ((blocks (sb-c::compiled-debug-fun-blocks compiler-debug-fun
)))
1797 (return-from parse-compiled-debug-blocks nil
)
1799 ;; KLUDGE: 8 is a hard-wired constant in the compiler for the
1800 ;; element size of the packed binary representation of the
1802 (live-set-len (ceiling var-count
8))
1803 (tlf-number (sb-c::compiled-debug-fun-tlf-number compiler-debug-fun
))
1804 (elsewhere-pc (sb-c::compiled-debug-fun-elsewhere-pc compiler-debug-fun
))
1806 (len (length blocks
))
1810 (block (make-compiled-debug-block))
1814 (flet ((new-block ()
1816 (setf (compiled-debug-block-code-locations block
)
1817 (coerce (nreverse (shiftf locations nil
))
1819 (compiled-debug-block-elsewhere-p block
)
1821 (push block result-blocks
)
1822 (setf block
(make-compiled-debug-block)))))
1827 (let* ((flags (aref+ blocks i
))
1828 (kind (svref sb-c
::+compiled-code-location-kinds
+
1829 (ldb (byte 3 0) flags
)))
1831 (sb-c:read-var-integerf blocks i
)))
1832 (tlf-offset (or tlf-number
1833 (sb-c::read-var-integerf blocks i
)))
1834 (equal-live (logtest sb-c
::compiled-code-location-equal-live flags
))
1836 (cond ((logtest sb-c
::compiled-code-location-zero-form-number flags
)
1839 (logtest sb-c
::compiled-code-location-live flags
))
1842 (setf prev-form-number
1843 (sb-c:read-var-integerf blocks i
)))))
1847 ((logtest sb-c
::compiled-code-location-live flags
)
1849 (sb-c:read-packed-bit-vector live-set-len blocks i
)))
1851 (make-array (* live-set-len
8) :element-type
'bit
))))
1853 (if (logtest sb-c
::compiled-code-location-stepping flags
)
1854 (sb-c:read-var-string blocks i
)
1857 (and (logtest sb-c
::compiled-code-location-context flags
)
1858 (compact-vector-ref (sb-c::compiled-debug-info-contexts
1859 (%code-debug-info
(compiled-debug-fun-component debug-fun
)))
1860 (sb-c:read-var-integerf blocks i
)))))
1861 (when (or (memq kind
'(:block-start
:non-local-entry
))
1862 (and (not elsewhere-p
)
1864 (setf elsewhere-p t
)))
1866 (push (make-known-code-location
1867 pc debug-fun block tlf-offset
1868 form-number live-set kind
1871 (setf last-pc pc
))))
1872 (coerce (nreverse result-blocks
) 'simple-vector
))))
1874 ;;; VARS is the parsed variables for a minimal debug function. We need
1875 ;;; to assign names of the form ARG-NNN. We must pad with leading
1876 ;;; zeros, since the arguments must be in alphabetical order.
1877 (defun assign-minimal-var-names (vars)
1878 (declare (simple-vector vars
))
1879 (let* ((len (length vars
))
1880 (width (length (format nil
"~D" (1- len
))))) ; use base 10 in both places!
1882 (setf (compiled-debug-var-name (svref vars i
))
1883 (possibly-base-stringize-to-heap (format nil
"ARG-~V,'0D" width i
))))))
1885 ;;; Parse the packed representation of DEBUG-VARs from
1886 ;;; DEBUG-FUN's SB-C::COMPILED-DEBUG-FUN, returning a vector
1887 ;;; of DEBUG-VARs, or NIL if there was no information to parse.
1888 (defun parse-compiled-debug-vars (debug-fun)
1889 (let* ((cdebug-fun (compiled-debug-fun-compiler-debug-fun
1891 (packed-vars (sb-c::compiled-debug-fun-vars cdebug-fun
))
1892 (default-package (sb-c::compiled-debug-info-package
1893 (compiled-debug-fun-debug-info debug-fun
)))
1894 (args-minimal (eq (sb-c::compiled-debug-fun-arguments cdebug-fun
)
1897 (return-from parse-compiled-debug-vars nil
))
1898 (when (zerop (compact-vector-length packed-vars
))
1899 ;; Return a simple-vector not whatever packed-vars may be.
1900 (return-from parse-compiled-debug-vars
'#()))
1903 (len (length packed-vars
))
1904 (buffer (make-array 0 :fill-pointer
0 :adjustable t
))
1907 ;; The routines in the "SB-C" package are macros that advance the
1909 (let* ((flags (prog1 (aref packed-vars i
) (incf i
)))
1910 (minimal (logtest sb-c
::compiled-debug-var-minimal-p flags
))
1911 (deleted (logtest sb-c
::compiled-debug-var-deleted-p flags
))
1912 (name (cond (minimal "")
1913 ((logtest sb-c
::compiled-debug-var-same-name-p flags
)
1915 (t (sb-c::read-var-string packed-vars i
))))
1917 (minimal default-package
)
1918 ((logtest sb-c
::compiled-debug-var-packaged
1920 (find-package (sb-c::read-var-string packed-vars i
)))
1921 ((logtest sb-c
::compiled-debug-var-uninterned
1927 (if deleted
0 (sb-c::read-var-integerf packed-vars i
)))
1929 (if (logtest sb-c
::compiled-debug-var-save-loc-p flags
)
1930 (sb-c::read-var-integerf packed-vars i
)
1933 (if (logtest sb-c
::compiled-debug-var-indirect-p flags
)
1934 (sb-c::read-var-integerf packed-vars i
)
1936 (aver (not (and args-minimal
(not minimal
))))
1937 (cond ((and prev-name
(string= prev-name name
))
1943 (make-compiled-debug-var
1945 (logtest sb-c
::compiled-debug-var-environment-live flags
)
1946 sc
+offset save-sc
+offset
1949 (when (>= i len
) (return)))
1950 (let ((result (coerce buffer
'simple-vector
)))
1952 (assign-minimal-var-names result
))
1955 ;;; The argument is a debug internals structure. This returns NIL if
1956 ;;; there is no variable information. It returns an empty
1957 ;;; simple-vector if there were no locals in the function. Otherwise
1958 ;;; it returns a SIMPLE-VECTOR of DEBUG-VARs.
1959 (defun debug-fun-debug-vars (debug-fun)
1960 (let ((vars (debug-fun-%debug-vars debug-fun
)))
1961 (if (eq vars
:unparsed
)
1962 (let* ((new (etypecase debug-fun
1964 (parse-compiled-debug-vars debug-fun
))
1965 (bogus-debug-fun nil
)))
1966 (old (cas (debug-fun-%debug-vars debug-fun
) :unparsed new
)))
1967 (if (eq old
:unparsed
) new old
))
1970 ;;; COMPILED-DEBUG-FUN-LAMBDA-LIST calls this when a
1971 ;;; COMPILED-DEBUG-FUN has no lambda list information cached. It
1972 ;;; returns the lambda list as the first value and whether there was
1973 ;;; any argument information as the second value. Therefore,
1974 ;;; (VALUES NIL T) means there were no arguments, but (VALUES NIL NIL)
1975 ;;; means there was no argument information.
1976 (defun parse-compiled-debug-fun-lambda-list (debug-fun)
1977 ;; This file could not be slammed if COERCE is inlined because it thinks :UNPARSED
1978 ;; (i.e. not a sequence) can be returned as the DEBUG-VARS. But it can't, and a running
1979 ;; image was able to recompile the function with no decl and no warning. What's up with that?
1980 (let ((args (sb-c::compiled-debug-fun-arguments
1981 (compiled-debug-fun-compiler-debug-fun debug-fun
))))
1986 (values (ensure-heap-list (coerce (debug-fun-debug-vars debug-fun
) 'list
))
1989 (values (parse-compiled-debug-fun-lambda-list/args-available
1990 (debug-fun-debug-vars debug-fun
) args
)
1993 ;;;; unpacking packed debug functions
1995 ;;; sleazoid "macro" to keep our indentation sane in UNCOMPACT-FUN-MAP
1996 (defmacro make-uncompacted-debug-fun
()
1997 '(sb-c::make-compiled-debug-fun
1998 :name
(if (logtest flags sb-c
::packed-debug-fun-previous-name
)
2002 (sb-c::compiled-debug-info-contexts info
)
2003 (sb-c::read-var-integerf map i
))))
2004 :kind
(svref sb-c
::packed-debug-fun-kinds
2005 (ldb sb-c
::packed-debug-fun-kind-byte options
))
2008 (let ((len (sb-c::read-var-integerf map i
)))
2009 (prog1 (subseq map i
(+ i len
))
2013 (let* ((len (sb-c::read-var-integerf map i
))
2015 (prog1 (subseq map i
(+ i len
))
2019 (when (logtest sb-c
::packed-debug-fun-tlf-number-bit flags
)
2020 (sb-c::read-var-integerf map i
))
2023 (if (logtest sb-c
::packed-debug-fun-non-minimal-arguments-bit flags
)
2024 (let ((len (sb-c::read-var-integerf map i
))
2025 (buffer (make-array 0 :fill-pointer
0 :adjustable t
)))
2027 (let ((arg (sb-c::read-var-integerf map i
)))
2029 (#.sb-c
::packed-debug-fun-arg-deleted
2030 (vector-push-extend 'sb-c
::deleted buffer
))
2031 (#.sb-c
::packed-debug-fun-arg-supplied-p
2032 (vector-push-extend 'sb-c
::supplied-p buffer
))
2033 (#.sb-c
::packed-debug-fun-arg-optional
2034 (vector-push-extend 'sb-c
::optional buffer
))
2035 (#.sb-c
::packed-debug-fun-arg-rest
2036 (vector-push-extend 'sb-c
::rest buffer
))
2037 (#.sb-c
::packed-debug-fun-arg-more
2038 (vector-push-extend 'sb-c
::more buffer
))
2039 (#.sb-c
::packed-debug-fun-key-arg-keyword
2040 (vector-push-extend (intern (sb-c::read-var-string map i
)
2043 (#.sb-c
::packed-debug-fun-key-arg-packaged
2044 (without-package-locks
2045 (vector-push-extend (intern (sb-c::read-var-string map i
)
2046 (sb-c::read-var-string map i
))
2048 (#.sb-c
::packed-debug-fun-key-arg-uninterned
2049 (vector-push-extend (make-symbol (sb-c::read-var-string map i
))
2052 (vector-push-extend (- arg sb-c
::packed-debug-fun-arg-index-offset
)
2054 (coerce buffer
'simple-vector
))
2057 (ecase (ldb sb-c
::packed-debug-fun-returns-byte options
)
2058 (#.sb-c
::packed-debug-fun-returns-standard
2060 (#.sb-c
::packed-debug-fun-returns-fixed
2062 (#.sb-c
::packed-debug-fun-returns-specified
2063 (let ((buffer (make-array 0 :fill-pointer
0 :adjustable t
)))
2064 (dotimes (idx (sb-c::read-var-integerf map i
))
2065 (vector-push-extend (sb-c::read-var-integerf map i
) buffer
))
2066 (coerce buffer
'simple-vector
))))
2067 #-fp-and-pc-standard-save
:return-pc
2068 #-fp-and-pc-standard-save
(sb-c::read-var-integerf map i
)
2069 #-fp-and-pc-standard-save
:return-pc-pass
2070 #-fp-and-pc-standard-save
(sb-c::read-var-integerf map i
)
2071 #-fp-and-pc-standard-save
:old-fp
2072 #-fp-and-pc-standard-save
(sb-c::read-var-integerf map i
)
2073 #-fp-and-pc-standard-save
:lra-saved-pc
2074 #-fp-and-pc-standard-save
(sb-c::read-var-integerf map i
)
2075 #-fp-and-pc-standard-save
:cfp-saved-pc
2076 #-fp-and-pc-standard-save
(sb-c::read-var-integerf map i
)
2078 (when (logtest flags sb-c
::packed-debug-fun-closure-save-loc-bit
)
2079 (sb-c::read-var-integerf map i
))
2080 #+unwind-to-frame-and-call-vop
:bsp-save
2081 #+unwind-to-frame-and-call-vop
2082 (when (logtest flags sb-c
::packed-debug-fun-bsp-save-loc-bit
)
2083 (sb-c::read-var-integerf map i
))
2086 (setq code-start-pc
(+ code-start-pc
(sb-c::read-var-integerf map i
)))
2087 (+ code-start-pc
(sb-c::read-var-integerf map i
)))
2089 (setq elsewhere-pc
(+ elsewhere-pc
(sb-c::read-var-integerf map i
)))))
2091 ;;; Return a normal function map derived from a packed debug info
2092 ;;; function map. This involves looping parsing PACKED-DEBUG-FUNs and
2093 ;;; then building a vector out of them.
2094 (defun uncompact-fun-map (info)
2095 (declare (type sb-c
::compiled-debug-info info
))
2096 (let* ((map (sb-c::decompress
(sb-c::compiled-debug-info-fun-map info
)))
2101 (name (sb-c::compiled-debug-info-name info
)))
2104 (when (= i len
) (return))
2105 (let* ((options (prog1 (aref map i
) (incf i
)))
2106 (flags (prog1 (aref map i
) (incf i
)))
2107 (vars-p (logtest flags
2108 sb-c
::packed-debug-fun-variables-bit
))
2109 (blocks-p (logtest flags
2110 sb-c
::packed-debug-fun-blocks-bit
))
2111 (dfun (make-uncompacted-debug-fun)))
2115 (coerce (cdr (res)) 'simple-vector
))))
2117 ;;; a map from packed DEBUG-INFO function maps to unpacked
2118 ;;; versions thereof
2119 (define-load-time-global *uncompacted-fun-maps
* nil
)
2121 ;;; Return a FUN-MAP for a given COMPILED-DEBUG-INFO object. If the
2122 ;;; info is packed, and has not been parsed, then parse it.
2123 (defun get-debug-info-fun-map (info)
2124 (declare (type sb-c
::compiled-debug-info info
))
2125 (with-weak-cache (ht *uncompacted-fun-maps
*)
2126 (or (gethash info ht
)
2127 (setf (gethash info ht
) (uncompact-fun-map info
)))))
2131 ;;; If we're sure of whether code-location is known, return T or NIL.
2132 ;;; If we're :UNSURE, then try to fill in the code-location's slots.
2133 ;;; This determines whether there is any debug-block information, and
2134 ;;; if code-location is known.
2136 ;;; ??? IF this conses closures every time it's called, then break off the
2137 ;;; :UNSURE part to get the HANDLER-CASE into another function.
2138 (defun code-location-unknown-p (basic-code-location)
2139 (ecase (code-location-%unknown-p basic-code-location
)
2143 (setf (code-location-%unknown-p basic-code-location
)
2144 (handler-case (not (fill-in-code-location basic-code-location
))
2145 (no-debug-blocks () t
))))))
2147 ;;; Return the DEBUG-BLOCK containing code-location if it is available.
2148 ;;; Some debug policies inhibit debug-block information, and if none
2149 ;;; is available, then this signals a NO-DEBUG-BLOCKS condition.
2150 (defun code-location-debug-block (basic-code-location)
2151 (let ((block (code-location-%debug-block basic-code-location
)))
2152 (if (eq block
:unparsed
)
2153 (etypecase basic-code-location
2154 (compiled-code-location
2155 (compute-compiled-code-location-debug-block basic-code-location
))
2156 ;; (There used to be more cases back before sbcl-0.7.0, when
2157 ;; we did special tricks to debug the IR1 interpreter.)
2161 ;;; Store and return BASIC-CODE-LOCATION's debug-block. We determines
2162 ;;; the correct one using the code-location's pc. We use
2163 ;;; DEBUG-FUN-DEBUG-BLOCKS to return the cached block information
2164 ;;; or signal a NO-DEBUG-BLOCKS condition. The blocks are sorted by
2165 ;;; their first code-location's pc, in ascending order. Therefore, as
2166 ;;; soon as we find a block that starts with a pc greater than
2167 ;;; basic-code-location's pc, we know the previous block contains the
2168 ;;; pc. If we get to the last block, then the code-location is either
2169 ;;; in the second to last block or the last block, and we have to be
2170 ;;; careful in determining this since the last block could be code at
2171 ;;; the end of the function. We have to check for the last block being
2172 ;;; code first in order to see how to compare the code-location's pc.
2173 (defun compute-compiled-code-location-debug-block (basic-code-location)
2174 (let* ((pc (compiled-code-location-pc basic-code-location
))
2175 (debug-fun (code-location-debug-fun
2176 basic-code-location
))
2177 (blocks (debug-fun-debug-blocks debug-fun
))
2178 (len (length blocks
)))
2179 (declare (simple-vector blocks
))
2180 (setf (code-location-%debug-block basic-code-location
)
2186 (let ((last (svref blocks end
)))
2188 ((debug-block-elsewhere-p last
)
2190 (sb-c::compiled-debug-fun-elsewhere-pc
2191 (compiled-debug-fun-compiler-debug-fun
2193 (svref blocks
(1- end
))
2196 (compiled-code-location-pc
2197 (svref (compiled-debug-block-code-locations last
)
2199 (svref blocks
(1- end
)))
2201 (declare (type index i end
))
2203 (compiled-code-location-pc
2204 (svref (compiled-debug-block-code-locations
2207 (return (svref blocks
(1- i
)))))))))
2209 ;;; Return the CODE-LOCATION's DEBUG-SOURCE.
2210 (defun code-location-debug-source (code-location)
2211 (let ((info (compiled-debug-fun-debug-info
2212 (code-location-debug-fun code-location
))))
2213 (or (sb-c::debug-info-source info
)
2214 (debug-signal 'no-debug-blocks
:debug-fun
2215 (code-location-debug-fun code-location
)))))
2217 ;;; Returns the number of top level forms before the one containing
2218 ;;; CODE-LOCATION as seen by the compiler in some compilation unit. (A
2219 ;;; compilation unit is not necessarily a single file, see the section
2220 ;;; on debug-sources.)
2221 (defun code-location-toplevel-form-offset (code-location)
2222 (when (code-location-unknown-p code-location
)
2223 (error 'unknown-code-location
:code-location code-location
))
2224 (let ((tlf-offset (code-location-%tlf-offset code-location
)))
2225 (cond ((eq tlf-offset
:unparsed
)
2226 (etypecase code-location
2227 (compiled-code-location
2228 (unless (fill-in-code-location code-location
)
2229 ;; This check should be unnecessary. We're missing
2230 ;; debug info the compiler should have dumped.
2231 (bug "unknown code location"))
2232 (code-location-%tlf-offset code-location
))
2233 ;; (There used to be more cases back before sbcl-0.7.0,,
2234 ;; when we did special tricks to debug the IR1
2239 ;;; Return the number of the form corresponding to CODE-LOCATION. The
2240 ;;; form number is derived by a walking the subforms of a top level
2241 ;;; form in depth-first order.
2242 (defun code-location-form-number (code-location)
2243 (when (code-location-unknown-p code-location
)
2244 (error 'unknown-code-location
:code-location code-location
))
2245 (let ((form-num (code-location-%form-number code-location
)))
2246 (cond ((eq form-num
:unparsed
)
2247 (etypecase code-location
2248 (compiled-code-location
2249 (unless (fill-in-code-location code-location
)
2250 ;; This check should be unnecessary. We're missing
2251 ;; debug info the compiler should have dumped.
2252 (bug "unknown code location"))
2253 (code-location-%form-number code-location
))
2254 ;; (There used to be more cases back before sbcl-0.7.0,,
2255 ;; when we did special tricks to debug the IR1
2260 ;;; Return the kind of CODE-LOCATION, one of:
2261 ;;; :INTERPRETED, :UNKNOWN-RETURN, :KNOWN-RETURN, :INTERNAL-ERROR,
2262 ;;; :NON-LOCAL-EXIT, :BLOCK-START, :CALL-SITE, :SINGLE-VALUE-RETURN,
2263 ;;; :NON-LOCAL-ENTRY
2264 (defun code-location-kind (code-location)
2265 (when (code-location-unknown-p code-location
)
2266 (error 'unknown-code-location
:code-location code-location
))
2267 (etypecase code-location
2268 (compiled-code-location
2269 (let ((kind (compiled-code-location-kind code-location
)))
2270 (cond ((not (eq kind
:unparsed
)) kind
)
2271 ((not (fill-in-code-location code-location
))
2272 ;; This check should be unnecessary. We're missing
2273 ;; debug info the compiler should have dumped.
2274 (bug "unknown code location"))
2276 (compiled-code-location-kind code-location
)))))
2277 ;; (There used to be more cases back before sbcl-0.7.0,,
2278 ;; when we did special tricks to debug the IR1
2282 ;;; This returns CODE-LOCATION's live-set if it is available. If
2283 ;;; there is no debug-block information, this returns NIL.
2284 (defun compiled-code-location-live-set (code-location)
2285 (if (code-location-unknown-p code-location
)
2287 (let ((live-set (compiled-code-location-%live-set code-location
)))
2288 (fill-in-code-location code-location
)
2289 (cond ((eq live-set
:unparsed
)
2290 (unless (fill-in-code-location code-location
)
2291 ;; This check should be unnecessary. We're missing
2292 ;; debug info the compiler should have dumped.
2294 ;; FIXME: This error and comment happen over and over again.
2295 ;; Make them a shared function.
2296 (bug "unknown code location"))
2297 (compiled-code-location-%live-set code-location
))
2300 (defun code-location-context (code-location)
2301 (unless (code-location-unknown-p code-location
)
2302 (let ((context (compiled-code-location-context code-location
)))
2303 (cond ((eq context
:unparsed
)
2304 (etypecase code-location
2305 (compiled-code-location
2306 (unless (fill-in-code-location code-location
)
2307 (bug "unknown code location"))
2308 (compiled-code-location-context code-location
))))
2311 (defun error-context (&optional
(frame sb-debug
:*stack-top-hint
*))
2313 (code-location-context (frame-code-location frame
))))
2315 (defun decode-arithmetic-error-operands (context)
2316 (let* ((alien-context (sb-alien:sap-alien context
(* os-context-t
)))
2317 (fp (int-sap (context-register alien-context
2318 sb-vm
::cfp-offset
)))
2319 (sb-debug:*stack-top-hint
* (find-interrupted-frame))
2320 (error-context (error-context)))
2322 (values (car error-context
)
2323 (loop for x in
(cdr error-context
)
2324 collect
(if (integerp x
)
2325 (sub-access-debug-var-slot
2329 ;;; true if OBJ1 and OBJ2 are the same place in the code
2330 (defun code-location= (obj1 obj2
)
2332 (compiled-code-location
2334 (compiled-code-location
2335 (and (eq (code-location-debug-fun obj1
)
2336 (code-location-debug-fun obj2
))
2337 (sub-compiled-code-location= obj1 obj2
)))
2338 ;; (There used to be more cases back before sbcl-0.7.0,,
2339 ;; when we did special tricks to debug the IR1
2342 ;; (There used to be more cases back before sbcl-0.7.0,,
2343 ;; when we did special tricks to debug IR1-interpreted code.)
2345 (defun sub-compiled-code-location= (obj1 obj2
)
2346 (= (compiled-code-location-pc obj1
)
2347 (compiled-code-location-pc obj2
)))
2349 ;;; Fill in CODE-LOCATION's :UNPARSED slots, returning T or NIL
2350 ;;; depending on whether the code-location was known in its
2351 ;;; DEBUG-FUN's debug-block information. This may signal a
2352 ;;; NO-DEBUG-BLOCKS condition due to DEBUG-FUN-DEBUG-BLOCKS, and
2353 ;;; it assumes the %UNKNOWN-P slot is already set or going to be set.
2354 (defun fill-in-code-location (code-location)
2355 (declare (type compiled-code-location code-location
))
2356 (let* ((debug-fun (code-location-debug-fun code-location
))
2357 (blocks (debug-fun-debug-blocks debug-fun
))
2359 (declare (simple-vector blocks
))
2360 (dotimes (i (length blocks
) nil
)
2361 (let* ((block (svref blocks i
))
2362 (locations (compiled-debug-block-code-locations block
)))
2363 (declare (simple-vector locations
))
2364 (dotimes (j (length locations
))
2365 (let ((loc (svref locations j
)))
2366 (when (sub-compiled-code-location= code-location loc
)
2369 ;; There may be multiple locations in multiple blocks at a given PC, prefer
2370 ;; the :internal-error ones.
2371 (when (eq (compiled-code-location-kind loc
) :internal-error
)
2375 (setf (code-location-%debug-block code-location
)
2376 (code-location-%debug-block found
))
2377 (setf (code-location-%tlf-offset code-location
)
2378 (code-location-%tlf-offset found
))
2379 (setf (code-location-%form-number code-location
)
2380 (code-location-%form-number found
))
2381 (setf (compiled-code-location-%live-set code-location
)
2382 (compiled-code-location-%live-set found
))
2383 (setf (compiled-code-location-kind code-location
)
2384 (compiled-code-location-kind found
))
2385 (setf (compiled-code-location-step-info code-location
)
2386 (compiled-code-location-step-info found
))
2387 (setf (compiled-code-location-context code-location
)
2388 (compiled-code-location-context found
))
2391 ;;;; operations on DEBUG-BLOCKs
2393 ;;; Execute FORMS in a context with CODE-VAR bound to each
2394 ;;; CODE-LOCATION in DEBUG-BLOCK, and return the value of RESULT.
2395 (defmacro do-debug-block-locations
((code-var debug-block
&optional result
)
2397 (let ((code-locations (gensym))
2399 `(let ((,code-locations
(debug-block-code-locations ,debug-block
)))
2400 (declare (simple-vector ,code-locations
))
2401 (dotimes (,i
(length ,code-locations
) ,result
)
2402 (let ((,code-var
(svref ,code-locations
,i
)))
2405 ;;; Return the name of the function represented by DEBUG-FUN.
2406 ;;; This may be a string or a cons; do not assume it is a symbol.
2407 (defun debug-block-fun-name (debug-block)
2408 (etypecase debug-block
2409 (compiled-debug-block
2410 (let ((code-locs (compiled-debug-block-code-locations debug-block
)))
2411 (declare (simple-vector code-locs
))
2412 (if (zerop (length code-locs
))
2413 "??? Can't get name of debug-block's function."
2415 (code-location-debug-fun (svref code-locs
0))))))
2416 ;; (There used to be more cases back before sbcl-0.7.0, when we
2417 ;; did special tricks to debug the IR1 interpreter.)
2420 (defun debug-block-code-locations (debug-block)
2421 (etypecase debug-block
2422 (compiled-debug-block
2423 (compiled-debug-block-code-locations debug-block
))
2424 ;; (There used to be more cases back before sbcl-0.7.0, when we
2425 ;; did special tricks to debug the IR1 interpreter.)
2428 ;;;; operations on debug variables
2430 ;;; Return the symbol from interning DEBUG-VAR-NAME in the package DEBUG-VAR-PACKAGE.
2431 (defun debug-var-symbol (debug-var)
2432 (let ((package (debug-var-package debug-var
)))
2434 (without-package-locks
2435 (intern (debug-var-name debug-var
) package
))
2436 (make-symbol (debug-var-name debug-var
)))))
2438 ;;; Return the value stored for DEBUG-VAR in frame, or if the value is
2439 ;;; not :VALID, then signal an INVALID-VALUE error.
2440 (defun debug-var-valid-value (debug-var frame
)
2441 (unless (eq (debug-var-validity debug-var
(frame-code-location frame
))
2443 (error 'invalid-value
:debug-var debug-var
:frame frame
))
2444 (debug-var-value debug-var frame
))
2446 ;;; Returns the value stored for DEBUG-VAR in frame. The value may be
2447 ;;; invalid. This is SETFable.
2448 (defun debug-var-value (debug-var frame
)
2449 (aver (typep frame
'compiled-frame
))
2450 (let ((res (access-compiled-debug-var-slot debug-var frame
)))
2451 (if (indirect-value-cell-p res
)
2452 (value-cell-ref res
)
2455 ;;; This returns what is stored for the variable represented by
2456 ;;; DEBUG-VAR relative to the FRAME. This may be an indirect value
2457 ;;; cell if the variable is both closed over and set.
2458 (defun access-compiled-debug-var-slot (debug-var frame
)
2459 (let ((escaped (compiled-frame-escaped frame
)))
2460 (cond ((compiled-debug-var-indirect-sc+offset debug-var
)
2461 (sub-access-debug-var-slot
2462 ;; Indirect are accessed through a frame pointer of the parent.
2464 (sub-access-debug-var-slot
2465 (frame-pointer frame
)
2467 (compiled-debug-var-sc+offset debug-var
)
2469 (compiled-debug-var-save-sc+offset debug-var
)
2470 (compiled-debug-var-sc+offset debug-var
)))
2472 (compiled-debug-var-indirect-sc+offset debug-var
)
2475 (sub-access-debug-var-slot
2476 (frame-pointer frame
)
2477 (compiled-debug-var-sc+offset debug-var
)
2480 (sub-access-debug-var-slot
2481 (frame-pointer frame
)
2482 (or (compiled-debug-var-save-sc+offset debug-var
)
2483 (compiled-debug-var-sc+offset debug-var
)))))))
2485 ;;; a helper function for working with possibly-invalid values:
2486 ;;; Do (%MAKE-LISP-OBJ VAL) only if the value looks valid.
2488 ;;; (Such values can arise in registers on machines with conservative
2489 ;;; GC, and might also arise in debug variable locations when
2490 ;;; those variables are invalid.)
2492 ;;; NOTE for precisely GC'd platforms:
2493 ;;; this function is not GC-safe in the slightest when creating
2494 ;;; a pointer to an object in dynamic space. If a GC occurs between
2495 ;;; the start of the call to VALID-TAGGED-POINTER-P and the end of
2496 ;;; %MAKE-LISP-OBJ then the object could move before the boxed pointer
2497 ;;; is constructed. This can happen on CHENEYGC if an asynchronous
2498 ;;; interrupt occurs within the window. This can happen on GENCGC
2499 ;;; under the same circumstances, but is more likely due to all GENCGC
2500 ;;; platforms supporting threaded operation.
2502 ;;; On x86oids we are able to eliminate the vulnerable window
2503 ;;; by conservatively pinning an object (i.e. storing a bit pattern
2504 ;;; that would be the address of an object, assuming it is an object)
2505 ;;; whether or not there is actually an object to pin.
2506 ;;; To see the GC-safeness problem without WITH-PINNED-OBJECTS, consider
2507 ;;; the following sequence of events, and suppose for the sake of argument
2508 ;;; that tagged pointer #x104003 is valid at the moment of call.
2509 ;;; Assume 1 low zero bit in a fixnum, so the register contains #x208006.
2510 ;;; 1. move-to-word: arg-passing-reg <- #x104003 ; implicit pin
2511 ;;; /* at this point the fixnum whose representation is #x208006
2512 ;;; was spilled to stack prior to call, *and* the descriptor bits
2513 ;;; are also in a register. The fixnum pins nothing as it does not
2514 ;;; have Lisp pointer nature. The passing reg pins something */
2515 ;;; 2. call C : will return true, and assume that the arg-passing-reg
2516 ;;; gets clobbered. The return-reg contains 1 for true.
2517 ;;; 3. -- GC triggered by other thread
2518 ;;; transport the object that was #x104003 to somewhere new
2519 ;;; 4. now %MAKE-LISP-OBJ creates a bogus pointer.
2520 ;;; By preemptively using (WITH-PINNED-OBJECTS ((%MAKE-LISP-OBJ)))
2521 ;;; we ensure that the bit pattern #x104003 is on the stack for root scan.
2522 ;;; Unfortunately, WITH-PINNED-OBJECTS can not be used with precise GC
2523 ;;; because random trash is not allowed in a descriptor register.
2524 ;;; If we really wanted to make this safe for precise GC, we could use a
2525 ;;; new special binding, something like *PINNED-WORDS* which would be a list
2526 ;;; of INTEGERs, each of which, _if_ its bit pattern is that of an object
2527 ;;; descriptor, would pin the corresponding object. On the lisp side
2528 ;;; the cons cell in the list would hold the supplied VAL directly.
2529 (defun make-lisp-obj (val &optional
(errorp t
))
2532 (zerop (logand val fixnum-tag-mask
))
2533 ;; immediate single float, 64-bit only
2535 (= (logand val
#xff
) single-float-widetag
)
2537 (and (zerop (logandc2 val
#x1fffffff
)) ; Top bits zero
2538 (= (logand val
#xff
) character-widetag
)) ; char tag
2540 (= val unbound-marker-widetag
))
2541 (values (%make-lisp-obj val
) t
)
2542 ;; To mitigate the danger of GC running in between testing pointer
2543 ;; validity and returning the object, we must pin a potentially
2544 ;; non-object which is harmless on the conservative backends
2545 ;; but harmful on precise GC.
2546 (macrolet ((possibly-pin (form)
2548 `(with-pinned-objects ((%make-lisp-obj val
)) ,form
)
2549 #-
(or x86 x86-64
) form
))
2550 (let ((obj (if (and (typep val
'word
) (is-lisp-pointer val
))
2552 (if (= (valid-tagged-pointer-p (int-sap val
)) 0)
2554 (%make-lisp-obj val
)))
2556 (cond ((not (eql obj
0)) (values obj t
))
2558 (error "~S is not a valid argument to ~S"
2559 val
'make-lisp-obj
))
2561 (values (make-unprintable-object
2562 (format nil
"invalid object #x~X" val
))
2565 (defun sub-access-debug-var-slot (fp sc
+offset
&optional escaped
)
2566 ;; NOTE: The long-float support in here is obviously decayed. When
2567 ;; the x86oid and non-x86oid versions of this function were unified,
2568 ;; the behavior of long-floats was preserved, which only served to
2569 ;; highlight its brokenness.
2570 (macrolet ((with-escaped-value ((var) &body forms
)
2572 (let ((,var
(context-register escaped
2573 (sb-c:sc
+offset-offset sc
+offset
))))
2575 :invalid-value-for-unescaped-register-storage
))
2576 (escaped-boxed-value ()
2578 (boxed-context-register
2580 (sb-c:sc
+offset-offset sc
+offset
))
2581 :invalid-value-for-unescaped-register-storage
))
2582 (escaped-float-value (format)
2584 (context-float-register escaped
2585 (sb-c:sc
+offset-offset sc
+offset
) ',format
)
2586 :invalid-value-for-unescaped-register-storage
))
2587 (with-nfp ((var) &body body
)
2588 ;; x86oids have no separate number stack, so dummy it
2590 #+c-stack-is-control-stack
2593 #-c-stack-is-control-stack
2594 `(let ((,var
(if escaped
2596 (context-register escaped sb-vm
::nfp-offset
))
2597 (sap-ref-sap fp
(* nfp-save-offset n-word-bytes
)))))
2599 (number-stack-offset (&optional
(offset 0))
2601 `(+ (sb-vm::frame-byte-offset
(sb-c:sc
+offset-offset sc
+offset
))
2604 `(+ (* (sb-c:sc
+offset-offset sc
+offset
) n-word-bytes
)
2606 (ecase (sb-c:sc
+offset-scn sc
+offset
)
2607 ((#.any-reg-sc-number
2608 #.descriptor-reg-sc-number
)
2609 (escaped-boxed-value))
2610 (#.character-reg-sc-number
2611 (with-escaped-value (val)
2613 (#.sap-reg-sc-number
2614 (with-escaped-value (val)
2616 (#.signed-reg-sc-number
2617 (with-escaped-value (val)
2618 (if (logbitp (1- n-word-bits
) val
)
2619 (logior val
(ash -
1 n-word-bits
))
2621 (#.unsigned-reg-sc-number
2622 (with-escaped-value (val)
2625 (#.non-descriptor-reg-sc-number
2626 (error "Local non-descriptor register access?"))
2627 #-
(or x86 x86-64 arm64
)
2628 (#.interior-reg-sc-number
2629 (error "Local interior register access?"))
2631 ((#.sb-vm
::sse-reg-sc-number
#.sb-vm
::int-sse-reg-sc-number
)
2632 (escaped-float-value simd-pack-int
))
2634 ((#.sb-vm
::single-sse-reg-sc-number
)
2635 (escaped-float-value simd-pack-single
))
2637 ((#.sb-vm
::double-sse-reg-sc-number
)
2638 (escaped-float-value simd-pack-double
))
2640 ((#.sb-vm
::int-sse-stack-sc-number
)
2642 (%make-simd-pack-ub64
2643 (sap-ref-64 nfp
(number-stack-offset 0))
2644 (sap-ref-64 nfp
(number-stack-offset 8)))))
2646 ((#.sb-vm
::single-sse-stack-sc-number
)
2648 (%make-simd-pack-single
2649 (sap-ref-single nfp
(number-stack-offset 0))
2650 (sap-ref-single nfp
(number-stack-offset 4))
2651 (sap-ref-single nfp
(number-stack-offset 8))
2652 (sap-ref-single nfp
(number-stack-offset 12)))))
2654 ((#.sb-vm
::double-sse-stack-sc-number
)
2656 (%make-simd-pack-double
2657 (sap-ref-double nfp
(number-stack-offset 0))
2658 (sap-ref-double nfp
(number-stack-offset 8)))))
2660 ((#.sb-vm
::ymm-reg-sc-number
#.sb-vm
::int-avx2-reg-sc-number
)
2661 (escaped-float-value simd-pack-256-int
))
2663 ((#.sb-vm
::single-avx2-reg-sc-number
)
2664 (escaped-float-value simd-pack-256-single
))
2666 ((#.sb-vm
::double-avx2-reg-sc-number
)
2667 (escaped-float-value simd-pack-256-double
))
2669 ((#.sb-vm
::int-avx2-stack-sc-number
)
2671 (%make-simd-pack-256-ub64
2672 (sap-ref-64 nfp
(number-stack-offset 0))
2673 (sap-ref-64 nfp
(number-stack-offset 8))
2674 (sap-ref-64 nfp
(number-stack-offset 16))
2675 (sap-ref-64 nfp
(number-stack-offset 24)))))
2677 ((#.sb-vm
::single-avx2-stack-sc-number
)
2679 (%make-simd-pack-256-single
2680 (sap-ref-single nfp
(number-stack-offset 0))
2681 (sap-ref-single nfp
(number-stack-offset 4))
2682 (sap-ref-single nfp
(number-stack-offset 8))
2683 (sap-ref-single nfp
(number-stack-offset 12))
2684 (sap-ref-single nfp
(number-stack-offset 16))
2685 (sap-ref-single nfp
(number-stack-offset 20))
2686 (sap-ref-single nfp
(number-stack-offset 24))
2687 (sap-ref-single nfp
(number-stack-offset 28)))))
2689 ((#.sb-vm
::double-avx2-stack-sc-number
)
2691 (%make-simd-pack-256-double
2692 (sap-ref-double nfp
(number-stack-offset 0))
2693 (sap-ref-double nfp
(number-stack-offset 8))
2694 (sap-ref-double nfp
(number-stack-offset 16))
2695 (sap-ref-double nfp
(number-stack-offset 24)))))
2696 (#.single-reg-sc-number
2697 (escaped-float-value single-float
))
2698 (#.double-reg-sc-number
2699 (escaped-float-value double-float
))
2701 (#.long-reg-sc-number
2702 (escaped-float-value long-float
))
2703 (#.complex-single-reg-sc-number
2704 (escaped-float-value complex-single-float
))
2705 (#.complex-double-reg-sc-number
2706 (escaped-float-value complex-double-float
))
2708 (#.complex-long-reg-sc-number
2709 (escaped-float-value sb-kernel
::complex-long-float
))
2710 (#.single-stack-sc-number
2712 (sap-ref-single nfp
(number-stack-offset))))
2713 (#.double-stack-sc-number
2715 (sap-ref-double nfp
(number-stack-offset))))
2717 (#.long-stack-sc-number
2719 (sap-ref-long nfp
(number-stack-offset))))
2720 (#.complex-single-stack-sc-number
2723 (sap-ref-single nfp
(number-stack-offset))
2724 (sap-ref-single nfp
(number-stack-offset 4)))))
2725 (#.complex-double-stack-sc-number
2728 (sap-ref-double nfp
(number-stack-offset))
2729 (sap-ref-double nfp
(number-stack-offset 8)))))
2731 (#.complex-long-stack-sc-number
2734 (sap-ref-long nfp
(number-stack-offset))
2736 (number-stack-offset #+sparc
4
2737 #+(or x86 x86-64
) 3)))))
2738 (#.control-stack-sc-number
2739 (stack-ref fp
(sb-c:sc
+offset-offset sc
+offset
)))
2740 (#.character-stack-sc-number
2742 (code-char (sap-ref-word nfp
(number-stack-offset)))))
2743 (#.unsigned-stack-sc-number
2745 (sap-ref-word nfp
(number-stack-offset))))
2746 (#.signed-stack-sc-number
2748 (signed-sap-ref-word nfp
(number-stack-offset))))
2749 (#.sap-stack-sc-number
2751 (sap-ref-sap nfp
(number-stack-offset))))
2752 (#.constant-sc-number
2754 (let ((code (code-header-from-pc (context-pc escaped
))))
2756 (code-header-ref code
(sb-c:sc
+offset-offset sc
+offset
))
2757 :invalid-code-object-at-pc
))
2758 :invalid-value-for-unescaped-register-storage
))
2759 (#.immediate-sc-number
2760 (sb-c:sc
+offset-offset sc
+offset
)))))
2762 ;;; This stores value as the value of DEBUG-VAR in FRAME. In the
2763 ;;; COMPILED-DEBUG-VAR case, access the current value to determine if
2764 ;;; it is an indirect value cell. This occurs when the variable is
2765 ;;; both closed over and set.
2766 (defun (setf debug-var-value
) (new-value debug-var frame
)
2767 (aver (typep frame
'compiled-frame
))
2768 (let ((old-value (access-compiled-debug-var-slot debug-var frame
)))
2769 (if (indirect-value-cell-p old-value
)
2770 (value-cell-set old-value new-value
)
2771 (set-compiled-debug-var-slot debug-var frame new-value
)))
2774 ;;; This stores VALUE for the variable represented by debug-var
2775 ;;; relative to the frame. This assumes the location directly contains
2776 ;;; the variable's value; that is, there is no indirect value cell
2777 ;;; currently there in case the variable is both closed over and set.
2778 (defun set-compiled-debug-var-slot (debug-var frame value
)
2779 (let ((escaped (compiled-frame-escaped frame
)))
2781 (sub-set-debug-var-slot (frame-pointer frame
)
2782 (compiled-debug-var-sc+offset debug-var
)
2784 (sub-set-debug-var-slot
2785 (frame-pointer frame
)
2786 (or (compiled-debug-var-save-sc+offset debug-var
)
2787 (compiled-debug-var-sc+offset debug-var
))
2790 (defun sub-set-debug-var-slot (fp sc
+offset value
&optional escaped
)
2791 ;; Like sub-access-debug-var-slot, this is the unification of two
2792 ;; divergent copy-pasted functions. The astute reviewer will notice
2793 ;; that long-floats are messed up here as well, that x86oids
2794 ;; apparently don't support accessing float values that are in
2795 ;; registers, and that non-x86oids store the real part of a float
2796 ;; for both the real and imaginary parts of a complex on the stack
2797 ;; (but not in registers, oddly enough). Some research has
2798 ;; indicated that the different forms of THE used for validating the
2799 ;; type of complex float components between x86oid and non-x86oid
2800 ;; systems are only significant in the case of using a non-complex
2801 ;; number as input (as the non-x86oid case effectively converts
2802 ;; non-complex numbers to complex ones and the x86oid case will
2803 ;; error out). That said, the error message from entering a value
2804 ;; of the wrong type will be slightly easier to understand on x86oid
2806 (macrolet ((set-escaped-value (val)
2808 (setf (context-register escaped
2809 (sb-c:sc
+offset-offset sc
+offset
))
2812 (set-escaped-boxed-value (val)
2814 (setf (boxed-context-register
2816 (sb-c:sc
+offset-offset sc
+offset
))
2819 (set-escaped-float-value (format val
)
2821 (setf (context-float-register escaped
2822 (sb-c:sc
+offset-offset sc
+offset
)
2826 (with-nfp ((var) &body body
)
2827 ;; x86oids have no separate number stack, so dummy it
2829 #+c-stack-is-control-stack
2832 #-c-stack-is-control-stack
2833 `(let ((,var
(if escaped
2834 (int-sap (context-register escaped sb-vm
::nfp-offset
))
2835 (sap-ref-sap fp
(* nfp-save-offset n-word-bytes
)))))
2837 (number-stack-offset (&optional
(offset 0))
2839 `(+ (sb-vm::frame-byte-offset
(sb-c:sc
+offset-offset sc
+offset
))
2842 `(+ (* (sb-c:sc
+offset-offset sc
+offset
) n-word-bytes
)
2844 (ecase (sb-c:sc
+offset-scn sc
+offset
)
2845 ((#.any-reg-sc-number
2846 #.descriptor-reg-sc-number
)
2847 (set-escaped-boxed-value value
))
2848 (#.character-reg-sc-number
2849 (set-escaped-value (char-code value
)))
2850 (#.sap-reg-sc-number
2851 (set-escaped-value (sap-int value
)))
2852 (#.signed-reg-sc-number
2853 (set-escaped-value (logand value most-positive-word
)))
2854 (#.unsigned-reg-sc-number
2855 (set-escaped-value value
))
2857 (#.non-descriptor-reg-sc-number
2858 (error "Local non-descriptor register access?"))
2859 #-
(or x86 x86-64 arm64
)
2860 (#.interior-reg-sc-number
2861 (error "Local interior register access?"))
2863 ((#.sb-vm
::sse-reg-sc-number
#.sb-vm
::int-sse-reg-sc-number
)
2864 (set-escaped-float-value simd-pack-int value
))
2866 ((#.sb-vm
::single-sse-reg-sc-number
)
2867 (set-escaped-float-value simd-pack-single value
))
2869 ((#.sb-vm
::double-sse-reg-sc-number
)
2870 (set-escaped-float-value simd-pack-double value
))
2872 ((#.sb-vm
::int-sse-stack-sc-number
)
2873 (multiple-value-bind (a b
) (%simd-pack-ub64s value
)
2875 (setf (sap-ref-64 nfp
(number-stack-offset 0)) a
2876 (sap-ref-64 nfp
(number-stack-offset 8)) b
))))
2878 ((#.sb-vm
::single-sse-stack-sc-number
)
2879 (multiple-value-bind (a b c d
) (%simd-pack-singles value
)
2881 (setf (sap-ref-single nfp
(number-stack-offset 0)) a
2882 (sap-ref-single nfp
(number-stack-offset 4)) b
2883 (sap-ref-single nfp
(number-stack-offset 8)) c
2884 (sap-ref-single nfp
(number-stack-offset 12)) d
))))
2886 ((#.sb-vm
::double-sse-stack-sc-number
)
2887 (multiple-value-bind (a b
) (%simd-pack-doubles value
)
2889 (setf (sap-ref-double nfp
(number-stack-offset 0)) a
2890 (sap-ref-double nfp
(number-stack-offset 8)) b
))))
2892 ((#.sb-vm
::ymm-reg-sc-number
#.sb-vm
::int-avx2-reg-sc-number
)
2893 (set-escaped-float-value simd-pack-256-int value
))
2895 ((#.sb-vm
::single-avx2-reg-sc-number
)
2896 (set-escaped-float-value simd-pack-256-single value
))
2898 ((#.sb-vm
::double-avx2-reg-sc-number
)
2899 (set-escaped-float-value simd-pack-256-double value
))
2901 ((#.sb-vm
::int-avx2-stack-sc-number
)
2903 (multiple-value-bind (a b c d
) (%simd-pack-256-ub64s value
)
2904 (setf (sap-ref-64 nfp
(number-stack-offset 0)) a
2905 (sap-ref-64 nfp
(number-stack-offset 8)) b
2906 (sap-ref-64 nfp
(number-stack-offset 16)) c
2907 (sap-ref-64 nfp
(number-stack-offset 24)) d
))))
2909 ((#.sb-vm
::single-avx2-stack-sc-number
)
2910 (multiple-value-bind (a b c d e f g h
) (%simd-pack-256-singles value
)
2912 (setf (sap-ref-single nfp
(number-stack-offset 0)) a
2913 (sap-ref-single nfp
(number-stack-offset 4)) b
2914 (sap-ref-single nfp
(number-stack-offset 8)) c
2915 (sap-ref-single nfp
(number-stack-offset 12)) d
2916 (sap-ref-single nfp
(number-stack-offset 16)) e
2917 (sap-ref-single nfp
(number-stack-offset 20)) f
2918 (sap-ref-single nfp
(number-stack-offset 24)) g
2919 (sap-ref-single nfp
(number-stack-offset 28)) h
))))
2921 ((#.sb-vm
::double-avx2-stack-sc-number
)
2922 (multiple-value-bind (a b c d
) (%simd-pack-256-doubles value
)
2924 (setf (sap-ref-double nfp
(number-stack-offset 0)) a
2925 (sap-ref-double nfp
(number-stack-offset 8)) b
2926 (sap-ref-double nfp
(number-stack-offset 16)) c
2927 (sap-ref-double nfp
(number-stack-offset 24)) d
))))
2928 (#.single-reg-sc-number
2929 #-
(or x86 x86-64
) ;; don't have escaped floats.
2930 (set-escaped-float-value single-float value
))
2931 (#.double-reg-sc-number
2932 (set-escaped-float-value double-float value
))
2934 (#.long-reg-sc-number
2935 (set-escaped-float-value long-float value
))
2936 (#.complex-single-reg-sc-number
2937 (set-escaped-float-value complex-single-float value
))
2938 (#.complex-double-reg-sc-number
2939 (set-escaped-float-value complex-double-float value
))
2941 (#.complex-long-reg-sc-number
2942 (set-escaped-float-value complex-long-float
))
2943 (#.single-stack-sc-number
2945 (setf (sap-ref-single nfp
(number-stack-offset))
2946 (the single-float value
))))
2947 (#.double-stack-sc-number
2949 (setf (sap-ref-double nfp
(number-stack-offset))
2950 (the double-float value
))))
2952 (#.long-stack-sc-number
2954 (setf (sap-ref-long nfp
(number-stack-offset))
2955 (the long-float value
))))
2956 (#.complex-single-stack-sc-number
2958 (setf (sap-ref-single nfp
(number-stack-offset))
2960 (realpart (the (complex single-float
) value
))
2962 (the single-float
(realpart value
)))
2963 (setf (sap-ref-single nfp
(number-stack-offset 4))
2965 (imagpart (the (complex single-float
) value
))
2967 (the single-float
(realpart value
)))))
2968 (#.complex-double-stack-sc-number
2970 (setf (sap-ref-double nfp
(number-stack-offset))
2972 (realpart (the (complex double-float
) value
))
2974 (the double-float
(realpart value
)))
2975 (setf (sap-ref-double nfp
(number-stack-offset 8))
2977 (imagpart (the (complex double-float
) value
))
2979 (the double-float
(realpart value
)))))
2981 (#.complex-long-stack-sc-number
2984 nfp
(number-stack-offset))
2986 (realpart (the (complex long-float
) value
))
2988 (the long-float
(realpart value
)))
2990 nfp
(number-stack-offset #+sparc
4
2991 #+(or x86 x86-64
) 3))
2993 (imagpart (the (complex long-float
) value
))
2995 (the long-float
(realpart value
)))))
2996 (#.control-stack-sc-number
2997 (%set-stack-ref fp
(sb-c:sc
+offset-offset sc
+offset
) value
)
2998 value
) ; I doubt that the return value matters, but who knows ...
2999 (#.character-stack-sc-number
3001 (setf (sap-ref-word nfp
(number-stack-offset 0))
3002 (char-code (the character value
)))))
3003 (#.unsigned-stack-sc-number
3005 (setf (sap-ref-word nfp
(number-stack-offset 0)) (the word value
))))
3006 (#.signed-stack-sc-number
3008 (setf (signed-sap-ref-word nfp
(number-stack-offset))
3009 (the signed-word value
))))
3010 (#.sap-stack-sc-number
3012 (setf (sap-ref-sap nfp
(number-stack-offset))
3013 (the system-area-pointer value
)))))))
3015 ;;; The method for setting and accessing COMPILED-DEBUG-VAR values use
3016 ;;; this to determine if the value stored is the actual value or an
3017 ;;; indirection cell.
3018 (defun indirect-value-cell-p (x)
3019 (and (%other-pointer-p x
)
3020 (eql (%other-pointer-widetag x
) value-cell-widetag
)))
3022 ;;; Return three values reflecting the validity of DEBUG-VAR's value
3023 ;;; at BASIC-CODE-LOCATION:
3024 ;;; :VALID The value is known to be available.
3025 ;;; :INVALID The value is known to be unavailable.
3026 ;;; :UNKNOWN The value's availability is unknown.
3028 ;;; If the variable is always alive, then it is valid. If the
3029 ;;; code-location is unknown, then the variable's validity is
3030 ;;; :unknown. Once we've called CODE-LOCATION-UNKNOWN-P, we know the
3031 ;;; live-set information has been cached in the code-location.
3032 (defun debug-var-validity (debug-var basic-code-location
)
3033 (compiled-debug-var-validity debug-var basic-code-location
))
3035 ;;; This is the method for DEBUG-VAR-VALIDITY for COMPILED-DEBUG-VARs.
3036 ;;; For safety, make sure basic-code-location is what we think.
3037 (defun compiled-debug-var-validity (debug-var basic-code-location
)
3038 (declare (type compiled-code-location basic-code-location
))
3039 (cond ((debug-var-alive-p debug-var
)
3040 (let ((debug-fun (code-location-debug-fun basic-code-location
)))
3041 (if (>= (compiled-code-location-pc basic-code-location
)
3042 (sb-c::compiled-debug-fun-start-pc
3043 (compiled-debug-fun-compiler-debug-fun debug-fun
)))
3046 ((code-location-unknown-p basic-code-location
) :unknown
)
3048 (let ((pos (position debug-var
3049 (debug-fun-debug-vars
3050 (code-location-debug-fun
3051 basic-code-location
)))))
3053 (error 'unknown-debug-var
3054 :debug-var debug-var
3056 (code-location-debug-fun basic-code-location
)))
3057 ;; There must be live-set info since basic-code-location is known.
3058 (if (zerop (sbit (compiled-code-location-live-set
3059 basic-code-location
)
3066 ;;; This code produces and uses what we call source-paths. A
3067 ;;; source-path is a list whose first element is a form number as
3068 ;;; returned by CODE-LOCATION-FORM-NUMBER and whose last element is a
3069 ;;; top level form number as returned by
3070 ;;; CODE-LOCATION-TOPLEVEL-FORM-NUMBER. The elements from the last to
3071 ;;; the first, exclusively, are the numbered subforms into which to
3072 ;;; descend. For example:
3074 ;;; (let ((a (aref x 3)))
3076 ;;; The call to AREF in this example is form number 5. Assuming this
3077 ;;; DEFUN is the 11'th top level form, the source-path for the AREF
3078 ;;; call is as follows:
3080 ;;; Given the DEFUN, 3 gets you the LET, 1 gets you the bindings, 0
3081 ;;; gets the first binding, and 1 gets the AREF form.
3083 ;;; This returns a table mapping form numbers to source-paths. A
3084 ;;; source-path indicates a descent into the TOPLEVEL-FORM form,
3085 ;;; going directly to the subform corressponding to the form number.
3087 ;;; The vector elements are in the same format as the compiler's
3088 ;;; NODE-SOURCE-PATH; that is, the first element is the form number and
3089 ;;; the last is the TOPLEVEL-FORM number.
3091 ;;; This should be synchronized with SB-C::SUB-FIND-SOURCE-PATHS
3092 (defun form-number-translations (form tlf-number
)
3094 (translations (make-array 12 :fill-pointer
0 :adjustable t
)))
3095 (labels ((translate1 (form path
)
3096 (unless (member form seen
)
3098 (vector-push-extend (cons (fill-pointer translations
) path
)
3103 (declare (fixnum pos
))
3106 (when (atom subform
) (return))
3107 (let ((fm (car subform
)))
3109 (setf fm
(comma-expr fm
)))
3111 (translate1 fm
(cons pos path
)))
3113 ;; Don't look into quoted constants.
3116 (setq subform
(cdr subform
))
3117 (when (eq subform trail
) (return)))))
3121 (setq trail
(cdr trail
))))))))
3122 (translate1 form
(list tlf-number
)))
3123 (coerce translations
'simple-vector
)))
3125 ;;; FORM is a top level form, and path is a source-path into it. This
3126 ;;; returns the form indicated by the source-path. Context is the
3127 ;;; number of enclosing forms to return instead of directly returning
3128 ;;; the source-path form. When context is non-zero, the form returned
3129 ;;; contains a marker, #:****HERE****, immediately before the form
3130 ;;; indicated by path.
3131 (defun source-path-context (form path context
)
3132 (declare (type unsigned-byte context
))
3133 ;; Get to the form indicated by path or the enclosing form indicated
3134 ;; by context and path.
3135 (let ((path (reverse (butlast (cdr path
)))))
3136 (dotimes (i (- (length path
) context
))
3137 (let ((index (first path
)))
3138 (unless (and (listp form
) (< index
(length form
)))
3139 (error "Source path no longer exists."))
3140 (setq form
(elt form index
))
3141 (setq path
(rest path
))))
3142 ;; Recursively rebuild the source form resulting from the above
3143 ;; descent, copying the beginning of each subform up to the next
3144 ;; subform we descend into according to path. At the bottom of the
3145 ;; recursion, we return the form indicated by path preceded by our
3146 ;; marker, and this gets spliced into the resulting list structure
3147 ;; on the way back up.
3148 (labels ((frob (form path level
)
3149 (if (or (zerop level
) (null path
))
3152 `(#:***here
*** ,form
))
3153 (let ((n (first path
)))
3154 (unless (and (listp form
) (< n
(length form
)))
3155 (error "Source path no longer exists."))
3156 (let ((res (frob (elt form n
) (rest path
) (1- level
))))
3157 (nconc (subseq form
0 n
)
3158 (cons res
(nthcdr (1+ n
) form
))))))))
3159 (frob form path context
))))
3161 ;;; Given a code location, return the associated form-number
3162 ;;; translations and the actual top level form.
3163 ;;; Note that functions compiled to memory (via COMPILE or implicitly
3164 ;;; via LOAD if *EVALUATOR-MODE* = :COMPILE) do not save their source form
3165 ;;; in the DEBUG-SOURCE corresponding to their code-component. Instead the
3166 ;;; form hangs off the %SIMPLE-FUN-INFO slot, so that we can get an accurate
3167 ;;; depiction of the source form for any lambda no matter where from.
3168 (defun get-toplevel-form (location)
3169 (let ((d-source (code-location-debug-source location
)))
3170 (let* ((offset (code-location-toplevel-form-offset location
))
3172 (cond ((and (core-debug-source-p d-source
)
3173 (core-debug-source-form d-source
)))
3174 ((debug-source-namestring d-source
)
3175 (get-file-toplevel-form location
))
3176 (t (bug "Don't know how to use a DEBUG-SOURCE without ~
3177 a namestring or a form.")))))
3178 (values (form-number-translations res offset
) res
))))
3180 ;;; To suppress the read-time evaluation #. macro during source read,
3181 ;;; *READTABLE* is modified.
3183 ;;; FIXME: This breaks #+#.(cl:if ...) Maybe we need a SAFE-READ-EVAL, which
3184 ;;; this code can use for side- effect free #. calls?
3186 ;;; FIXME: This also knows nothing of custom readtables. The assumption
3187 ;;; is that the current readtable is a decent approximation for what
3188 ;;; we want, but that's lossy.
3189 (defun safe-readtable ()
3190 (let ((rt (copy-readtable)))
3191 (set-dispatch-macro-character
3192 #\
# #\.
(lambda (stream sub-char
&rest rest
)
3193 (declare (ignore rest sub-char
))
3194 (let ((token (read stream t nil t
)))
3195 (format nil
"#.~S" token
)))
3199 ;;; Locate the source file (if it still exists) and grab the top level
3200 ;;; form. If the file is modified, or if we are in the middle of
3201 ;;; loading the file (so that the start positions map is not available
3202 ;;; yet), we use the top level form offset instead of the recorded
3203 ;;; character offset.
3204 (defun get-file-toplevel-form (location)
3205 (let* ((d-source (code-location-debug-source location
))
3206 (tlf-offset (code-location-toplevel-form-offset location
))
3207 (start-positions (sb-di:debug-source-start-positions d-source
))
3208 (namestring (debug-source-namestring d-source
))
3209 (sbcl-source-p (eql (search "SYS:" namestring
) 0)))
3210 ;; FIXME: External format?
3211 (with-open-file (f namestring
:if-does-not-exist nil
)
3213 (let ((*readtable
* (safe-readtable)))
3214 (cond ((and (eql (debug-source-created d-source
) (file-write-date f
))
3216 (file-position f
(aref start-positions tlf-offset
)))
3218 (when start-positions
3220 "~%; File has been modified since compilation:~%; ~A"
3223 "~%; Using form offset instead of character position.~%")
3224 (let ((*read-suppress
* t
)
3225 (*features
* (if sbcl-source-p
3228 (symbol-value 'sb-impl
::+internal-features
+))
3230 (loop repeat tlf-offset
3234 ;;;; PREPROCESS-FOR-EVAL
3236 ;;; Return a function of one argument that evaluates form in the
3237 ;;; lexical context of the BASIC-CODE-LOCATION LOC, or signal a
3238 ;;; NO-DEBUG-VARS condition when the LOC's DEBUG-FUN has no
3239 ;;; DEBUG-VAR information available.
3241 ;;; The returned function takes the frame to get values from as its
3242 ;;; argument, and it returns the values of FORM. The returned function
3243 ;;; can signal the following conditions: INVALID-VALUE,
3244 ;;; AMBIGUOUS-VAR-NAME, and FRAME-FUN-MISMATCH.
3245 (defun preprocess-for-eval (form loc
)
3246 (declare (type code-location loc
))
3247 (let ((n-frame (gensym))
3248 (fun (code-location-debug-fun loc
)))
3249 (unless (debug-var-info-available fun
)
3250 (debug-signal 'no-debug-vars
:debug-fun fun
))
3253 (multiple-value-bind (more-context more-count
)
3254 (debug-fun-more-args fun
)
3255 (do-debug-fun-vars (var fun
)
3256 (let ((validity (debug-var-validity var loc
)))
3257 (unless (or (eq validity
:invalid
)
3258 (eq var more-context
)
3259 (eq var more-count
))
3260 (let* ((sym (debug-var-symbol var
))
3261 (found (assoc sym
(binds))))
3264 (setf (second found
) :ambiguous
))
3266 (binds (list sym validity var
))))))))
3267 (when (and more-context more-count
)
3268 (let ((more (assoc 'sb-debug
::more
(binds))))
3270 (setf (second more
) :ambiguous
)
3271 (binds (list 'sb-debug
::more
:more more-context more-count
))))))
3272 (dolist (bind (binds))
3273 (let ((name (first bind
))
3275 (unless (eq (info :variable
:kind name
) :special
)
3276 (ecase (second bind
)
3278 (specs `(,name
(debug-var-value ',var
,n-frame
))))
3280 (let ((count-var (fourth bind
)))
3281 (specs `(,name
(multiple-value-list
3282 (sb-c:%more-arg-values
(debug-var-value ',var
,n-frame
)
3284 (debug-var-value ',count-var
,n-frame
)))))))
3286 (specs `(,name
(debug-signal 'invalid-value
3290 (specs `(,name
(debug-signal 'ambiguous-var-name
3292 :frame
,n-frame
))))))))
3293 ;; Process the symbol macros outside of the function to avoid
3294 ;; all those symbol-macrolets from showing in the sources if
3295 ;; there is a problem evaluating this form
3296 (let ((res (let ((sb-c:*lexenv
* (make-null-lexenv)))
3297 (sb-c::funcall-in-symbol-macrolet-lexenv
3299 (lambda (&optional vars
)
3300 (declare (ignore vars
))
3301 (eval-in-lexenv `(lambda (,n-frame
)
3302 (declare (ignorable ,n-frame
))
3307 ;; This prevents these functions from being used in any
3308 ;; location other than a function return location, so maybe
3309 ;; this should only check whether FRAME's DEBUG-FUN is the
3311 (unless (code-location= (frame-code-location frame
) loc
)
3312 (debug-signal 'frame-fun-mismatch
3313 :code-location loc
:form form
:frame frame
))
3314 (funcall res frame
))))))
3318 (defun eval-in-frame (frame form
)
3319 (declare (type frame frame
))
3320 "Evaluate FORM in the lexical context of FRAME's current code location,
3321 returning the results of the evaluation."
3322 (funcall (preprocess-for-eval form
(frame-code-location frame
)) frame
))
3326 ;;;; user-visible interface
3328 ;;; Create and return a breakpoint. When program execution encounters
3329 ;;; the breakpoint, the system calls HOOK-FUN. HOOK-FUN takes the
3330 ;;; current frame for the function in which the program is running and
3331 ;;; the breakpoint object.
3333 ;;; WHAT and KIND determine where in a function the system invokes
3334 ;;; HOOK-FUN. WHAT is either a code-location or a DEBUG-FUN. KIND is
3335 ;;; one of :CODE-LOCATION, :FUN-START, or :FUN-END. Since the starts
3336 ;;; and ends of functions may not have code-locations representing
3337 ;;; them, designate these places by supplying WHAT as a DEBUG-FUN and
3338 ;;; KIND indicating the :FUN-START or :FUN-END. When WHAT is a
3339 ;;; DEBUG-FUN and kind is :FUN-END, then HOOK-FUN must take two
3340 ;;; additional arguments, a list of values returned by the function
3341 ;;; and a FUN-END-COOKIE.
3343 ;;; INFO is information supplied by and used by the user.
3345 ;;; FUN-END-COOKIE is a function. To implement :FUN-END
3346 ;;; breakpoints, the system uses starter breakpoints to establish the
3347 ;;; :FUN-END breakpoint for each invocation of the function. Upon
3348 ;;; each entry, the system creates a unique cookie to identify the
3349 ;;; invocation, and when the user supplies a function for this
3350 ;;; argument, the system invokes it on the frame and the cookie. The
3351 ;;; system later invokes the :FUN-END breakpoint hook on the same
3352 ;;; cookie. The user may save the cookie for comparison in the hook
3355 ;;; Signal an error if WHAT is an unknown code-location.
3356 (defun make-breakpoint (hook-fun what
3357 &key
(kind :code-location
) info fun-end-cookie
)
3360 (when (code-location-unknown-p what
)
3361 (error "cannot make a breakpoint at an unknown code location: ~S"
3363 (aver (eq kind
:code-location
))
3364 (let ((bpt (%make-breakpoint hook-fun what kind info
)))
3366 (compiled-code-location
3367 ;; This slot is filled in due to calling CODE-LOCATION-UNKNOWN-P.
3368 (when (eq (compiled-code-location-kind what
) :unknown-return
)
3369 (let ((other-bpt (%make-breakpoint hook-fun what
3370 :unknown-return-partner
3372 (setf (breakpoint-unknown-return-partner bpt
) other-bpt
)
3373 (setf (breakpoint-unknown-return-partner other-bpt
) bpt
))))
3374 ;; (There used to be more cases back before sbcl-0.7.0,,
3375 ;; when we did special tricks to debug the IR1
3382 (%make-breakpoint hook-fun what kind info
))
3384 (unless (eq (sb-c::compiled-debug-fun-returns
3385 (compiled-debug-fun-compiler-debug-fun what
))
3387 (error ":FUN-END breakpoints are currently unsupported ~
3388 for the known return convention."))
3390 (let* ((bpt (%make-breakpoint hook-fun what kind info
))
3391 (starter (compiled-debug-fun-end-starter what
)))
3393 (setf starter
(%make-breakpoint
#'list what
:fun-start nil
))
3394 (setf (breakpoint-hook-fun starter
)
3395 (fun-end-starter-hook starter what
))
3396 (setf (compiled-debug-fun-end-starter what
) starter
))
3397 (setf (breakpoint-start-helper bpt
) starter
)
3398 (push bpt
(breakpoint-%info starter
))
3399 (setf (breakpoint-cookie-fun bpt
) fun-end-cookie
)
3402 ;;; These are unique objects created upon entry into a function by a
3403 ;;; :FUN-END breakpoint's starter hook. These are only created
3404 ;;; when users supply :FUN-END-COOKIE to MAKE-BREAKPOINT. Also,
3405 ;;; the :FUN-END breakpoint's hook is called on the same cookie
3406 ;;; when it is created.
3407 (defstruct (fun-end-cookie
3408 (:print-object
(lambda (obj str
)
3409 (print-unreadable-object (obj str
:type t
))))
3410 (:constructor make-fun-end-cookie
(bpt-lra debug-fun
))
3412 ;; a pointer to the bpt-lra created for :FUN-END breakpoints
3413 (bpt-lra nil
:read-only t
)
3414 ;; the DEBUG-FUN associated with this cookie
3415 (debug-fun nil
:read-only t
))
3417 ;;; This returns a hook function for the start helper breakpoint
3418 ;;; associated with a :FUN-END breakpoint. The returned function
3419 ;;; makes a fake LRA that all returns go through, and this piece of
3420 ;;; fake code actually breaks. Upon return from the break, the code
3421 ;;; provides the returnee with any values. Since the returned function
3422 ;;; effectively activates FUN-END-BPT on each entry to DEBUG-FUN's
3423 ;;; function, we must establish breakpoint-data about FUN-END-BPT.
3424 (defun fun-end-starter-hook (starter-bpt debug-fun
)
3425 (declare (type breakpoint starter-bpt
)
3426 (type compiled-debug-fun debug-fun
))
3427 (lambda (frame breakpoint
)
3428 (declare (ignore breakpoint
)
3430 (multiple-value-bind (lra bpt-codeblob offset
)
3431 (make-bpt-lra (frame-saved-lra frame debug-fun
))
3432 (setf (frame-saved-lra frame debug-fun
) lra
)
3433 (let ((end-bpts (breakpoint-%info starter-bpt
)))
3434 (let ((data (breakpoint-data bpt-codeblob offset
)))
3435 (setf (breakpoint-data-breakpoints data
) end-bpts
)
3436 (dolist (bpt end-bpts
)
3437 (setf (breakpoint-internal-data bpt
) data
)))
3438 (let ((cookie (make-fun-end-cookie lra debug-fun
)))
3439 (setf (code-header-ref bpt-codeblob cookie-slot
) cookie
)
3440 (dolist (bpt end-bpts
)
3441 (let ((fun (breakpoint-cookie-fun bpt
)))
3442 (when fun
(funcall fun frame cookie
)))))))))
3444 ;;; This takes a FUN-END-COOKIE and a frame, and it returns
3445 ;;; whether the cookie is still valid. A cookie becomes invalid when
3446 ;;; the frame that established the cookie has exited. Sometimes cookie
3447 ;;; holders are unaware of cookie invalidation because their
3448 ;;; :FUN-END breakpoint hooks didn't run due to THROW'ing.
3450 ;;; This takes a frame as an efficiency hack since the user probably
3451 ;;; has a frame object in hand when using this routine, and it saves
3452 ;;; repeated parsing of the stack and consing when asking whether a
3453 ;;; series of cookies is valid.
3454 (defun fun-end-cookie-valid-p (frame cookie
)
3455 (let ((lra (fun-end-cookie-bpt-lra cookie
)))
3456 (do ((frame frame
(frame-down frame
)))
3458 (when (and (compiled-frame-p frame
)
3459 (#-
(or x86 x86-64
) eq
#+(or x86 x86-64
) sap
=
3461 (frame-saved-lra frame
(frame-debug-fun frame
))))
3464 ;;;; ACTIVATE-BREAKPOINT
3466 ;;; Cause the system to invoke the breakpoint's hook function until
3467 ;;; the next call to DEACTIVATE-BREAKPOINT or DELETE-BREAKPOINT. The
3468 ;;; system invokes breakpoint hook functions in the opposite order
3469 ;;; that you activate them.
3470 (defun activate-breakpoint (breakpoint)
3471 (when (eq (breakpoint-status breakpoint
) :deleted
)
3472 (error "cannot activate a deleted breakpoint: ~S" breakpoint
))
3473 (unless (eq (breakpoint-status breakpoint
) :active
)
3474 (ecase (breakpoint-kind breakpoint
)
3476 (let ((loc (breakpoint-what breakpoint
)))
3478 (compiled-code-location
3479 (activate-compiled-code-location-breakpoint breakpoint
)
3480 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
3482 (activate-compiled-code-location-breakpoint other
))))
3483 ;; (There used to be more cases back before sbcl-0.7.0, when
3484 ;; we did special tricks to debug the IR1 interpreter.)
3487 (etypecase (breakpoint-what breakpoint
)
3489 (activate-compiled-fun-start-breakpoint breakpoint
))
3490 ;; (There used to be more cases back before sbcl-0.7.0, when
3491 ;; we did special tricks to debug the IR1 interpreter.)
3494 (etypecase (breakpoint-what breakpoint
)
3496 (let ((starter (breakpoint-start-helper breakpoint
)))
3497 (unless (eq (breakpoint-status starter
) :active
)
3498 ;; may already be active by some other :FUN-END breakpoint
3499 (activate-compiled-fun-start-breakpoint starter
)))
3500 (setf (breakpoint-status breakpoint
) :active
))
3501 ;; (There used to be more cases back before sbcl-0.7.0, when
3502 ;; we did special tricks to debug the IR1 interpreter.)
3506 (defun activate-compiled-code-location-breakpoint (breakpoint)
3507 (declare (type breakpoint breakpoint
))
3508 (let ((loc (breakpoint-what breakpoint
)))
3509 (declare (type compiled-code-location loc
))
3510 (sub-activate-breakpoint
3512 (breakpoint-data (compiled-debug-fun-component
3513 (code-location-debug-fun loc
))
3514 (+ (compiled-code-location-pc loc
)
3515 (if (or (eq (breakpoint-kind breakpoint
)
3516 :unknown-return-partner
)
3517 (eq (compiled-code-location-kind loc
)
3518 :single-value-return
))
3519 single-value-return-byte-offset
3522 (defun activate-compiled-fun-start-breakpoint (breakpoint)
3523 (declare (type breakpoint breakpoint
))
3524 (let ((debug-fun (breakpoint-what breakpoint
)))
3525 (sub-activate-breakpoint
3527 (breakpoint-data (compiled-debug-fun-component debug-fun
)
3528 (sb-c::compiled-debug-fun-start-pc
3529 (compiled-debug-fun-compiler-debug-fun
3532 (defun sub-activate-breakpoint (breakpoint data
)
3533 (declare (type breakpoint breakpoint
)
3534 (type breakpoint-data data
))
3535 (setf (breakpoint-status breakpoint
) :active
)
3537 (unless (breakpoint-data-breakpoints data
)
3538 (let ((code (breakpoint-data-component data
)))
3539 (with-pinned-objects (code)
3540 (setf (breakpoint-data-instruction data
)
3541 (breakpoint-install (get-lisp-obj-address code
)
3542 (breakpoint-data-offset data
))))))
3543 (setf (breakpoint-data-breakpoints data
)
3544 (append (breakpoint-data-breakpoints data
) (list breakpoint
)))
3545 (setf (breakpoint-internal-data breakpoint
) data
)))
3547 ;;;; DEACTIVATE-BREAKPOINT
3549 ;;; Stop the system from invoking the breakpoint's hook function.
3550 (defun deactivate-breakpoint (breakpoint)
3551 (when (eq (breakpoint-status breakpoint
) :active
)
3553 (let ((loc (breakpoint-what breakpoint
)))
3555 ((or compiled-code-location compiled-debug-fun
)
3556 (deactivate-compiled-breakpoint breakpoint
)
3557 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
3559 (deactivate-compiled-breakpoint other
))))
3560 ;; (There used to be more cases back before sbcl-0.7.0, when
3561 ;; we did special tricks to debug the IR1 interpreter.)
3565 (defun deactivate-compiled-breakpoint (breakpoint)
3566 (if (eq (breakpoint-kind breakpoint
) :fun-end
)
3567 (let ((starter (breakpoint-start-helper breakpoint
)))
3568 (unless (find-if (lambda (bpt)
3569 (and (not (eq bpt breakpoint
))
3570 (eq (breakpoint-status bpt
) :active
)))
3571 (breakpoint-%info starter
))
3572 (deactivate-compiled-breakpoint starter
)))
3573 (let* ((data (breakpoint-internal-data breakpoint
))
3574 (bpts (delete breakpoint
(breakpoint-data-breakpoints data
))))
3575 (setf (breakpoint-internal-data breakpoint
) nil
)
3576 (setf (breakpoint-data-breakpoints data
) bpts
)
3578 (let ((code (breakpoint-data-component data
)))
3579 (with-pinned-objects (code)
3580 (breakpoint-remove (get-lisp-obj-address code
)
3581 (breakpoint-data-offset data
)
3582 (breakpoint-data-instruction data
))))
3583 (delete-breakpoint-data data
))))
3584 (setf (breakpoint-status breakpoint
) :inactive
)
3587 ;;;; BREAKPOINT-INFO
3589 ;;; Return the user-maintained info associated with breakpoint. This
3591 (defun breakpoint-info (breakpoint)
3592 (breakpoint-%info breakpoint
))
3593 (defun (setf breakpoint-info
) (value breakpoint
)
3594 (setf (breakpoint-%info breakpoint
) value
)
3595 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
3597 (setf (breakpoint-%info other
) value
)))
3600 ;;;; BREAKPOINT-ACTIVE-P and DELETE-BREAKPOINT
3602 (defun breakpoint-active-p (breakpoint)
3603 (ecase (breakpoint-status breakpoint
)
3605 ((:inactive
:deleted
) nil
)))
3607 ;;; Free system storage and remove computational overhead associated
3608 ;;; with breakpoint. After calling this, breakpoint is completely
3609 ;;; impotent and can never become active again.
3610 (defun delete-breakpoint (breakpoint)
3611 (let ((status (breakpoint-status breakpoint
)))
3612 (unless (eq status
:deleted
)
3613 (when (eq status
:active
)
3614 (deactivate-breakpoint breakpoint
))
3615 (setf (breakpoint-status breakpoint
) :deleted
)
3616 (let ((other (breakpoint-unknown-return-partner breakpoint
)))
3618 (setf (breakpoint-status other
) :deleted
)))
3619 (when (eq (breakpoint-kind breakpoint
) :fun-end
)
3620 (let* ((starter (breakpoint-start-helper breakpoint
))
3621 (breakpoints (delete breakpoint
3622 (the list
(breakpoint-info starter
)))))
3623 (setf (breakpoint-info starter
) breakpoints
)
3625 (delete-breakpoint starter
)
3626 (setf (compiled-debug-fun-end-starter
3627 (breakpoint-what breakpoint
))
3631 ;;;; C call out stubs
3633 ;;; This actually installs the break instruction in the component. It
3634 ;;; returns the overwritten bits. You must call this in a context in
3635 ;;; which GC is disabled, so that Lisp doesn't move objects around
3636 ;;; that C is pointing to.
3637 (sb-alien:define-alien-routine
"breakpoint_install" sb-alien
:unsigned-int
3638 (code-obj sb-alien
:unsigned
)
3639 (pc-offset sb-alien
:int
))
3641 ;;; This removes the break instruction and replaces the original
3642 ;;; instruction. You must call this in a context in which GC is disabled
3643 ;;; so Lisp doesn't move objects around that C is pointing to.
3644 (sb-alien:define-alien-routine
"breakpoint_remove" sb-alien
:void
3645 (code-obj sb-alien
:unsigned
)
3646 (pc-offset sb-alien
:int
)
3647 (old-inst sb-alien
:unsigned-int
))
3649 (sb-alien:define-alien-routine
"breakpoint_do_displaced_inst" sb-alien
:void
3650 (scp (* os-context-t
))
3651 (orig-inst sb-alien
:unsigned-int
))
3653 ;;;; breakpoint handlers (layer between C and exported interface)
3655 ;;; This maps components to a mapping of offsets to BREAKPOINT-DATAs.
3656 ;;; FIXME: these data should hang off of the component itself.
3657 (define-load-time-global *component-breakpoint-offsets
*
3658 (make-hash-table :test
'eq
:synchronized t
))
3660 ;;; This returns the BREAKPOINT-DATA object associated with component cross
3661 ;;; offset. If none exists, this makes one, installs it, and returns it.
3662 (defun breakpoint-data (component offset
&optional
(create t
))
3664 (flet ((install-breakpoint-data ()
3665 ;; Well, this has at least these three problems if not more:
3666 ;; 1. For the double-checked lock pattern to be correct we have to
3667 ;; re-check whether a key is in the table within the scope of the lock.
3668 ;; 2. The push should probably be a PUSHNEW, but even better, it too
3669 ;; needs to be locked or else dups can occur. Maybe use our newfangled
3670 ;; ordered lockfree linked lists.
3671 ;; 3. The hash-table should probably be weak keyed
3673 (let ((data (make-breakpoint-data component offset
)))
3674 (push (cons offset data
)
3675 (gethash component
*component-breakpoint-offsets
*))
3677 (let ((offsets (gethash component
*component-breakpoint-offsets
*)))
3679 (let ((data (assoc offset offsets
)))
3682 (install-breakpoint-data)))
3683 (install-breakpoint-data)))))
3685 ;;; We use this when there are no longer any active breakpoints
3686 ;;; corresponding to DATA.
3687 (defun delete-breakpoint-data (data)
3688 ;; Again, this looks brittle. Is there no danger of being interrupted
3690 (let* ((component (breakpoint-data-component data
))
3691 (offsets (delete (breakpoint-data-offset data
)
3692 (gethash component
*component-breakpoint-offsets
*)
3695 (setf (gethash component
*component-breakpoint-offsets
*) offsets
)
3696 (remhash component
*component-breakpoint-offsets
*)))
3699 ;;; The C handler for interrupts calls this when it has a
3700 ;;; debugging-tool break instruction. This does *not* handle all
3701 ;;; breaks; for example, it does not handle breaks for internal
3703 (defun handle-breakpoint (offset component signal-context
)
3704 (let ((data (breakpoint-data component offset nil
)))
3706 (error "unknown breakpoint in ~S at offset ~S"
3707 (debug-fun-name (debug-fun-from-pc component offset
))
3709 (let ((breakpoints (breakpoint-data-breakpoints data
)))
3710 (if (or (null breakpoints
)
3711 (eq (breakpoint-kind (car breakpoints
)) :fun-end
))
3712 (handle-fun-end-breakpoint-aux breakpoints data signal-context
)
3713 (handle-breakpoint-aux breakpoints data
3714 offset component signal-context
)))))
3716 ;;; This holds breakpoint-datas while invoking the breakpoint hooks
3717 ;;; associated with that particular component and location. While they
3718 ;;; are executing, if we hit the location again, we ignore the
3719 ;;; breakpoint to avoid infinite recursion. fun-end breakpoints
3720 ;;; must work differently since the breakpoint-data is unique for each
3722 (defvar *executing-breakpoint-hooks
* nil
)
3724 ;;; This handles code-location and DEBUG-FUN :FUN-START
3726 (defun handle-breakpoint-aux (breakpoints data offset component signal-context
)
3728 (bug "breakpoint that nobody wants"))
3729 (unless (member data
*executing-breakpoint-hooks
*)
3730 (let ((*executing-breakpoint-hooks
* (cons data
3731 *executing-breakpoint-hooks
*)))
3732 (invoke-breakpoint-hooks breakpoints signal-context
)))
3733 ;; At this point breakpoints may not hold the same list as
3734 ;; BREAKPOINT-DATA-BREAKPOINTS since invoking hooks may have allowed
3735 ;; a breakpoint deactivation. In fact, if all breakpoints were
3736 ;; deactivated then data is invalid since it was deleted and so the
3737 ;; correct one must be looked up if it is to be used. If there are
3738 ;; no more breakpoints active at this location, then the normal
3739 ;; instruction has been put back, and we do not need to
3740 ;; DO-DISPLACED-INST.
3741 (setf data
(breakpoint-data component offset nil
))
3742 (when (and data
(breakpoint-data-breakpoints data
))
3743 ;; The breakpoint is still active, so we need to execute the
3744 ;; displaced instruction and leave the breakpoint instruction
3745 ;; behind. The best way to do this is different on each machine,
3746 ;; so we just leave it up to the C code.
3747 (breakpoint-do-displaced-inst signal-context
3748 (breakpoint-data-instruction data
))
3749 ;; Some platforms have no usable sigreturn() call. If your
3750 ;; implementation of arch_do_displaced_inst() _does_ sigreturn(),
3751 ;; it's polite to warn here
3752 #+(and sparc solaris
)
3753 (error "BREAKPOINT-DO-DISPLACED-INST returned?")))
3755 (defun invoke-breakpoint-hooks (breakpoints signal-context
)
3756 (let* ((frame (signal-context-frame signal-context
)))
3757 (dolist (bpt breakpoints
)
3758 (funcall (breakpoint-hook-fun bpt
)
3760 ;; If this is an :UNKNOWN-RETURN-PARTNER, then pass the
3761 ;; hook function the original breakpoint, so that users
3762 ;; aren't forced to confront the fact that some
3763 ;; breakpoints really are two.
3764 (if (eq (breakpoint-kind bpt
) :unknown-return-partner
)
3765 (breakpoint-unknown-return-partner bpt
)
3768 (defun signal-context-frame (signal-context)
3769 (let* ((scp (sb-alien:sap-alien signal-context
(* os-context-t
)))
3770 (cfp (int-sap (context-register scp sb-vm
::cfp-offset
))))
3771 (compute-calling-frame cfp
3772 ;; KLUDGE: This argument is ignored on
3773 ;; x86oids in this scenario, but is
3774 ;; declared to be a SAP.
3775 #+(or x86 x86-64
) (context-pc scp
)
3776 #-
(or x86 x86-64
) nil
3779 (defun handle-fun-end-breakpoint (offset component context
)
3780 (let ((data (breakpoint-data component offset nil
)))
3782 (error "unknown breakpoint in ~S at offset ~S"
3783 (debug-fun-name (debug-fun-from-pc component offset
))
3785 (let ((breakpoints (breakpoint-data-breakpoints data
)))
3787 (aver (eq (breakpoint-kind (car breakpoints
)) :fun-end
))
3788 (handle-fun-end-breakpoint-aux breakpoints data context
)))))
3790 ;;; Either HANDLE-BREAKPOINT calls this for :FUN-END breakpoints
3791 ;;; [old C code] or HANDLE-FUN-END-BREAKPOINT calls this directly
3793 (defun handle-fun-end-breakpoint-aux (breakpoints data signal-context
)
3794 ;; FIXME: This looks brittle: what if we are interrupted somewhere
3795 ;; here? ...or do we have interrupts disabled here?
3796 (delete-breakpoint-data data
)
3797 (let* ((scp (sb-alien:sap-alien signal-context
(* os-context-t
)))
3798 (frame (signal-context-frame signal-context
))
3799 (component (breakpoint-data-component data
))
3800 (cookie (code-header-ref component cookie-slot
)))
3801 (dolist (bpt breakpoints
)
3802 (funcall (breakpoint-hook-fun bpt
)
3804 (get-fun-end-breakpoint-values scp
)
3807 (defun get-fun-end-breakpoint-values (scp)
3808 (let ((ocfp (int-sap (context-register
3810 #-
(or x86 x86-64
) sb-vm
::ocfp-offset
3811 #+x86-64 sb-vm
::rbx-offset
3812 #+x86 sb-vm
::ebx-offset
)))
3813 (nargs (boxed-context-register scp sb-vm
::nargs-offset
))
3814 (reg-arg-offsets '#.sb-vm
::*register-arg-offsets
*)
3816 (dotimes (arg-num nargs
)
3817 (push (if reg-arg-offsets
3818 (boxed-context-register scp
(pop reg-arg-offsets
))
3819 (stack-ref ocfp
(+ arg-num
3820 #+(or x86 x86-64
) sb-vm
::sp-
>fp-offset
)))
3822 (nreverse results
)))
3824 ;;;; MAKE-BPT-LRA (used for :FUN-END breakpoints)
3826 ;;; FIXME: why does this imply that it makes an LRA when it actually makes
3827 ;;; a code blob? Despite the rename in git rev 2437d7f139 apparently I took a cue
3828 ;;; from the former name ("MAKE-BOGUS-LRA") as if that spoke the truth.
3829 ;;; Make a breakpoint LRA object that signals a breakpoint trap when returned to.
3830 ;;; If the breakpoint trap handler returns, REAL-LRA is returned to.
3831 ;;; Three values are returned: the new LRA object, the code component it is part of,
3832 ;;; and the PC offset for the trap instruction.
3833 ;;; Note: you can't cache these, because object identity confers a full dynamic
3834 ;;; state of the program, not merely a return PC location.
3835 ;;; (I tried changing this to DEFUN-CACHED, which failed a regression test)
3836 (defun make-bpt-lra (real-lra)
3837 (declare (type #-
(or x86 x86-64 arm64 riscv
) lra
#+(or x86 x86-64 arm64 riscv
) system-area-pointer real-lra
))
3839 #+arm64
(error "Breakpoints do not work on ARM64")
3840 #+riscv
(error "Breakpoints don't work on RISC-V")
3842 (macrolet ((symbol-addr (name)
3843 `(find-dynamic-foreign-symbol-address ,name
))
3845 `(- (symbol-addr "fun_end_breakpoint_trap") src-start
)))
3846 ;; These are really code labels, not variables: but this way we get
3848 (let* ((src-start (symbol-addr "fun_end_breakpoint_guts"))
3849 (length (the index
(- (symbol-addr "fun_end_breakpoint_end")
3852 (sb-c:allocate-code-object
3854 ;; Ensure required boxed header alignment.
3855 (align-up bpt-lra-boxed-nwords sb-c
::code-boxed-words-align
)
3857 n-word-bytes
; Jump Table prefix word
3858 ;; Alignment padding, LRA header
3859 #-
(or x86 x86-64
) (* 2 n-word-bytes
)
3860 ;; 2 extra raw bytes represent CODE-N-ENTRIES (which is zero)
3862 (setf (%code-debug-info code-object
) :bpt-lra
)
3863 (with-pinned-objects (code-object)
3864 #+(or x86 x86-64 arm64
)
3865 (let ((instructions ; Don't touch the jump table prefix word
3866 (sap+ (code-instructions code-object
) n-word-bytes
)))
3867 (multiple-value-bind (offset code
) (compute-lra-data-from-pc real-lra
)
3868 (setf (code-header-ref code-object real-lra-slot
) code
3869 (code-header-ref code-object
(1+ real-lra-slot
)) offset
)
3870 (system-area-ub8-copy (int-sap src-start
) 0 instructions
0 length
)
3871 ;; CODE-OBJECT is implicitly pinned after leaving WITH-PINNED-OBJECTS
3872 ;; (and would be pinned even if the W-P-O were deleted), so we're OK
3873 ;; to return a SAP to the instructions.
3874 ;; TRAP-OFFSET is the distance from CODE-INSTRUCTIONS to the trapping
3875 ;; opcode, for which we have to account for the jump table prefix word.
3876 (values instructions code-object
(+ (trap-offset) n-word-bytes
))))
3877 #-
(or x86 x86-64 arm64
)
3878 (let* ((lra-header-addr
3879 ;; Skip over the jump table prefix, and align properly for LRA header
3880 (sap+ (code-instructions code-object
) (* 2 n-word-bytes
)))
3881 ;; Compute the LRA->code backpointer in words
3882 (delta (ash (sap- lra-header-addr
3883 (int-sap (logandc2 (get-lisp-obj-address code-object
)
3886 (setf (code-header-ref code-object real-lra-slot
) real-lra
)
3887 (setf (sap-ref-word lra-header-addr
0)
3888 (logior (ash delta n-widetag-bits
) return-pc-widetag
))
3889 (system-area-ub8-copy (int-sap src-start
) 0
3890 (sap+ lra-header-addr n-word-bytes
)
3892 (values (%make-lisp-obj
(logior (sap-int lra-header-addr
) other-pointer-lowtag
))
3893 (sanctify-for-execution code-object
)
3894 ;; FIXME: what does "3" represent in this formula?
3895 (+ (trap-offset) (* 3 n-word-bytes
))))))))
3899 ;;; This appears here because it cannot go with the DEBUG-FUN
3900 ;;; interface since DO-DEBUG-BLOCK-LOCATIONS isn't defined until after
3901 ;;; the DEBUG-FUN routines.
3903 ;;; Return a code-location before the body of a function and after all
3904 ;;; the arguments are in place; or if that location can't be
3905 ;;; determined due to a lack of debug information, return NIL.
3906 (defun debug-fun-start-location (debug-fun)
3907 (etypecase debug-fun
3909 (code-location-from-pc debug-fun
3910 (sb-c::compiled-debug-fun-start-pc
3911 (compiled-debug-fun-compiler-debug-fun
3914 ;; (There used to be more cases back before sbcl-0.7.0, when
3915 ;; we did special tricks to debug the IR1 interpreter.)
3919 ;;;; Single-stepping
3921 ;;; The single-stepper works by inserting conditional trap instructions
3922 ;;; into the generated code (see src/compiler/*/call.lisp), currently:
3924 ;;; 1) Before the code generated for a function call that was
3925 ;;; translated to a VOP
3926 ;;; 2) Just before the call instruction for a full call
3928 ;;; In both cases, the trap will only be executed if stepping has been
3929 ;;; enabled, in which case it'll ultimately be handled by
3930 ;;; HANDLE-SINGLE-STEP-TRAP, which will either signal a stepping condition,
3931 ;;; or replace the function that's about to be called with a wrapper
3932 ;;; which will signal the condition.
3934 (defun handle-single-step-trap (kind callee-register-offset
)
3935 (let ((context (nth-interrupt-context (1- *free-interrupt-context-index
*))))
3936 ;; The following calls must get tail-call eliminated for
3937 ;; *STEP-FRAME* to get set correctly on non-x86.
3938 (if (= kind single-step-before-trap
)
3939 (handle-single-step-before-trap context
)
3940 (handle-single-step-around-trap context callee-register-offset
))))
3942 (defvar *step-frame
* nil
)
3944 (defun handle-single-step-before-trap (context)
3945 (let ((step-info (single-step-info-from-context context
)))
3946 ;; If there was not enough debug information available, there's no
3947 ;; sense in signaling the condition.
3950 (signal-context-frame (sb-alien:alien-sap context
))))
3951 (sb-impl::step-form step-info
3952 ;; We could theoretically store information in
3953 ;; the debug-info about to determine the
3954 ;; arguments here, but for now let's just pass
3958 ;;; This function will replace the fdefn / function that was in the
3959 ;;; register at CALLEE-REGISTER-OFFSET with a wrapper function. To
3960 ;;; ensure that the full call will use the wrapper instead of the
3961 ;;; original, conditional trap must be emitted before the fdefn /
3962 ;;; function is converted into a raw address.
3963 (defun handle-single-step-around-trap (context callee-register-offset
)
3964 ;; Fetch the function / fdefn we're about to call from the
3965 ;; appropriate register.
3968 (sb-vm::linkage-addr-
>name
(context-register context callee-register-offset
) :abs
)
3970 (make-lisp-obj (logior (context-register context callee-register-offset
)
3971 #+untagged-fdefns other-pointer-lowtag
)))
3972 (step-info (single-step-info-from-context context
)))
3973 ;; If there was not enough debug information available, there's no
3974 ;; sense in signaling the condition.
3976 (return-from handle-single-step-around-trap
))
3977 (let* ((fun (lambda (&rest args
)
3979 (apply (typecase callee
3980 (fdefn (fdefn-fun callee
))
3981 ((or function
#+linkage-space symbol
) callee
))
3983 ;; Signal a step condition
3985 (let ((*step-frame
* (frame-down (top-frame))))
3986 (sb-impl::step-form step-info args
))))
3987 ;; And proceed based on its return value.
3989 ;; STEP-INTO was selected. Use *STEP-OUT* to
3990 ;; let the stepper know that selecting the
3991 ;; STEP-OUT restart is valid inside this
3992 (let ((sb-impl::*step-out
* :maybe
))
3993 ;; Pass the return values of the call to
3994 ;; STEP-VALUES, which will signal a
3995 ;; condition with them in the VALUES slot.
3997 (multiple-value-call #'sb-impl
::step-values
4000 ;; If the user selected the STEP-OUT
4001 ;; restart during the call, resume
4003 (when (eq sb-impl
::*step-out
* t
)
4004 (sb-impl::enable-stepping
))))
4005 ;; STEP-NEXT / CONTINUE / OUT selected:
4006 ;; Disable the stepper for the duration of
4008 (sb-impl::with-stepping-disabled
4010 (new-callee (etypecase callee
4011 #+linkage-space
((or list symbol
) (sb-vm::stepper-fun fun
))
4014 (let ((fdefn (make-fdefn '(#:dummy
))))
4015 (setf (fdefn-fun fdefn
) fun
)
4018 ;; And then store the wrapper in the same place.
4019 (with-pinned-objects (new-callee)
4020 ;; %SET-CONTEXT-REGISTER is a function, so the address of
4021 ;; NEW-CALLEE gets converted to a fixnum before passing, which
4022 ;; won't keep NEW-CALLEE pinned down. Once it's inside
4023 ;; CONTEXT, which is registered in thread->interrupt_contexts,
4024 ;; it will properly point to NEW-CALLEE.
4026 #+linkage-space
((or list symbol
)
4027 ;; the new callee is a funcallable instance that jumps to FUN.
4028 ;; Point the callee register to the address of the FIN's trampoline word
4029 (setf (context-register context callee-register-offset
)
4030 (+ (get-lisp-obj-address new-callee
)
4031 (- sb-vm
:n-word-bytes sb-vm
:fun-pointer-lowtag
))))
4033 (setf (context-register context callee-register-offset
)
4035 (logandc2 (get-lisp-obj-address new-callee
) lowtag-mask
)
4037 (get-lisp-obj-address new-callee
))))))))
4039 ;;; Given a signal context, fetch the step-info that's been stored in
4040 ;;; the debug info at the trap point.
4041 (defun single-step-info-from-context (context)
4042 (multiple-value-bind (code pc-offset
)
4043 (escaped-frame-from-context context
)
4044 (let* ((debug-fun (debug-fun-from-pc code pc-offset
))
4045 (location (code-location-from-pc debug-fun
4050 (fill-in-code-location location
)
4051 (code-location-debug-source location
)
4052 (compiled-code-location-step-info location
))
4056 ;;; Return the frame that triggered a single-step condition. Used to
4057 ;;; provide a *STACK-TOP-HINT*.
4058 (defun find-stepped-frame ()
4062 ;;;; fetching errorful function name
4064 ;;; This flag is used to prevent infinite recursive lossage when
4065 ;;; we can't find the caller for some reason.
4066 (defvar *finding-frame
* nil
)
4068 (defun find-caller-frame ()
4069 (unless *finding-frame
*
4071 (let* ((*finding-frame
* t
)
4072 (frame (frame-down (frame-down (top-frame)))))
4073 (flush-frames-above frame
)
4075 ((or error debug-condition
) ()))))
4077 (defun find-interrupted-frame ()
4078 (when (plusp *free-interrupt-context-index
*)
4080 (signal-context-frame
4082 (nth-interrupt-context (1- *free-interrupt-context-index
*))))
4083 ((or error debug-condition
) ()))))
4085 (defun find-caller-of-named-frame (name)
4086 (unless *finding-frame
*
4088 (let ((*finding-frame
* t
))
4089 (do ((frame (top-frame) (frame-down frame
)))
4091 (when (and (compiled-frame-p frame
)
4092 (eq name
(debug-fun-name
4093 (frame-debug-fun frame
))))
4094 (let ((caller (frame-down frame
)))
4095 (flush-frames-above caller
)
4097 ((or error debug-condition
) ()))))