标签: ld

排序 /etc/ld.so.conf 可以吗

我想知道我是否可以将条目/etc/ld.so.conf排序。

ld.so.conf现在看起来像这样:

/usr/X11R6/lib64/Xaw3d
/usr/X11R6/lib64
/usr/lib64/Xaw3d
/usr/X11R6/lib/Xaw3d
/usr/X11R6/lib
/usr/lib/Xaw3d
/usr/x86_64-suse-linux/lib
/usr/local/lib
/opt/kde3/lib
/usr/local/lib64
/opt/kde3/lib64
/lib64
/lib
/usr/lib64
/usr/lib
/usr/local/cuda-6.5/lib64
Run Code Online (Sandbox Code Playgroud)

当我排序时,它看起来像这样 - 我可以安全地进行排序还是它们是我会“破坏”排序的一些依赖项?

/lib
/lib64
/opt/kde3/lib
/opt/kde3/lib64
/usr/X11R6/lib
/usr/X11R6/lib/Xaw3d
/usr/X11R6/lib64
/usr/X11R6/lib64/Xaw3d
/usr/lib
/usr/lib/Xaw3d
/usr/lib64
/usr/lib64/Xaw3d
/usr/local/cuda-6.5/lib64
/usr/local/lib
/usr/local/lib64
/usr/x86_64-suse-linux/lib
include /etc/ld.so.conf.d/*.conf
Run Code Online (Sandbox Code Playgroud)

shared-library ld

7
推荐指数
1
解决办法
1万
查看次数

如何找出使用给定 C 库函数所需的链接器标志?

运行示例 C 代码是一项痛苦的练习,除非它带有 makefile。

我经常发现自己有一个 C 文件,其中包含的代码据说可以做一些很酷的事情,但是第一次基本的编译尝试 ( gcc main.c) 失败了——

main.c:(.text+0x1f): undefined reference to `XListInputDevices'
clang-3.7: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

——或类似。

我知道这意味着我缺少正确的链接器标志,例如-lX11,-lXext-lpthread

但哪些呢?


我目前处理这个问题的方法是找到包含一个函数的库头文件,使用 Github 的搜索来查找其他一些导入相同头文件的程序,打开它的 makefile,找到链接器标志,将它们复制到我的编译命令中,并继续删除标志,直到我找到仍然可以编译的最小集合。

这是低效的,无聊的,让我觉得必须有更好的方法。

compiling c ld

7
推荐指数
1
解决办法
6291
查看次数

覆盖正在运行的可执行文件或 .so

我有一个关于覆盖正在运行的可执行文件或覆盖一个或多个正在运行的程序正在使用的共享库 (.so) 文件的问题。

过去,出于显而易见的原因,覆盖正在运行的可执行文件是行不通的。甚至还有一个特定的 errno 值 ETXTBSY,它涵盖了这种情况。

但现在相当长一段时间,我注意到,当我不小心尝试覆盖正在运行的可执行文件(例如,通过发射了一个构建,其最后一步是cc -o exefile对的exefile,恰好运行),它的工作原理!

所以我的问题是,这是如何工作的,是否在任何地方都有记录,依赖它是否安全?

看起来有人可能已经调整ld以取消链接其输出文件并创建一个新文件,只是为了消除这种情况下的错误。我不太清楚它是一直在这样做,还是仅在需要时才这样做(也就是说,可能是在它尝试覆盖现有文件并遇到 ETXTBSY 之后)。而且我在ld的手册页上没有看到任何提及。(我想知道为什么人们不抱怨ld现在可能会破坏他们的硬链接,或者改变文件所有权,等等。)


附录:这个问题并不是专门关于cc/ ld(尽管这最终成为答案的重要部分);问题真的只是“为什么我再也看不到 ETXTBSY?它仍然是一个错误吗?” 答案是,是的,它仍然是一个错误,只是在实践中很少见。(另请参阅我刚刚发布到我自己的问题的澄清答案。)

executable write ld

7
推荐指数
1
解决办法
2978
查看次数

ELF 符号可见性级别之间有什么区别?

NASM关于elf全球指令的扩展”的文档说,

您还可以选择控制符号的 ELF 可见性。只需添加可见性关键字之一:defaultinternalhiddenprotecteddefault当然是默认的。

这些是在哪里定义的?以及如何ld使用它们?我看到C++ 中经常提到的访问级别包括protectedpublicprivate,但我不知道这是否是 ELF 所引用的?

我的用例是 C 和汇编,因此如果您能让这与这两种语言和链接器相关,那就加分了。

elf symbol-table ld nasm

7
推荐指数
1
解决办法
4761
查看次数

setuid 二进制文件的 LD_PRELOAD

我正在尝试覆盖程序的 malloc/free 函数,这需要 setuid/setgid 权限。为此,我使用 LD_PRELOAD 变量。根据ld 文档,我需要将我的库放入标准搜索目录之一(我选择 /usr/lib)并为其授予 setuid/setgid 权限。我已经这么做了。但是,我仍然无法链接到我的 .so 文件,出现错误:

object 'liballoc.so' from LD_PRELOAD cannot be preloaded: ignored

可能的原因是什么?在没有 setuid/setgid 权限的程序上测试了这个 .so 文件,一切正常。操作系统:红帽7.0

linux rhel ld

7
推荐指数
2
解决办法
1998
查看次数

LD_PRELOAD 不起作用,LD_DEBUG 不显示任何内容

我用来LD_PRELOAD覆盖该read函数。对于最小的测试应用程序,它工作得很好,但如果我用更大的应用程序测试它,它就不再工作了。也根本LD_DEBUG=all不显示任何内容:

LD_DEBUG=all LD_PRELOAD=./lib.so ./big_app
Run Code Online (Sandbox Code Playgroud)

这只是运行./big_appLD_PRELOAD没有任何效果。有办法调试吗?

bash ld

7
推荐指数
1
解决办法
1480
查看次数

未定义的引用,即使链接库确实存在

我尝试从源代码编译 VTK,但收到以下错误。我运行的是 Fedora 27,内核版本 4.14.11-300.fc27.x86_64

/usr/lib64/libSM.so: undefined reference to `uuid_generate@UUID_1.0'
/usr/lib64/libSM.so: undefined reference to `uuid_unparse_lower@UUID_1.0'
Run Code Online (Sandbox Code Playgroud)

ldd /usr/lib64/libSM.so节目

 $ldd /usr/lib64/libSM.so
    linux-vdso.so.1 (0x00007ffd4998b000)
    libICE.so.6 => /lib64/libICE.so.6 (0x00007f3aa36ff000)
    libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f3aa34fa000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f3aa3115000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f3aa3b23000)
Run Code Online (Sandbox Code Playgroud)

进一步查看libuuid.so.1中的符号显示

$objdump -T /lib64/libuuid.so.1 | grep 'uuid_generate$'
0000000000002370 g    DF .text  0000000000000087  UUID_1.0    uuid_generate

$objdump -T /lib64/libuuid.so.1 | grep 'uuid_unparse_lower'
0000000000002710 g    DF .text  0000000000000002  UUID_1.0    uuid_unparse_lower
Run Code Online (Sandbox Code Playgroud)

的输出ldconfig

$sudo ldconfig -p | grep libuuid

libuuid.so.1 (libc6,x86-64) => /lib64/libuuid.so.1
    libuuid.so.1 (libc6) => /lib/libuuid.so.1 …
Run Code Online (Sandbox Code Playgroud)

linux linker ld

6
推荐指数
1
解决办法
2561
查看次数

Fedora 27 /usr/bin/ld: 找不到 -lstdc++

我有 Fedora 27。我正在从源代码构建一些东西。(如果重要的话,它是https://github.com/xmrig/xmrig-nvidia)。

Make 进行链接,然后失败并显示以下消息:

/usr/bin/ld: cannot find -lstdc++
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

安装了 libstdc++ 和 libstdc++-devel 包。为了以防万一,现在还安装了它们的 32 位版本。我仍然收到消息。

我能做些什么来解决这个问题?谢谢!

fedora make libraries c++ ld

6
推荐指数
1
解决办法
3084
查看次数

是否存在 ld 忽略 LD_LIBRARY_PATH 的情况?

我刚刚遇到一个ld我无法解释的小问题。假设我在我的主目录中编译了一个库并将其全部安装在~/root. 共享库文件可以在以下位置找到~/root/usr/local/lib/libmylib.so

因为~/root/usr/local/lib不在链接器的搜索路径中,所以我LD_LIBRARY_PATH像往常一样设置:

LD_LIBRARY_PATH="$HOME/root/usr/local/lib"
export LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)

并检查该库是否可用:

$ ls $LD_LIBRARY_PATH/libmylib.so
/home/me/root/usr/local/lib/libmylib.so
Run Code Online (Sandbox Code Playgroud)

现在,如果我运行:

$ ld -lmylib --verbose
Run Code Online (Sandbox Code Playgroud)

最后几行应包含以下内容:

attempt to open /home/me/root/usr/local/lib/libmylib.so succeeded
-lmylib (/home/me/root/usr/local/lib/libmylib.so)
Run Code Online (Sandbox Code Playgroud)

除了我的情况外,他们没有。ld根本不执行任何查找/home/me/root。的内容LD_LIBRARY_PATH根本不会出现在输出中,这表明ld无耻地忽略了该变量(实际上,我的目录从未出现在SEARCH_DIR输出的前面)。

但是,如果我运行:

$ ld -L $LD_LIBRARY_PATH -lmylib --verbose
Run Code Online (Sandbox Code Playgroud)

我确实得到了上述几行,一切都很顺利,这意味着库或安装路径没有任何问题。

有没有什么情况可以ld忽略LD_LIBRARY_PATH?我已经检查过env,但找不到任何其他与链接器相关的变量(RPATHLIBRARY_PATHLD_RUN_PATH,都经过测试)。除了注册一些(其他)目录之外,下面的配置/etc/ld.so.*似乎没有做任何事情。该机器运行 Scientific Linux 7.4、gcc 6.4 和 ld 2.25.1。有问题的图书馆是libxml++-3.0.

shared-library ld

6
推荐指数
1
解决办法
5631
查看次数

如何阻止进程写入 systemd 日志?

我正在使用第三方 .NET Core 应用程序(VS Code 扩展使用的二进制发行版),不幸的是,该应用程序启用了诊断日志记录,但没有明显的方法来禁用它(我已经向作者报告了这一点)。理想的解决方案(除了能够禁用它之外)是,如果我可以指定 systemd 它不应该为该特定程序记录任何内容,但我一直无法找到任何方法来执行此操作。这是迄今为止我尝试过的所有内容:

我尝试的第一件事是重定向stdoutstderr/dev/null: dotnet-app > /dev/null 2>&1。这确实禁用了任何正常输出,但诊断日志记录仍在写入 systemd 日志。

我希望应用程序有一个命令行参数,允许我禁用诊断日志记录。它确实有一个冗长的参数,但经过实验,它似乎只对正常输出有影响,对诊断日志记录没有影响。

通过使用strace并查找对 的调用connect,我发现应用程序将诊断日志直接写入到/dev/log.

该路径/dev/log是 的符号链接/run/systemd/journal/dev-log,因此为了验证我的发现,我将符号链接更改为指向/dev/null。这确实阻止了诊断日志记录出现在 systemd 日志中。

有人告诉我LD_PRELOAD并制作了一个库,connect用我自己的版本替换了标准,在尝试连接到/dev/log. 这在我的测试程序中工作正常,但在 .NET Core 应用程序中失败,在connect ENOENT /tmp/CoreFxPipe_1ddf2df2725f40a68990c92cb4d1ff1e. 我尝试了我的库,但即使我所做的只是直接将参数传递给标准connect函数,它仍然会失败并出现相同的错误。

然后,我尝试使用 Linux 命名空间来实现它,以便仅/dev/log指向/dev/null.NET Core 应用程序:unshare --map-root-user --mount sh -c "mount --bind /dev/null /dev/log; dotnet-app $@". …

gdb unix-sockets ld unshare systemd-journald

6
推荐指数
1
解决办法
2124
查看次数