IT袋

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

Linux

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

时间:2023-09-17 20:02:06 来源:IT袋 作者:苏晓敏
导读:Linux,动态链接器也会使用 LD_PRELOAD 环境变量来覆盖你想要的任何动态链接函数(你可以使用它来进行有趣的魔改,或者使用像 jemalloc 这样的替代品来替换默认

Linux

  • 动态链接器也会使用LD_PRELOAD环境变量来覆盖你想要的任何动态链接函数(你可以使用它来进行有趣的魔改,或者使用像 jemalloc 这样的替代品来替换默认内存分配器)
  • strace的输出中有一些mprotect,因为安全原因将库代码标记为只读
  • 在 Mac 上,不是使用LD_LIBRARY_PATH(Linux),而是DYLD_LIBRARY_PATH
  • 你可能会有疑问,如果动态链接发生在用户空间,我们为什么没有看到大量的stat系统调用在LD_LIBRARY_PATH中搜索这些库,就像 Bash 在PATH中搜索那样?

    这是因为ld/etc/ld.so.cache中有一个缓存,因此所有之前已经找到的库都会被记录在这里。你可以在strace的输出中看到它正在打开缓存 –openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3

    在 完整的 strace 输出中,我仍然对动态链接之后出现的一些系统调用感到困惑(什么是prlimit64?本地环境的内容是如何介入的?gconv-modules.cache是什么?rt_sigaction做了什么?arch_prctl是什么?以及set_tid_addressset_robust_list是什么?)。尽管如此,我觉得已经有了一个不错的开头。

    旁注:ldd 实际上是一个简单的 Shell 脚本!

    在 Mastodon 上,有人 指出,ldd实际上是一个 Shell 脚本,它设置了LD_TRACE_LOADED_OBJECTS=1环境变量,然后启动程序。因此,你也可以通过以下方式实现相同的功能:

    $ LD_TRACE_LOADED_OBJECTS=1 python3
        linux-vdso.so.1 (0x00007ffe13b0a000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f01a5a47000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f01a5a41000)
        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)
    

    事实上,ld也是一个可以直接运行的二进制文件,所以你也可以通过
    /lib64/ld-linux-x86-64.so.2 --list /usr/bin/python3.9来达到相同的效果。

    关于 init 和 fini

    让我们来谈谈这行strace输出中的内容:

    set_tid_address(0x7f58880dca10) = 3709103
    

    这似乎与线程有关,我认为这可能是因为pthread库(以及所有其他动态加载的库)在加载时得以运行初始化代码。在库加载时运行的代码位于

    相关阅读