【问题标题】:Why no error without library specifiers in Linux?为什么在 Linux 中没有库说明符就没有错误?
【发布时间】:2015-10-19 19:42:18
【问题描述】:

我目前是一名学生,正在学习操作系统并使用 Linux 作为操作系统进行练习。当我们开始使用多线程应用程序并开始练习它们(主要是 pthread_create() 和 pthread_join() )时,该类最常见的错误之一是在编译它们时使用:

gcc -Wall homework.c

代替:

gcc -Wall -lpthread homework.c

我的问题是为什么编译器和链接器在未使用 -lpthread 说明符编译/链接时不会抛出错误,即使代码中使用的函数需要 pthread 库。我的导师似乎也不知道原因。只是学校建立我们的系统的方式吗?所有 Linux 环境都会发生这种情况吗?为什么没有抛出链接错误?

【问题讨论】:

  • 注意pthread 是一种特殊 库,gcc 的正确参数是-pthread,而不是-lpthread。仍然很有趣的问题。
  • 根据@FelixPalmen 的回答,您最好提供一个示例代码,其中的问题是-- 没有给出-pthread 选项时没有编译器/链接器错误--可以复制。请同时提供您正在使用的 GCC 版本,来自 gcc --version,因为这些细节是特定于实现的。它还可能取决于您使用的 glibc 版本。
  • 使用gcc -v -Wall homework.c 找出gcc 在做什么...

标签: c linux pthreads


【解决方案1】:

无法重现:

#include <pthread.h>

void *thread(void *arg)
{
    (void) arg;
    return 0;
}

int main(void)
{
    pthread_t t;
    pthread_create(&t, 0, thread, 0);
    return 0;
}

试图在没有libpthread的情况下链接:

> gcc -Wall -o thread thread.c
/tmp/ccyyu0cn.o: In function `main':
thread.c:(.text+0x2e): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status

编辑:您可以使用nm -D 检查库中定义的符号,例如就我而言:

> nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep pthread_create
> nm -D /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
00000000000082e0 T pthread_create

(所以pthread_createlibc中找到,但确实在libpthread中)

edit2:您声称观察到的行为的唯一可能原因是其中一个库链接默认libc,也许是libgcc)定义pthread_create。那么它可能仍然依赖于仅在libpthread 中定义的东西。我现在想知道某些特定版本是否确实如此。请提供反馈。

【讨论】:

    【解决方案2】:

    @FelixPalmen 答案的附加假设。 pthread 可以传递给 gcc 规范中声明的链接器。 gcc 可以使用内置规范或从文件中读取。

    实验

    默认情况下,当我尝试在没有-lpthreads 的情况下构建示例时,系统链接器会出现打印错误:

    serga@XXXXX:~$ gcc ./thread.c -o thread
    /tmp/ccHgCRzO.o: In function `main':
    thread.c:(.text+0x29): undefined reference to `pthread_create'
    collect2: error: ld returned 1 exit status
    

    首先我检测到which files gcc tries to use as spec

    serga@XXXXX:~$ strace gcc 2>&1 | grep spec
    access("/usr/lib/gcc/i686-linux-gnu/5/specs", R_OK) = -1 ENOENT (No such file or directory)
    access("/usr/lib/gcc/i686-linux-gnu/5/../../../../i686-linux-gnu/lib/i686-linux-gnu/5/specs", R_OK) = -1 ENOENT (No such file or directory)
    access("/usr/lib/gcc/i686-linux-gnu/5/../../../../i686-linux-gnu/lib/specs", R_OK) = -1 ENOENT (No such file or directory)
    access("/usr/lib/gcc/i686-linux-gnu/specs", R_OK) = -1 ENOENT (No such file or directory)
    

    然后我创建自己的规范 getting build-in one 并将其放入上一步中获得的路径中:

        serga@XXXXX:~$ sudo gcc -dumpspecs >/usr/lib/gcc/i686-linux-gnu/5/specs
    

    我将-lpthread 一个一个插入到规范文件的*link:*lib:*libgcc: 部分。在所有情况下,gcc 都可以在不明确提及 pthread 库的情况下构建程序:

    serga@XXXXX:~$ gcc ./thread.c -o thread && echo "completed"
    completed
    

    明白了!!!

    检测 gcc 是否使用任何额外的规范文件

    需要看下一个的输出(我用的是gcc-5.1.0):

    serga@XXXXX:~$ gcc -v 2>&1 | head -1
    
    • 如果 gcc 使用特定文件中的规范,您将看到下一个:

      Reading specs from /usr/lib/gcc/i686-linux-gnu/5/specs
      
    • 否则:

      Using built-in specs.
      

      您可以看到这样做的内置规范:

      serga@XXXXX:~$ gcc -dumpspecs
      

    默认检测是否与pthread链接

    需要查看获取的规范文件中与链接器相关的部分中-lpthread 的任何外观。

    Spec file reference

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-07
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多