Search code examples
lispcommon-lispsbcl

Function address not in the range of memory-mapped files for the lisp image process


After defining and disassembling the function fn, I can see that the function (or code component) resides at memory address 0x53675216. But I don't see said memory address to be in the range of memory-mapped files attributed to the lisp image process (I'm using SBCL).

Am I missing something about how the internals of a process work?

enter image description here


FWIW My goal was to dump the entire memory of the process and inspect some of the memory. But if I can't even get at a function that I defined, what's the point?


Solution

  • Please post the actual text rather than a picture of the text.

    /proc/<pid>/map_files is not the right thing to look at: instead look at /proc/<pid>/maps which shows you all the memory maps.

    In my case if I define & compile foo on SBCL on x64 / Linux as:

    (defun foo ())
    

    Then (disassemble 'foo) looks like:

    ; disassembly for foo
    ; Size: 21 bytes. Origin: #x53624A7C                          ; foo
    [...]
    

    And I can use my hexdump-thing function from this answer to check this:

    > (hexdump-thing #'foo)
    > (hexdump-thing #'foo)
    lowtags:    1011
    function:   0000000053624A6B : 0000000053624A60
    

    So the actual address of the object is #x0000000053624A60, which is compatible with what disassemble is saying.

    So then if I look at /proc/<pid>/maps I see, among all the other lines, two lines like:

    52a00000-533f8000 rwxp 016a8000 fd:00 2758077                            /local/environments/sbcl/lib/sbcl/sbcl.core
    533f8000-5ac00000 rwxp 00000000 00:00 0
    

    The fields in this file are address, permissions, offset, device, inode, file. You can see that the range that includes the function's address is not mapped to any file (note that p means 'copy on write' so the range mapped to the core file will never be written back to the core file).

    The function's definition lives somewhere in this anonymous range of memory.


    As a note: if you want to investigate the memory of the implementation, do it from within the implementation, which will be hugely easier than trying to investigate it from outside. SBCL has lots of support for this sort of thing, although you have to find some of them by grovelling around in the source. After all this sort of thing is exactly what a garbage collector has to do.