程序在 main 函数前执行了什么

Tags
C语言
ID
56
 
💡
TL;DR 1. 初始化内存空间 2. 载入动态库 3. 初始化全局变量
notion image
如果用 gdb 调试一个 C 程序,可以发现函数调用栈的栈底不是 main,而是 _start_start 调用了 __libc_start_main_impl 函数,这个函数有 main,argc,argv,init,fini,rtld_finistack_end 参数,其中上面下划线的是回调函数指针, init 函数中做了初始化相关的工作,比如内存申请,动态库载入,全局变量初始化,而 fini 主要是 atexit 函数的调用,rtld_fini 主要是卸载动态库(就如名字 runtime ld)。
💡
动态库不是共享的吗?为什么需要载入到内存? 因为程序只能访问自己的用户空间,所以只能映射过来。在老版的 Linux 中,它的地址是 0x4000 0000 开始的一块空间,位于堆内存的内部(新版 Linux 内核修改了位置)。