LD_ASSUME_KERNEL 사용법에 대해 알아보기

LD_ASSUME_KERNEL 사용법에 대해 알아보기

LD_ASSUME_KERNEL내 시스템(Debian/bullseye+bpo)의 환경 변수를 이해하려고 합니다 .

에 따르면:

$ man pthreads

나는 이와 같은 것을 실행할 수 있어야 하지만 내 시스템에서는 다음과 같은 결과를 얻습니다.

% LD_ASSUME_KERNEL=2.2.5 ldd /bin/ls
/bin/bash: error while loading shared libraries: libdl.so.2: cannot open shared object file: No such file or directory

무슨 일이 일어나고 있는지 이해하기에는 너무 낮습니다. LD_ASSUME_KERNEL내 시스템의 구현이 다소 손상된 것인지, 아니면 문서를 올바르게 읽지 못한 것인지 알 수 없습니다 .

기타 실패한 시도:

% LD_TRACE_LOADED_OBJECTS=1 LD_ASSUME_KERNEL=2.2.5 ldd
        linux-vdso.so.1 (0x00007ffe3f7e0000)
        libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f5399001000)
        libdl.so.2 => not found
        libc.so.6 => not found
        libc.so.6 => not found

그리고

% LD_TRACE_LOADED_OBJECTS=1 LD_ASSUME_KERNEL=2.4.19 ldd
        linux-vdso.so.1 (0x00007ffeaacb9000)
        libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f861cb18000)
        libdl.so.2 => not found
        libc.so.6 => not found
        libc.so.6 => not found

하지만:

% LD_TRACE_LOADED_OBJECTS=1 ldd
        linux-vdso.so.1 (0x00007ffc929a9000)
        libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007fa319a29000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa319a23000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa31985e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fa319aaa000)

인용하다:

$ man pthreads
[...]
   Selecting the threading implementation: LD_ASSUME_KERNEL
       On systems with a glibc that supports both LinuxThreads and NPTL (i.e., glibc 2.3.x), the LD_ASSUME_KERNEL environment variable can be used to override  the  dynamic  linker's  default  choice  of threading implementation.  This variable tells the dynamic linker to assume that it is running on top of a particular kernel version.  By specifying a kernel version that does not provide the support required by NPTL, we can force the use of LinuxThreads.  (The most likely reason for doing this is to run a (broken) application that depends on some nonconformant behavior in  LinuxThreads.)
       For example:

           bash$ $( LD_ASSUME_KERNEL=2.2.5 ldd /bin/ls | grep libc.so | \
                           awk '{print $3}' ) | egrep -i 'threads|nptl'
                   linuxthreads-0.10 by Xavier Leroy

다음에도 적용됩니다.

$ man ld.so
[...]
       LD_ASSUME_KERNEL (since glibc 2.2.3)
              Each  shared object can inform the dynamic linker of the minimum kernel ABI version that it requires.  (This requirement is encoded in an ELF note section that is viewable via readelf -n as
              a section labeled NT_GNU_ABI_TAG.)  At run time, the dynamic linker determines the ABI version of the running kernel and will reject loading shared objects that specify minimum ABI versions
              that exceed that ABI version.

              LD_ASSUME_KERNEL  can  be  used to cause the dynamic linker to assume that it is running on a system with a different kernel ABI version.  For example, the following command line causes the
              dynamic linker to assume it is running on Linux 2.2.5 when loading the shared objects required by myprog:

                  $ LD_ASSUME_KERNEL=2.2.5 ./myprog

              On systems that provide multiple versions of a shared object (in different directories in the search path) that have different minimum kernel ABI version requirements, LD_ASSUME_KERNEL  can
              be used to select the version of the object that is used (dependent on the directory search order).

              Historically,  the  most common use of the LD_ASSUME_KERNEL feature was to manually select the older LinuxThreads POSIX threads implementation on systems that provided both LinuxThreads and
              NPTL (which latter was typically the default on such systems); see pthreads(7).
% apt-cache policy manpages
manpages:
  Installed: 5.10-1
  Candidate: 5.10-1
  Version table:
 *** 5.10-1 500
        500 http://deb.debian.org/debian bullseye/main amd64 Packages
        500 http://deb.debian.org/debian bullseye/main i386 Packages
        100 /var/lib/dpkg/status

참고로 다음의 출력은 항상 동일합니다.

/lib/x86_64-linux-gnu/libc.so.6
LD_ASSUME_KERNEL=2.2.5 /lib/x86_64-linux-gnu/libc.so.6
LD_ASSUME_KERNEL=2.4.19 /lib/x86_64-linux-gnu/libc.so.6

나는 얻다:

GNU C Library (Debian GLIBC 2.31-13+deb11u3) stable release version 2.31.
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 10.2.1 20210110.
libc ABIs: UNIQUE IFUNC ABSOLUTE
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.

답변1

여기서 가장 중요한 부분은 매뉴얼의 다음 인용문입니다.

런타임 시 동적 링커는 실행 중인 커널의 ABI 버전을 확인하고 해당 ABI 버전을 초과하는 최소 ABI 버전을 지정하는 공유 객체 로드를 거부합니다.

file주어진 라이브러리에 대한 최소 ABI 버전이 무엇인지 알려줄 것입니다. 이 를 실행하고 있으므로 x86_64대부분의 경우 최소 ABI 버전은 3.2.0입니다.

$ file -L /lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc-2.31.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=2e5abcee94f3bcbed7bba094f341070a2585a2ba, for GNU/Linux 3.2.0, stripped

시스템에서 예외는 libtinfo.so.6최소 ABI를 선언하지 않는다는 것입니다.

$ file -L /lib/x86_64-linux-gnu/libtinfo.so.6
/lib/x86_64-linux-gnu/libtinfo.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=d6920dbdd057f44edaf4c1fbce191b5854dfd9e6, stripped

3.2.0보다 작은 값을 설정하면 버전 3.2.0 이상이 필요한 라이브러리를 거부하도록 동적 링커에 지시합니다. LD_ASSUME_KERNEL시스템이 덜 까다로운 요구 사항을 가진 영향을 받는 라이브러리의 다른 버전을 제공하지 않기 때문에 ld.so실패하게 됩니다 .

관련 정보