linuxdynamic-linking

Making binary depend on the correct `libpthread`


I have these files:

└─$ ls
ld-2.31.so  libc.so.6  libpthread-2.31.so  professor  professor.zip

(I extracted them our of the zip file)

When running professor, I receive the following error:

└─$ ./professor
./professor: ./libc.so.6: version `GLIBC_ABI_DT_RELR' not found (required by /lib/x86_64-linux-gnu/libpthread.so.0)

I assume it is caused because the binary is not correctly dependant on the libpthread-2.31.so in the current directory:

└─$ ldd professor
./professor: ./libc.so.6: version `GLIBC_ABI_DT_RELR' not found (required by /lib/x86_64-linux-gnu/libpthread.so.0)
        linux-vdso.so.1 (0x00007ffefb53f000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7d5ce0a000)
        libc.so.6 => ./libc.so.6 (0x00007f7d5cc18000)
        ./ld-2.31.so => /lib64/ld-linux-x86-64.so.2 (0x00007f7d5ce24000)

Using patchelf --set-rpath . professor didn't help, as the rpath is already .. Looks like the loader is also set correcgtly, it's just libpthread that's problematic.

How can I make the binary depend on the correct libpthread?


Solution

  • See bottom for TLDR.

    You want to use the local libpthread-2.31.so, but your executable is linked to libpthread.so.0 not libpthread-2.31.so. You can create a symbolic link to set up this relationship.

    I don't have access to your professor executable but I'll use another common Linux command, gvim, to illustrate. This command is not linked against libpthread but I'll use libgtk instead to illustrate.

    $ ldd /usr/bin/gvim | grep libgtk
            libgtk-3.so.0 => /lib/x86_64-linux-gnu/libgtk-3.so.0 (0x00007f9c98000000)
    

    The gvim executable is linked against libgtk-3.so.0, which resolves to /lib/x86_64-linux-gnu/libgtk-3.so.0. But if you look at that path then you'll see that it's a symbolic link to another file.

    $ ls -l /lib/x86_64-linux-gnu/libgtk-3.so.0
    /lib/x86_64-linux-gnu/libgtk-3.so.0 -> libgtk-3.so.0.2405.32
    

    Make a local copy of the target file.

    $ cp /lib/x86_64-linux-gnu/libgtk-3.so.0.2405.32 .
    

    Now check the dependencies again.

    $ ldd /usr/bin/gvim | grep libgtk
            libgtk-3.so.0 => /lib/x86_64-linux-gnu/libgtk-3.so.0 (0x00007f924b000000)
    

    Nothing has changed. But that's because we have not modified the linker path. Let's try that.

    $ LD_LIBRARY_PATH=. ldd /usr/bin/gvim | grep libgtk
            libgtk-3.so.0 => /lib/x86_64-linux-gnu/libgtk-3.so.0 (0x00007f891cc00000)
    

    Still no change. Okay, now create a symbolic link.

    $ ln -s libgtk-3.so.0.2405.32 libgtk-3.so.0
    
    $ ls -l
    libgtk-3.so.0 -> libgtk-3.so.0.2405.32
    libgtk-3.so.0.2405.32
    

    Check on the linker again.

    $ LD_LIBRARY_PATH=. ldd /usr/bin/gvim | grep libgtk
            libgtk-3.so.0 => ./libgtk-3.so.0 (0x00007f3620800000)
    

    Aha! Now it's linking against the local copy.

    TLDR

    So I suspect that you need to do something like this:

    $ ln -s libpthread-2.31.so libpthread.so.0
    

    The check linking again.

    $ LD_LIBRARY_PATH=. ldd professor
    

    The linker should then find the local link libpthread.so.0 which points to the (local) libpthread-2.31.so file.