什么是__libc_start_main和_start? [英] What is __libc_start_main and _start?

查看:164
本文介绍了什么是__libc_start_main和_start?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去几天,我一直在尝试了解执行C程序时幕后发生的事情.但是,即使阅读了许多文章,我也无法找到详细而准确的解释.有人可以帮我吗?

From the past few days I have been trying to understand what happens behind the curtain when we execute a C program. However even after reading numerous posts I cannot find a detailed and accurate explanation for the same. Can someone please help me out ?

推荐答案

在编译和链接程序时,通常会找到这样的特殊名称以用于特定用途.

You would usually find special names like this for specific uses when compiling and linking programs.

通常,像 _start 这样的东西将是可执行文件的 actual 入口点,它将位于某个目标文件或库中(例如

Typically, something like _start would be the actual entry point for an executable, it will be located in some object file or library (like crt0.o for the C runtime start-up code) - this would normally be added automagically to your executable file by the linker, similar to the way the C runtime library is added(a).

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

The operating system code for starting a program would then be akin to (pseudo-code, obviously, and with much less error checking than it should have):

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启动代码的内容将与(最简单的)类似:

Even though you yourself create a main when coding in C, that's not really where things start happening. There's a whole slew of things that need to be done even before your main program starts. Hence the content of the C start-up code would be along the lines of (at its most simplistic):

_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程序做好准备所需的一切.可能包括以下内容:

The "weaving of magic" is whatever it takes to make the environment ready for a C program. This may include things like:

  • 设置静态数据(应该初始化为零,因此它可能只是一块内存的分配,然后由启动代码将其清零-否则,您需要存储其中的一部分可执行文件中已为零的大小);
  • 在堆栈上准备 argc argv ,甚至准备堆栈本身(有可能用于C的特定调用约定,并且很可能是操作系统调用 _start 时并不一定要完全设置堆栈 ,因为该过程的需求尚不清楚);
  • 设置特定于线程的数据结构(每个线程类似随机数生成器或错误变量之类的东西);
  • 以其他方式初始化C库;等等.
  • setting up static data (this is supposed to be initialised to zeros so it's probably just an allocation of a chunk of of memory, which is then zeroed by the start-up code - otherwise you would need to store a chunk of that size, already zeroed, in the executable file);
  • preparing argc and argv on the stack, and even preparing the stack itself (there are specific calling conventions that may be used for C, and it's likely the operating system doesn't necessarily set up the stack at all when calling _start since the needs of the process are not known);
  • setting up thread-specific data structures (things like random number generators, or error variables, per thread);
  • initialising the C library in other ways; and so on.

只有完成所有操作后,才能调用您的 main 函数.还有可能需要在 main 退出后 完成工作,例如:

Only once all that is complete will it be okay to call your main function. There's also the likelihood that work needs to be done after your main exits, such as:

  • 调用 atexit 处理程序(无论退出在何处,您都希望在退出时自动运行的内容);
  • 从共享资源中分离(例如,如果操作系统在关闭进程时没有自动执行此操作,则从共享内存中分离);和
  • 释放进程退出时未自动清除的其他所有资源,否则这些资源将继续闲逛.
  • invoking atexit handlers (things you want run automatically on exit, no matter where the exit occurs);
  • detaching from shared resources (for example, shared memory if the OS doesn't do this automatically when it shuts down a process); and
  • freeing up any other resources not automatically cleaned when the process exits, that would otherwise hang around.

(a)例如,如果您编写的是不使用标准C库的内容,则可以告诉许多链接程序这样做如果您想为低级工作提供自己的 _start 例程.

(a) Many linkers can be told to not do that if, for example, you're writing something that doesn't use the standard C library, or if you want to provide your own _start routine for low-level work.

这篇关于什么是__libc_start_main和_start?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆