Search code examples
linuxgdbshared-librarieselfcoredump

How do I get a list of shared library base addresses from a core dump in GDB when I don't have the shared library available?


I've got a core dump that came from another machine, but I don't have all the shared libraries that were loaded in the crashed process. I am not able to log on to the machine or reproduce the install state. I'm definitely not able to reproduce the bug locally.

The crash that triggered this core dump is in a shared library that I don't currently have locally, but I don't know which one.

bt doesn't give me any hints as to which shared library is associated with the address. Here's a snippet of that output:

(gdb) bt
#0  0x00007f4356396c21 in ?? ()
#1  0x00007f4356365009 in ?? ()

One may think that info shared would do the trick, but that only appears to show address ranges for shared libraries that gcc is able to find locally.

(gdb) info shared
From                To                  Syms Read   Shared Object Library
0x00007f43ac42a0c0  0x00007f43ac4b3766  Yes (*)     /usr/lib/x86_64-linux-gnu/libX11.so.6
                                        No          /usr/lib/x86_64-linux-gnu/libGL.so.1

Maybe my crash is in libGL.so.1, but how would I know, since I don't have an address range to work with? Maybe it's in one of the other 50 shared libraries in the process. Is there a reasonable way for me to discover where my crashing addresses come from, presumably by listing all the shared library address ranges? If I know which library this comes from, I might be able to get the original file, or dig around in a .map file to reproduce my call stacks by hand.


Solution

  • Is there a reasonable way for me to discover where my crashing addresses come from, presumably by listing all the shared library address ranges?

    Assuming you have a reasonably recent kernel (circa 2015 or newer) on the other machine, running readelf -n core should produce NT_FILE note with all the relevant info.

    Here is what it looks like for /bin/sleep 60 & X=$!; sleep 1; kill -ABRT $X:

    $ readelf -n core
    
    Displaying notes found at file offset 0x00000580 with length 0x00001450:
      Owner                Data size        Description
      CORE                 0x00000150       NT_PRSTATUS (prstatus structure)
      CORE                 0x00000088       NT_PRPSINFO (prpsinfo structure)
      CORE                 0x00000080       NT_SIGINFO (siginfo_t data)
      CORE                 0x00000150       NT_AUXV (auxiliary vector)
      CORE                 0x00000399       NT_FILE (mapped files)
        Page size: 4096
                     Start                 End         Page Offset
        0x0000563775c50000  0x0000563775c52000  0x0000000000000000
            /usr/bin/sleep
        0x0000563775c52000  0x0000563775c57000  0x0000000000000002
            /usr/bin/sleep
        0x0000563775c57000  0x0000563775c59000  0x0000000000000007
            /usr/bin/sleep
        0x0000563775c59000  0x0000563775c5a000  0x0000000000000009
            /usr/bin/sleep
        0x0000563775c5a000  0x0000563775c5b000  0x000000000000000a
            /usr/bin/sleep
        0x00007f8228800000  0x00007f8228ae9000  0x0000000000000000
            /usr/lib/locale/locale-archive
        0x00007f8228c00000  0x00007f8228c28000  0x0000000000000000
            /usr/lib/x86_64-linux-gnu/libc.so.6
        0x00007f8228c28000  0x00007f8228d98000  0x0000000000000028
            /usr/lib/x86_64-linux-gnu/libc.so.6
        0x00007f8228d98000  0x00007f8228df0000  0x0000000000000198
            /usr/lib/x86_64-linux-gnu/libc.so.6
        0x00007f8228df0000  0x00007f8228df4000  0x00000000000001f0
            /usr/lib/x86_64-linux-gnu/libc.so.6
        0x00007f8228df4000  0x00007f8228df6000  0x00000000000001f4
            /usr/lib/x86_64-linux-gnu/libc.so.6
        0x00007f8228f97000  0x00007f8228f99000  0x0000000000000000
            /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
        0x00007f8228f99000  0x00007f8228fbf000  0x0000000000000002
            /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
        0x00007f8228fbf000  0x00007f8228fca000  0x0000000000000028
            /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
        0x00007f8228fca000  0x00007f8228fcc000  0x0000000000000033
            /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
        0x00007f8228fcc000  0x00007f8228fce000  0x0000000000000035
            /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
      CORE                 0x00000200       NT_FPREGSET (floating point registers)
    ...
    

    You could also use eu-unstrip (related answer):

    eu-unstrip -n --core core
    0x563775c50000+0xb000 1984a78956c92ad376412aabc85955f20d444fe5@0x563775c50368 . - /usr/bin/sleep
    0x7ffde4b8e000+0x1000 2959b90435d422fde8e4f977259e42d551499b04@0x7ffde4b8e554 . - linux-vdso.so.1
    0x7f8228f97000+0x362b8 a897a1105e21dd270bd418fe58c441700a6d8ec5@0x7f8228f97248 /lib64/ld-linux-x86-64.so.2 /usr/lib/debug/.build-id/a8/97a1105e21dd270bd418fe58c441700a6d8ec5.debug ld-linux-x86-64.so.2
    0x7f8228c00000+0x202f90 532d686f61d5422a2617967cbfbecfd4bd6a39c7@0x7f8228c00380 /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/debug/.build-id/53/2d686f61d5422a2617967cbfbecfd4bd6a39c7.debug libc.so.6