任何了解程序如何加载到内存并执行的实践练习
题
我很好奇在调用 main() 之前发生的事情,例如将可执行文件加载到内存中,动态加载共享库。您对如何通过动手练习来理解这些事情有什么建议吗?
我所知道和现在使用的工具和东西包括:
- 斯特雷斯
- 拆卸
- 雷德尔夫
- /proc/pid/地图
笔记:我知道这本伟大的书 链接器和加载器, ,但是实践练习可能比阅读书本更能教会我。
解决方案
- ld.so 手册页 记录了几个可以设置为调整动态链接过程或提供其他详细信息的环境变量。
例如
LD_DEBUG=all cat </dev/null
- 您可以轻松获取所涉及的每个部分的源代码 - Linux 内核、动态链接器、C 库、启动代码(crt0.o 或类似代码)。您可以从研究代码并进行实验性修改开始。
其他提示
如果您想检查二进制文件的打包方式及其不同部分,我认为最好的程序是 对象转储.
选择任何可执行文件并执行以下操作:
objdump -S <executable> > myfile.S
另一个好的练习是:
- 创建使用外部库的程序
- 使用静态链接编译程序
- 运行程序
- 重命名库文件并检查程序是否运行
- 使用共享库编译程序
- 重命名库并检查程序是否运行
这将回答您关于幕后发生的事情以及如何发生的一些问题。
我发现了两个有趣的相关链接(至少对于 Linux)并且比提到的书(链接器和加载器)短一点
当我在大学上操作系统课程时,我们使用 玉米片. 。它不是一个操作系统 本身, ,而是一种在用户空间中运行的操作系统“模拟”。它是用 C++ 编写的,您可以交叉编译可执行文件,然后 Nachos 可以加载并运行这些可执行文件。您可以使用系统调用接口,并且通常可以通过摆弄代码来进行尽可能多的实验。
我们在 Solaris 实验室中运行它,我在我的个人计算机上的 Linux 上安装并运行它时遇到了一些麻烦,但如果您愿意深入研究一些代码,它可能是一个有趣的玩具。
我意识到对于您正在寻找的东西来说可能有很多,但是编写您自己的汇编器和链接器将非常有教育意义。我在大学时就这么做过并且很喜欢它。我记得大约花了 120 个小时才让它完成我想要它做的基本事情。我认为这个项目比其他任何事情都更让我确信编程职业适合我。
不隶属于 StackOverflow