IT袋

当前位置:主页 > 经验教程 > 系统教程 >

Linux

Linux 下“Hello World”的幕后发生了什么(6)

时间:2023-09-17 20:02:06 来源:IT袋 作者:苏晓敏
导读:Linux,好的!我们已从磁盘读取了字节数据,并启动了这个解释器。那么,接下来会发生什么呢?如果你执行 strace -o out.strace python3 ,你会在 execve 系统调用之后

Linux

好的!我们已从磁盘读取了字节数据,并启动了这个“解释器”。那么,接下来会发生什么呢?如果你执行strace -o out.strace python3,你会在execve系统调用之后观察到一系列的信息:

execve("/usr/bin/python3", ["python3"], 0x560af13472f0 /* 21 vars */) = 0
brk(NULL)                       = 0xfcc000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=32091, ...}) = 0
mmap(NULL, 32091, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f718a1e3000
close(3)                        = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "177ELF2113>1 l"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=149520, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f718a1e1000
...
close(3)                        = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3

这些内容初看可能让人望而生畏,但我希望你能重点关注这一部分:openat(AT_FDCWD, "
/lib/x86_64-linux-gnu/libpthread.so.0" ...
。这里正在打开一个被称为pthread的 C 语言线程库,运行 Python 解释器时需要这个库。

自行验证:如果你想知道一个二进制文件在运行时需要加载哪些库,你可以使用ldd命令。下面展示的是我运行后的效果:

$ ldd /usr/bin/python3.9
    linux-vdso.so.1 (0x00007ffc2aad7000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2fd6554000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2fd654e000)
    libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f2fd6549000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f2fd6405000)
    libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f2fd63d6000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f2fd63b9000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2fd61e3000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f2fd6580000)

你可以看到,第一个列出的库就是
/lib/x86_64-linux-gnu/libpthread.so.0,这就是它被第一个加载的原因。

关于 LD_LIBRARY_PATH

说实话,我关于动态链接的理解还有些模糊,以下是我所了解的一些内容:

  • 动态链接发生在用户空间,我的系统上的动态链接器位于/lib64/ld-linux-x86-64.so.2. 如果你缺少动态链接器,可能会遇到一些奇怪的问题,比如这种奇怪的“文件未找到”错误
  • 动态链接器使用LD_LIBRARY_PATH环境变量来查找库

相关阅读