Linux 下“Hello World”的幕后发生了什么(8)
Linux
init区域(或者也可能是.ctors区域)。
自行验证:让我们使用readelf来看看这个:
$ readelf -a /lib/x86_64-linux-gnu/libpthread.so.0
...
[10] .rela.plt RELA 00000000000051f0 000051f0
00000000000007f8 0000000000000018 AI 4 26 8
[11] .init PROGBITS 0000000000006000 00006000
000000000000000e 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 0000000000006010 00006010
0000000000000560 0000000000000010 AX 0 0 16
...
这个库没有.ctors区域,只有一个.init。但是,.init区域都有些什么内容呢?我们可以使用objdump来反汇编这段代码:$ objdump -d /lib/x86_64-linux-gnu/libpthread.so.0 Disassembly of section .init: 0000000000006000
所以它在调用
__pthread_initialize_minimal。我在 glibc 中找到了这个函数的代码,尽管我不得不找到一个较早版本的 glibc,因为在更近的版本中,libpthread不再是一个独立的库。
我不确定这个set_tid_address系统调用是否实际上来自
__pthread_initialize_minimal,但至少我们知道了库可以通过.init区域在启动时运行代码。
这里有一份关于 .init 区域的 elf 手册的笔记:
$ man elf
.init这个区域保存着对进程初始化代码有贡献的可执行指令。当程序开始运行时,系统会安排在调用主程序入口点之前执行该区域中的代码。
在 ELF 文件中也有一个在结束时运行的.fini区域,以及其他可以存在的区域.ctors/.dtors(构造器和析构器)。
好的,关于动态链接就说这么多。
9、转到 _start
在动态链接完成后,我们进入到 Python 解释器中的_start。然后,它将执行所有正常的 Python 解析器会做的事情。
我不打算深入讨论这个,因为我在这里关心的是关于如何在 Linux 上运行二进制文件的一般性知识,而不是特别针对 Python 解释器。
10、写入字符串
不过,我们仍然需要打印出 “hello world”。在底层,Python 的print函数调用了 libc 中的某个函数。但是,它调用了哪一个呢?让我们来找出答案!
自行验证:运行ltrace -o out python3 hello.py:
$ ltrace -o out python3 hello.py
$ grep hello out
write(1, "hello worldn", 12) = 12
看起来它确实在调用write函数。
我必须承认,我对ltrace总是有一些疑虑 —— 与我深信不疑的
相关阅读
-
win11字体安装位置详细介绍 windows11字体怎么安装
为网友们详解win11字体安装位置详细介绍方面的知识,关于win11字体安装位置详细介绍 windows11字体怎么安装,下面为详细的介绍。 有一些小伙伴在安装win11字体后,找不到自己的字体安装在哪里
-
win10开机进不了系统怎么办 重装系统不停重启教程
小编为大家说一说win10开机进不了系统怎么办和重装系统不停重启教程的介绍,接下来小编为网友介绍。 在日常使用电脑的过程中,我们有时候会遇到电脑开机后进不了系统的情况,这是令人
-
游戏分辨率怎么调 英雄联盟游戏分辨率怎么调
本文导读:游戏分辨率怎么调的方法内容,关于游戏分辨率怎么调 英雄联盟游戏分辨率怎么调,接下来一起来看看吧。 最近不少的IT袋用户问分辨率是不是越高越好,其实不然,分辨率高并不
-
win10怎么设置屏幕不休眠 win10怎么关闭屏幕不休眠
今天介绍win10怎么设置屏幕不休眠的相关知识,win10设置屏幕不休眠共三步,只需在电脑睡眠设置中进行操作即可。具体步骤如下:


