Search code examples
clinuxshared-librarieslddynamic-linking

How to know which shared library my program is actually using at run time?


How do I figure out the path of a shared library that my program is using at run time?

I have glibc 2.12 as the primary glibc running on my CentOS 6.10 system, and have also installed glibc 2.14 in /opt/glibc-2.14.

When I inspect my executable file with

$ objdump -p ./myProgram

it gives this info

Dynamic Section:
NEEDED               libpthread.so.0
NEEDED               libcurl.so.4
NEEDED               libc.so.6

and my LD_LIBRARY_PATH has this value /opt/glibc-2.14/lib.

Is there away to see which libc.so.6 library (perhaps with the path to the library file) my program is actually using while it is running?


Solution

  • On Linux: One possible approach is to look into the corresponding entry in the /proc/ filesystem. For example for a program with PID X you can find info in /proc/X/maps similar to:

    ...
    7f34a73d6000-7f34a73f8000 r--p 00000000 08:03 18371015                   /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc-2.27.so
    7f34a73f8000-7f34a7535000 r-xp 00022000 08:03 18371015                   /nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27/lib/libc-2.27.so
    ...
    

    It clearly shows where my libc (the one used by this program) is.


    Example (missing some error handling!) to show where fopen is coming from:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdint.h>
    
    #define BSIZE 200
    
    int main(void) {
        char buffer[BSIZE];
        int const pid = getpid();
        snprintf(buffer, BSIZE, "/proc/%d/maps", pid);
        FILE * const maps = fopen(buffer, "r");
        while (fgets(buffer, BSIZE, maps) != NULL) {
            unsigned long from, to;
            int const r = sscanf(buffer, "%lx-%lx", &from, &to);
            if (r != 2) {
                puts("!");
                continue;
            }
            if ((from <= (uintptr_t)&fopen) && ((uintptr_t)&fopen < to)) {
                char const * name = strchr(buffer, '/');
                if (name) {
                    printf("%s", name);
                } else {
                    puts("?");
                }
            }
        }
        fclose(maps);
    }