我目前在 debian (wheezy/amd64) 上有一个奇怪的问题。
我创建了一个 chroot 来安装服务器(抱歉,我无法提供更多详细信息)。让我们称其为 path /chr_path/。为方便起见,我使用 debootstrap(也是 wheezy/amd64)初始化了这个 chroot。
在 chroot 中一切似乎都运行良好,但是当我启动服务器的安装程序脚本时,我得到了 :(
zsh: Not found /some_path/perl由于某些原因,安装程序包含一个 perl 二进制文件)
当然,我检查了/some_path/位置并找到了“perl”二进制文件。file在 chroot 环境中返回:
/some_path/perl ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped
Run Code Online (Sandbox Code Playgroud)
该文件存在,似乎没问题,具有正确的权限。我可以在它上面使用file, ls,vim但是一旦我尝试执行它 -./perl例如 - 我得到 : zsh: Not found ./perl。
这种情况对我来说是可以理解的。而且 :
/chr_path/some_path/perl …假设我想测试一个库是否已安装并可由程序使用。我可以ldconfig -p | grep mylib用来确定它是否安装在系统上。但是如果图书馆只能通过设置知道LD_LIBRARY_PATH怎么办?
在这种情况下,程序可能能够找到库,但ldconfig不会。如何检查库是否在组合链接器路径中?
我要补充一点,我正在寻找一种解决方案,即使我手头实际上没有该程序(例如该程序尚未编译),我也正在寻找一种解决方案,我只想知道某个库存在于ld' s 路径。
我有一个名为“alpha”的二进制可执行文件,它需要一个链接库(libz.so.1.2.7),它位于 /home/username/myproduct/lib/libz.so.1.2.7
在通过执行以下命令生成二进制可执行文件之前,我将其导出到我的终端实例。
export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)
现在,当我生成另一个需要相同库但版本不同的应用程序“bravo”时,即 (libz.so.1.2.8) 在 中可用
/lib/x86_64-linux-gnu/libz.so.1.2.8,系统抛出以下错误。
version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)
Run Code Online (Sandbox Code Playgroud)
如果我取消设置LD_LIBRARY_PATH,“bravo”启动正常。我了解上述行为是因为LD_LIBRARY_PATH在/etc/ld.so.conf查找链接库时优先于定义的目录路径,因此发生了上述错误。我只是好奇,如果库的第一个实例是不同的版本,为什么 UNIX/LINUX 的开发人员没有设计操作系统根据层次结构搜索其他目录中的链接库。
简单地说,UNIX/LINUX 系统遍历一组目录,直到找到所需的库。但是为什么它在找到预期版本之前不做同样的事情,而不是接受库的第一个实例而不管其版本如何?
我偶然发现在我的 Debian Jessie 上没有LD_LIBRARY_PATH变量(确切地说,printenv | grep LD没有显示与链接器相关的任何内容,echo "$LD_LIBRARY_PATH"也没有显示任何内容)。
在 x 终端仿真器(可能由于 setgid 清除它)以及基本终端 ( Ctrl+Alt+F1) 中就是这种情况。
我知道这LD_LIBRARY_PATH 可能被认为是不好的,所以 Debian 可能会以某种方式阻止它,但另一方面,有一些文件/etc/ld.so.conf.d/包含一些要添加到LD_LIBRARY_PATH. 我的 rc 文件(我知道的)都没有弄乱LD_LIBRARY_PATH。
为什么我看不到LD_LIBRARY_PATH变量?
我知道这个问题不是很新,但似乎我无法解决我自己的问题。
ldd 生成以下输出
u123@PC-Ubuntu:~$ ldd /home/u123/Programme/TestPr/Debug/TestPr
    linux-vdso.so.1 =>  (0x00007ffcb6d99000)
    libcsfml-window.so.2.2 => not found
    libcsfml-graphics.so.2.2 => not found
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcebb2ed000)
    /lib64/ld-linux-x86-64.so.2 (0x0000560c48984000)
Run Code Online (Sandbox Code Playgroud)
哪个是告诉ld正确路径的正确方法?
当我通过strace实用程序运行命令时,我可以看到访问错误,例如
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
现在我在某处读到,上面一行中发生的事情是链接器正在寻找我正在运行的命令的优化版本,但找不到它。
我该如何解决这个问题?我需要安装什么软件包才能ld.so.nohwcap在系统上拥有该文件?即使不是出于优化目的而只是为了摆脱strace?
在我的情况下,似乎LD_LIBRARY_PATH设置为空字符串。但是所有标准系统工具仍然可以正常工作,所以我猜动态链接器会检查这种情况并LD_LIBRARY_PATH在这种情况下使用一些默认值。
这个默认值是多少?我想它至少包括/usr/lib但还有什么?有没有什么好的系统方法来确定动态链接器将搜索的标准位置?
这个问题与动态链接器将搜索的路径略有不同。 有一个默认值意味着它会使用LD_LIBRARY_PATH如果给定的值,或者如果没有给定,它将使用默认值 - 这意味着它不会使用如果LD_LIBRARY_PATH提供了默认值。
虽然两者都被称为“链接器”并用于链接二进制文件,但我真的无法弄清楚它们之间的区别。谁能告诉我他们的区别?
我有一个读取文件的应用程序。我们称之为processname和文件~/.configuration。当processname运行时,它总是读取~/.configuration并且不能以不同的方式配置。还有其他应用程序依赖于“~/.configuration”,之前和之后,但不是在processname运行时。
在替换~/.configuration内容的脚本中包装processname是一个选项,但我最近断电(当内容被换出时),我丢失了所述文件的先前内容,所以这是不可取的。
有没有办法(也许使用与 远相关的东西LD_DEBUG=files processname?)来欺骗进程在尝试读取特定文件时读取不同的内容?在可执行文件中搜索和替换文件名有点侵入性,但应该也能工作。
我知道可以编写一个内核模块来接管open()调用(https://news.ycombinator.com/item?id=2972958),但是有没有更简单或更干净的方法?
编辑:在processname可执行文件中搜索~/.configuration 时,我发现它在读取~/.configuration之前尝试读取另一个文件名。问题解决了。
有两个文件,一个编译并链接,gcc另一个手动使用nasm,ld我得到
这两件事有什么区别?我可以看到readelf -h那个是
DYN (Shared object file)EXEC (Executable file)我可以在维基百科ET_DYNET_EXEC上看到这些记录为和。这两者之间有什么实际区别?