Linux下main函数启动过程【程序员自我修养笔记】【自用】
1. 入口函数和程序初始化
1.1 程序从main开始吗?
当程序执行到main函数的第一行时,很多事情都已经完成了:
【证1】如下是一段C语言代码:

代码中可以看到,在程序刚刚执行到main的时候,全局变量的初始化过程已经结束了(a的值已经确定);
main函数的两个参数(argc 和 argv)也被正确的传了进来;
此外,堆和栈的初始化 已经完成;
- 一些 系统I/O 也被初始化了,因此,可以放心的使用printf和malloc。
【证2】如下是一段C++ 代码,main之前能够执行的代码还会更多,如下:

在这里,对象v的构造函数,以及用于初始化全局变量g的函数foo都会在main之前调用。
用于初始化全局变量g的函数:
#include <iostream>
using namespace std; int foo()
{
cout << "这个是用来初始化全局变量的函数" << endl;
return ;
} int g = foo(); int main()
{
cout << "这是main函数中第一条语句" << endl; cout << "main函数中直接输出g: " << g << endl; cout << "这是main函数中最后一条语句" << endl; return ;
}

作为全局变量的对象的构造函数:
#include <iostream>
using namespace std;
class MyString {
private :
int len;
public:
MyString(int t = ) : len(t) { cout << "默认构造函数" << t << endl; }
int getLen() {
return len;
}
~MyString() { cout << "析构函数调用" << len << endl; }
};
MyString t();
int main()
{
cout << "这是主函数里面的第一行语句\n";
MyString a();
cout << "这是主函数里最后一行语句\n";
return ;
}

【证3】atexit:特殊的函数,接收一个函数指针作为参数,并保证在程序正常退出(指从main里返回或调用exit函数时),这个函数指针指向的函数会被调用。如:


- atexit函数注册的函数的调用时机是在 main结束之后
- 在main返回之后,它会记录main函数的返回值,调用atexit注册的函数,然后结束进程。
由这些可以看出,首先运行的代码并不是main的第一行,而是某些特别的代码,这些代码负责准备好main函数执行需要的环境。
由此可知,程序的入口点实际上是一个 程序的初始化和结束部分,它往往是库的的一部分。
1.2 main函数形式
(1) Linux下常见的main函数形式:
- int main(int argc, char *argv[])
- int main(int argc, char **argv)
(2)其他形式:
- int main()
- int main(int argc, char **argv, char **envp)
(3) main函数的参数:
- argc:命令行参数的个数(包括最开始的可执行文件名称)
- argv:字符指针的数组,每个元素都是一个指向字符串的字符指针,即命令行中的每一个参数;命令行参数的列表,数组长度对应argc
- envp:字符指针的数组,每一个元素是 指向一个环境变量的字符指针; 它里面存放了当前系统的所有环境变量,环境变量指的是一大组字符串,代表系统开始运行时加载一些东西


3. 分析Linux操作系统如何装载链接并执行程序
尽量描述简单,不讲源码,先看如下的图:

Linux程序加载过程如图:

4. 总结
简短的说,整个在shell中键入./test执行应用程序的过程为:
当前shell进程fork出一个子进程(子shell)
子进程使用execve来脱离和父进程的关系,加载test文件(ELF格式)到内存中。
如果test使用了动态链接库,就需要加载动态链接器(或者叫程序解释器),进一步加载test使用到的动态链接库到内存,并重定位以供test调用。
最后从test的入口地址开始执行test。
Linux下main函数启动过程【程序员自我修养笔记】【自用】的更多相关文章
- [oracle] oracle的三种密码验证机制以及在windows和linux下的不同启动过程
oracle数据库的密码验证机制: ① 操作系统验证 拥有SYSDBA和SYSOPER的用户用该方式验证此时数据库无需启动,也无需开启监听和实例服务. 要求:本地组ora_dba中有该操作系统的登录用 ...
- linux编程之main()函数启动过程【转】
转自:http://blog.csdn.net/gary_ygl/article/details/8506007 1 最简单的程序 1)编辑helloworld程序,$vim helloworld. ...
- pwn学习日记Day10 《程序员自我修养》读书笔记
第一章 从 Hello world 说起 抛出问题: 1.程序为什么要被编译器编译后才能执行? 2.编译器在把C语言程序转换成可以执行的机器码的过程中做了什么,怎么做的? 3.最后编译出来的可执行文件 ...
- ***IT程序员自我修养和情商提升文章
低情商的13个表现 --------------------------------------------------------------------- — THE END —
- Linux移植之内核启动过程start_kernel函数简析
在Linux移植之内核启动过程引导阶段分析中从arch/arm/kernel/head.S开始分析,最后分析到课start_kernel这个C函数,下面就简单分析下这个函数,因为涉及到Linux的内容 ...
- 对于linux下system()函数的深度理解(整理)
原谅: http://blog.sina.com.cn/s/blog_8043547601017qk0.html 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同 ...
- 转:对于linux下system()函数的深度理解(整理)
这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...
- (笔记)Linux下system()函数的深度理解(整理)
注:从其它地方转的非常好的一篇文章,值得深究! 这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数 ...
- Linux下使用vim编辑C程序
这几天在系统能力班自学linux,加上最近大数据课上开始使用linux,我在这里总结一下,linux下使用vim编辑c程序的一些问题. 大数据课上是直接使用micro来编辑的,我这里只是简单的说明一下 ...
随机推荐
- tp5命令行基础介绍
查看指令 生成模块 生成文件 生成类库映射文件 生成路由缓存文件 生成数据表字段缓存文件 指令扩展示例 命令行调试 命令行颜色支持 调用命令 查看指令 命令行工具需要在命令行下面执行,请先确保你的ph ...
- 【bfs】拯救少林神棍(poj1011)
Description 乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过50个长度单位.然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度.请你 ...
- Apache rewrite地址重写
Apache-rewrite+13个经典案例Apache 重写规则的常见应用(rewrite)一:目的 如何用Apache重写规则来解决一些常见的URL重写方法的问题,通过常见的 实例给用户一些使用重 ...
- Python数据结构之栈的实现
一图胜千言,看图! 代码code: #coding:utf-8 #常见数据结构之栈的实现 class Stack(): #创建Stack类 def __init__(st,size): st.stac ...
- 51Nod--1117 聪明的木匠(排序)
我们可以反过来想,如何将这几个线段组成一根 并且每次花费是组成的两段的和 #include<bits/stdc++.h> using namespace std; #define maxn ...
- Linux下使用pv监控进度
使用pv移动文件 pv example.mkv > /tmp/example.mkv 使用pv监控dd pv -cN source < example.iso | dd of=/dev/s ...
- WebClient请求接口,get和post方法
1,get方式 string URI = "url"; //实例化 WebClient client = new WebClient(); // client.UseDefault ...
- 认识Jmeter工具
1.Apache jmeter 是一个100%的纯java桌面应用,是Apache组织开发的基于java的压力测试工具.它最初被设计用于Web应用测试但后来扩展到其他测试领域,可以用于对静态的和动态的 ...
- Ubuntu下安装Goldendict(翻译软件)
Ubuntu直接安装 sudo apt-get install goldendict 通过源码安装 失败 下载词典 http://blog.sina.com.cn/s/blog_c58823b3010 ...
- C++基础知识--DAY4
今天主要讲的是类中除了构造器析构器以外的拷贝构造器,运算符重载等问题 首先是拷贝构造器 1. copy constructor(拷贝构造) 其也是构造器,其地位和constructor的地位是一样的 ...