确定哪个Linux系统库包含一个函数

10

我正在使用一个开发系统,在其中访问函数时必须指定库名称。

以前我使用过像open()这样的函数,不知怎么的我发现它们在libc.so中。

现在我想使用lstat(),但它似乎不在libc中。不幸的是,我查看的手册没有记录函数位置。

因此,有两个问题:

  1. 有人能告诉我哪个库管理lstat吗?
  2. 我该如何一般性地找到这个信息?除了在lib文件夹中使用grep "name"之外。

1
你不能使用'nm'命令来执行此操作:nm lib*.so* | grep lstat。未经测试,因此只是注释,而不是答案。 - Martin Wickman
lstat在libc中不存在,似乎被称为__lxstat,并且这可能会在链接时解决。 - nos
不幸的是,我从中得到的只是一长串“nm: libXXX.sp.N: no symbols”的列表。很奇怪。也许我的系统出了什么问题。 - Thomas Tempelmann
nos - __lxstat确实存在,但似乎没有起作用 - 它一直返回-1。我猜可能是因为它有更多或不同的参数。 (更新) 确实 - 我应该先检查头文件。它在那里声明了。 - Thomas Tempelmann
2
对于动态对象(例如共享库),需要在nm命令中使用-D选项来显示动态符号而不是普通符号。 - jschmier
6个回答

5

在C语言中建立一个简单的测试用例,编译并运行'ldd -r'命令以检查加载了哪些库。如果你在C语言中没有得到lstat()函数,则说明你的开发环境存在问题,或者这个环境还停留在符号链接之前的时代 :-)


好主意。 在这种情况下,问题实际上是库中没有真正的lstat,只有__lxstat。虽然这可以在头文件中看到。 - Thomas Tempelmann
如果存在来自未知且默认情况下未关联的库的函数,则该想法并不太好。在将库名称添加到二进制链接之前,将没有可运行ldd的二进制文件。另外,还有 LD_DEBUG = all ./binary 以查看实际的链接过程; ld.so 将显示所请求的符号及其尝试查找它们的位置。 - osgx

3
这是一种实现方式:
tomislav@malik:~$ cd /usr/lib
tomislav@malik:/usr/lib$ grep "lstat()" *
Binary file libperl.so.5.10 matches
Binary file libperl.so.5.10.0 matches
tomislav@malik:/usr/lib$ 

2
libperl?那肯定不对。使用“nm”命令代替。例如:nm lib*.so* | grep lstat - Martin Wickman
是的,grep 也显示了 _imports_,我相信这就是关于 libperl 的错误结果。 - Thomas Tempelmann
1
libperl匹配是因为它包含字符串lstat(),这是在此处实现的Perl函数。这与底层系统调用关系不大。 - ephemient

1
当我在Linux上交叉编译Windows应用程序时,如果遇到链接问题,我倾向于使用我命名为mingw-findin的脚本。类似的脚本也可用于常规Linux编译,只需使用普通的nm,而不是mingw替代品,并且不是查找交叉编译前缀目录,而是查找/usr/lib。要使用此脚本,我运行
./mingw-findin函数名称
以下是代码:
#!/bin/sh
liblist=` ls /usr/x86_64-w64-mingw32/lib `

for i in $liblist
do

if x86_64-w64-mingw32-nm /usr/x86_64-w64-mingw32/lib/$i | grep -q $1; then
        echo $i
        x86_64-w64-mingw32-nm /usr/x86_64-w64-mingw32/lib/$i | grep $1
fi

done

还是带上-D标志使用 nm 命令?在 Linux 上还有 /lib 目录;因此,我们应该检查 /etc/ld.so.conf/etc/ld.so.conf.d/* 中的搜索路径以查找库。 - osgx

0

试试这个:

$ cat ./foobar.c
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(void)
{
    struct stat buf;
    return lstat(".", &buf);
}


$ LD_DEBUG=bindings ./foobar 2>&1   | grep stat
31000:  binding file ./foobar [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: \
normal symbol `__lxstat' [GLIBC_2.2.5]

-2

来自 manpage(man lstat):

LSTAT(P)

NAME
       lstat - get symbolic link status

SYNOPSIS
       #include <sys/stat.h>

       int lstat(const char *restrict path, struct stat *restrict buf);

3
OP想知道函数最终存储在哪个库中,而不是哪个头文件中。 - Duck

-2

lstat在libc中,而libc默认链接。你不需要做任何事情来使用lstat,除了包含它的头文件#include <sys/stat.h>

手册页面通常会说明它们所在的库。


1
我认为我清楚地指出了这不是关于C语言,而是关于一个开发环境,在其中我需要明确指定库。 - Thomas Tempelmann
然而,它在libc中,因此链接到libc。如果这是一些与Linux机器上通常发现的内容无关的环境,则需要告诉我们这是什么样的环境。 除了其文档(有时缺乏)之外,没有固定的方法可以知道函数所在的位置。 - nos
nos - 我找不到它在libc中的唯一原因是它在那里没有被声明,正如你在上面指出的那样。我已经解决了,谢谢。 - Thomas Tempelmann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接