、任何一个C/C++程序,它的背后都是一套庞大的代码来进行支撑,以使得该程序能够正常运行。这套代码至少包括入口函数、及其依赖的函数所构成的函数集合。当然,它还应该包括各种标准函数(如字符串,数学运算等)的实。一般的程序运行过程如下:

1.操作系统创建进程后,把控制权交给程序的入口函数(gcc -e (_startEntryPoint)),这个函数往往是运行时库的某个入口函数,glibc的入口函数是_start,msvc(vc6.0)是mainCRTStartup

2.入口函数对运行库和程序运行环境进行初始化,包括堆、I/O、线程、全局变量构造函数(constructor)等。

3.调用MAIN函数,正式开始执行程序主体。

4.执行MAIN完毕,返回入口函数,进行清理工作,包括全局变量析构、堆销毁、关闭I/O等,然后进行系统调用结束进程

二、启动时库主要功能模块

1.启动与退出,包括入口函数及其依赖函数

2.标准函数

3.I/O功能的封装和实现,如提供PRINT

4.堆的封装和实现

5.调试支持等

三、程序详细运行过程

以下分析默认为windows静态链接过程

1.程序执行前装载器会把用户的参数和环境变量压入栈,接着操作系统把控制权交给mainCRTStartup入口函数。

用户的参数:对应int main(int argc, char **argv)

环境变量:系统公用数据,系统搜索路径等等

程序需要获取用户参数和环境变量均是从栈上获取,需要理解栈帧的概念

2.初始化和OS版本相关的全局变量

3.初始化堆,每个进程都有属于自己的堆。它是一次性从系统中申请一块比较大的虚拟空间(实际需要时(如malloc)才会映射到物理页),以后在进程中由库的堆管理算法来维护这个堆。当堆不够用时再继续申请一块大的虚拟空间继续分配。可见,并非程序每次malloc都会调用系统API(API调用比较耗时,涉及到用户态到内核态的上下文切换),效率比较高。

堆相关操作:

HeapCreate:创建一个堆,最终会调用virtualAlloc()系统API函数去创建堆。

HeapAlloc:malloc会调用该函数

HeapFree:free会调用该函数

HeapDestroy:摧毁一个堆

4.I/O初始化,继承父进程打开文件表。可见,子进程是可以访问父进程打开的文件。如果父进程没有打开标准的输入输出,该进程会初始化标准输入输出。即初始化一下指针变量:stdin,stdout,stderr。他们都是FILE类型指针。在linux和windows中,打开文件对应于操作一个内核对象,其处于内核态,因此用户态是不能直接操作该内核对象的。用户只能操作与内核对象相关联的FILE结构指针。对应关系是:

printf其实是调用stdout指针在屏幕上输出 #define printf(args...) fprintf(stdout, ##args) Args...表示变长输入参数。用以下四个宏根据栈来获取。Va_list,Va_start,Va_arg,Va_end

5.获取命令行参数和环境变量

6.初始化C库的一些数据

7.全局变量构造,如各个全局类对象的构造函数调用和标记__attribute__((constructor))属性的各个函数。它们都应该在进入main前进行调用。

需要调用运行时库和C/C++编译器、连接器的配合才能实现这个功能

1)编译器编译某个.cpp(设为main.cpp)文件时,会将所有的构造函数实现作为一个整体放到.init段,把析构函数实现放到.finit段,然后在,ctors段放置.init段的地址(该地址即是该文件的各个构造函数的总入口)。

2)运行时库有一个库是crtbegin.o,它的.ctors段放置的内容为-1,ctrend.o,她的.ctors段放置的内容也是-1。

3)用链接器进行连接:ld crtbegin.o main.o crtend.o 一定要按这种顺序,否则出错。链接后的.ELF文件是将以上各个文件的.init/.finit/.ctors等段分别合并。当然.data/.text段也会相应合并。

全局变量构造时即是遍历.ctors段的内容,从-1(crtbegin.o)开始,再到-1(crtend.o)结束,中间每四个字节即是各个文件的构造入口函数指针,如果非0,即进行调用

8.注册析构函数

为了支持C++类的析构函数,和标记__attribute__((destructor))属性的各个函数在main之后会被调用,而且是按构造的相反顺序进行调用的,同样需要编译器以及运行时库的支持,原理跟构造相仿。只是为了逆序,使用了atexit注册各个函数,注册时在链表头插入连接,main退出以后也是从链表头开始获取链表函数,并进行调用

9.执行函数主体

调用main函数执行,等待返回。在这里可以用到之前已经初始化的各种资源,如I/O,堆,申请释放等等

10.调用析构函数

11.释放堆

12.释放其它资源

13.调用exit系统API退出进程

转自:http://www.cnblogs.com/yueqian-scut/p/3952263.html

C++运行时候库操作概述和整个程序运行流程相关推荐

  1. python 程序运行计时 动态_python中time库clock 使用Python,实现程序运行计时的数码管表示...

    python编程中time模块下的clock()函数怎么用?pr想起现在的孩子在玩荡秋千回想小编们的第一次.高高兴兴的荡秋千.多久都不累 python编程中time模块下的clock()函数怎么用?在 ...

  2. win7 安装运行时库失败,不更新操作系统运行编写的程序

    1.vs2015 编写的程序在客户机上发布的时候,经常出现安装vc_redist.x86.exe  但是有的操作系统安装不上. 2. 查看日志是因为 Windows6.1-KB2999226-x64. ...

  3. Python携库一并打包(打包pyecharts程序运行报错的解决方法)

    python正常打包,我们只需要在Terminal里输入 pyinstaller -F +项目 即可,如下图 但是呢,有一天我的新项目里 添加了pyecharts这个库,但是打包后,发现用不了.总是报 ...

  4. java 运行批处理文件_如何从Java应用程序运行批处理文件?

    在我的Java应用程序中,我想运行一个调用"scons -Q implicit-deps-changed build\file_load_type export\file_load_type ...

  5. android应用程序运行不了版本号,我的应用程序运行良好,除了Android 9版本。我无法理解什么是问题...

    我是Android的新手.我有一个应用程序,除了android 9(Pie)以外,所有设备都运行良好. 当试图打开这个应用程序时,它崩溃了. 这是我的gradle和代码; public class T ...

  6. 如何设置计划任务程序 每6小时运行一次_如何使win10系统运行的更快?

    微软推出的新操作系统Windows 10越来越受到欢迎,用户越来越多,大家是不是会有这样的感觉:同一款电脑,同样的配置,为什么有的人的电脑用起来非常的流畅,而有的人就连打开个网页都卡的要命:有的人的电 ...

  7. debug —— set args调试命令(作为程序运行时的参数)

    debug调试 -- set  args 作为程序运行时候的参数 set args作为程序运行时参数: 源代码: 1 #include <stdio.h>2 int main(int ar ...

  8. python显示运行时间_python程序运行进程、使用时间、剩余时间显示功能的实现代码...

    有很多程序运行时间比较长,如果不将运行过程输出将很难判断程序运行的时间.下边这段程序将按照上图所示的格式输出程序运行进程.已用时间.剩余时间. def time_change(time_init): ...

  9. mfc140dll 丢失 微软常用运行库_集成最新运行库、一键安装、一键到位,运行库操作简单!...

    背景有很多童鞋在安装诸如PS.vc++等软件总会提示缺少关键组件或者运行框架,也有在后台问我的,所以今天就给大家分享一下一些电脑安装软软件或者游戏常用的运行库,号主找了一些并且写了批处理直接运行就可以 ...

最新文章

  1. mysql存储过程不常用_Python--day46--mysql存储过程(不常用)(包含防sql注入)
  2. 谈谈我理解的文化包容性
  3. 制作根文件系统出现错误:No init found
  4. 高并发Web服务的演变:节约系统内存和CPU
  5. LeetCode 5832. 构造元素不等于两相邻元素平均值的数组
  6. OllyDbg笔记-软件逆向调试技巧
  7. 57 MM配置-评估和科目设置-物料类型与账户分类参考对应关系
  8. Django 数据库建表的时候 No migrations to apply原因出现和解决
  9. 【MySQL】MySQL 如何查看sql语句执行时间和效率
  10. 2018年计算机职称考试冲刺,2018年中级会计职称考试冲刺阶段学习计划
  11. mysql 存储过程代码_mysql存储过程语法与实例
  12. 浅谈sql之连接查询
  13. 计算机字符编码从0/1到UTF-8
  14. EastFax USB SERVER推动天润集团U盾管理提效升级
  15. 在桌面计算机找不到光盘驱动,如何弹出DVD驱动器,没有按钮,我在计算机中找不到DVD驱动器...
  16. Linux与Windows命令行杀死端口命令
  17. 《智慧彼岸之定心经》
  18. linux 鼠标卡顿,树莓派鼠标延迟以及其它问题汇总
  19. 3D模型在线云转换和在线展示
  20. 中兴通信亮相文博会,5G创新变革

热门文章

  1. 如何用catia画半圆_简笔画用半圆画卡通动物
  2. pandas中的DataFrame数据结构
  3. i2c Linux 动态 波特率,如何在Linux中设置i2c总线的波特率?
  4. 使用JBoss Modules来模块化Java
  5. 彻底解决Git中文乱码问题
  6. 160家优秀国外技术公司博客
  7. java设计模式2--抽象工厂模式(Abstract Factory)
  8. 程序员面试题精选100题(29)-调整数组顺序使奇数位于偶数前面[算法]
  9. C++实用技巧(三)
  10. Day 25: 联合Tornado、MongoDB 和 AngularJS 进行应用开发