wanted: DISASSEMBLE arguments :include-argument-parsing, :include-anonymous-functions

Bug #387357 reported by Tobias C. Rittweiler
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
Confirmed
Wishlist
Unassigned

Bug Description

:INCLUDE-ARGUMENT-PARSING should display the disassembly of what
comes before no-arg-parsing-entry.

:INCLUDE-ANONYMOUS-FUNCTIONS (better name needed) should also
display the disassembly of lambda functions referenced in a function.

For example:

  (defun quux (alist)
    (declare (optimize speed))
    (remove "foo" alist :test #'(lambda (x y)
                                  (string= x (car y)))))

  (disassemble #'quux)

; disassembly for QUUX
; 0B803C31: 8B15FC3B800B MOV EDX, [#xB803BFC] ; "foo"
                                                              ; no-arg-parsing entry point
; 37: 8B35003C800B MOV ESI, [#xB803C00] ; :TEST
; 3D: 8B05F83B800B MOV EAX, [#xB803BF8] ; #<FUNCTION (LAMBDA
                                                              ; #) {B80382D}>
; 43: 8945F8 MOV [EBP-8], EAX
; 46: 8B05043C800B MOV EAX, [#xB803C04] ; #<FDEFINITION object for REMOVE>
; 4C: B910000000 MOV ECX, 16
; 51: FF7504 PUSH DWORD PTR [EBP+4]
; 54: FF6005 JMP DWORD PTR [EAX+5]
; 57: CC0A BREAK 10 ; error trap
; 59: 02 BYTE #X02
; 5A: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR
; 5B: 4D BYTE #X4D ; ECX

I'd also like to see the disassembly of the #<FUNCTION (LAMBDA ...) {B80382D}> object.
It's not always easy to extract the source of such a lambda out to pass it to DISASSEMBLE
because of closures and other lexical dependencies (like the optimize settings in the example.)

Changed in sbcl:
importance: Undecided → Wishlist
status: New → Confirmed
Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

I'm not wild about the names, but I definitely agree with the sentiment. How to display the disassembly of the referenced anon (or just local!) function is a good question, though.

As a stopgap measure here is something I sometimes use:

(defun disassemble-code-object-functions (code-object &key ignore)
  (let ((ep (sb-kernel:%code-entry-points code-object)))
    (loop while ep
          do (unless (member ep ignore)
               (format t "~%===~%~S~%===~%" (sb-kernel:%simple-fun-name ep))
               (disassemble ep))
          (setf ep (sb-kernel:%simple-fun-next ep)))))

(defun disassemble-component (fun &key ignore)
  (disassemble-code-object-functions
   (sb-kernel:fun-code-header (sb-kernel:%fun-fun fun))
   :ignore (mapcar (lambda (name)
                     (sb-kernel:%fun-fun (fdefinition name)))
                   ignore)))

Note that it doesn't really get the elsewhere segment right: the disassembly for (LAMBDA (X Y)) here includes the invalid arg-count traps for both the lambda and the main function. (Which, incidentally, is bad: since the arg count is in ECX in both cases -- like always -- there should be just one trap.)

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.