繁体   English   中英

__libc_start_main 和 _start 是什么?

[英]What is __libc_start_main and _start?

从过去几天开始,我一直试图了解当我们执行 C 程序时幕后会发生什么。 但是,即使在阅读了许多帖子之后,我也找不到详细而准确的解释。 有人可以帮我吗?

在编译和链接程序时,您通常会为特定用途找到像这样的特殊名称。

通常,像_start这样的东西是可执行文件的实际入口点,它将位于某些 object 文件或库中(如 C 运行时启动代码的crt0.o ) - 这通常会自动添加到您的可执行文件中通过 linker,类似于添加 C 运行时库的方式(a)

用于启动程序的操作系统代码将类似于(显然是伪代码,并且错误检查比应有的少得多):

def spawnProg(progName):
    id = newProcess()                       # make process address space
    loadProgram(pid = id, file = progName)  # load program into it
    newThread(pid, initialPc = '_start')    # make new thread to run it

即使您在 C 中编码时自己创建了一个main ,但这并不是事情真正开始发生的地方。 甚至在您的主程序启动之前,还有很多事情需要完成。 因此,C 启动代码的内容将类似于(最简单的):

_start:  ;; Weave magic here to set up C and libc.

         call __setup_for_c       ; set up C environment
         call __libc_start_main   ; set up standard library
         call _main               ; call your main
         call __libc_stop_main    ; tear down standard library
         call __teardown_for_c    ; tear down C environment
         jmp  __exit              ; return to OS

“魔法编织”是使环境为 C 程序做好准备所需的一切。 可能包括以下内容:

  • 设置 static 数据(这应该被初始化为零,所以它可能只是 memory 的一个块的分配,然后由启动代码归零 - 否则你需要存储一个该大小的块,已经归零,在可执行文件中);
  • 在堆栈上准备argcargv ,甚至准备堆栈本身(有可能用于 C 的特定调用约定,并且很可能操作系统在调用_start时根本不需要设置堆栈因为需要过程未知);
  • 设置线程特定的数据结构(每个线程的随机数生成器或错误变量);
  • 以其他方式初始化C库; 等等。

只有在所有这些都完成后,才能调用您的main function。 也有可能在您的main退出需要完成工作,例如:

  • 调用atexit处理程序(您希望在退出时自动运行的事情,无论退出发生在哪里);
  • 从共享资源中分离(例如,如果操作系统在关闭进程时没有自动执行此操作,则为共享 memory);
  • 释放进程退出时未自动清理的任何其他资源,否则会挂起。

(a)如果您正在编写不使用标准 C 库的东西,或者如果您想为低级工作提供自己的_start例程,则可以告诉许多链接器要这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM