首页 > 解决方案 > Qemu 和 LD_LIBRARY_PATH 变量

问题描述

当我qemu-aarch64使用使用共享库的二进制文件执行时,我得到以下信息:

 qemu-aarch64 -L /usr/aarch64-linux-gnu ./test                                                                                 
 ./test: error while loading shared libraries: testlibrary.so.1: cannot open shared object file: No such file or directory

显然是因为test不知道共享库在哪里。

因此:

 qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_PRELOAD="/home/test/libraries/testlibrary.so.1 /home/test/libraries/testlibrary2.so.1" ./test                                                                                 
 hi!

好的,它有效;但是当我使用 LD_LIBRARY_PATH 它不起作用:

  qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_LIBRARY_PATH="/home/test/libraries ./test                                                                                 
 ./test: error while loading shared libraries: testlibrary.so.1: cannot open shared object file: No such file or directory

LD_PRELOAD 和 LD_LIBRARY_PATH 的区别,来自 ld.so man:

LD_PRELOAD: 
      A list of additional, user-specified, ELF shared objects
      to be loaded before all others.  This feature can be used
      to selectively override functions in other shared objects.

      The items of the list can be separated by spaces or
      colons, and there is no support for escaping either
      separator.  The objects are searched for using the rules
      given under DESCRIPTION.  Objects are searched for and
      added to the link map in the left-to-right order specified
      in the list.

      In secure-execution mode, preload pathnames containing
      slashes are ignored.  Furthermore, shared objects are
      preloaded only from the standard search directories and
      only if they have set-user-ID mode bit enabled (which is
      not typical).

      Within the names specified in the LD_PRELOAD list, the
      dynamic linker understands the tokens $ORIGIN, $LIB, and
      $PLATFORM (or the versions using curly braces around the
      names) as described above in Dynamic string tokens.  (See
      also the discussion of quoting under the description of
      LD_LIBRARY_PATH.)

      There are various methods of specifying libraries to be
      preloaded, and these are handled in the following order:

      (1) The LD_PRELOAD environment variable.

      (2) The --preload command-line option when invoking the
          dynamic linker directly.

      (3) The /etc/ld.so.preload file (described below).
          

和,

LD_LIBRARY_PATH: 
      A list of directories in which to search for ELF libraries
      at execution time.  The items in the list are separated by
      either colons or semicolons, and there is no support for
      escaping either separator.  A zero-length directory name
      indicates the current working directory.

      This variable is ignored in secure-execution mode.

      Within the pathnames specified in LD_LIBRARY_PATH, the
      dynamic linker expands the tokens $ORIGIN, $LIB, and
      $PLATFORM (or the versions using curly braces around the
      names) as described above in Dynamic string tokens.  Thus,
      for example, the following would cause a library to be
      searched for in either the lib or lib64 subdirectory below
      the directory containing the program to be executed:

          $ LD_LIBRARY_PATH='$ORIGIN/$LIB' prog

      (Note the use of single quotes, which prevent expansion of
      $ORIGIN and $LIB as shell variables!)
          

为什么它适用于 LD_PRELOAD 而不是 LD_LIBRARY_PATH?

标签: linuxshared-librariesldqemu

解决方案


您使用 LD_PRELOAD 打开的库是“testlibrary.so.1”,但动态加载器要查找的库是“testlibrary.so.3”,这表明您拥有的库版本与该库不匹配二进制文件所链接的版本,这可能是 LD_PRELOAD 是侧步。如果您确保在二进制文件正在查找的目录中有文件,LD_LIBRARY_PATH 是否有效?


推荐阅读