来自 https://mp.weixin.qq.com/s/qg1mFzMEYv7GDDM72H1DOQ  操作系统学习

1. 什么是CRT

crt是C run-time library的简称,称为C运行时库,它诞生于20世纪70年代,是程序在运行时所需要的库文件,属于C语言世界的概念。

C语言是由贝尔实验室的Dennis Ritchie从1969年到1973年开发的。1973年,Ken Thompson和Ritchie使用C语言重写了90%以上的UNIX系统函数,并且把其中最常用的部分独立出来,形成头文件和对应的LIBRARY,C运行时库就这样形成的。

随着C语言的流行,各个C编译器的生产商/个体/团体都遵循老的传统,在不同平台上都有相对应的Standard Library,但大部分实现都是与各个平台有关的。由于各个C编译器对C的支持和理解有很多分歧和微妙的差别,所以就有了ANSI C。ANSI C(主观意图上)详细的规定了C语言各个要素的具体含义和编译器实现要求,引进了新的函数声明方式,同时订立了StandardLibrary的标准形式。所以C运行时库由编译器生产商提供,至于由其他厂商/个人/团体提供的头文件和库函数,应当称为第三方C运行库(Third party C run-time libraries)。

Glibc(The GNU C Library)是GNU发布的libc库,即C运行库。Glibc是Linux系统中最底层的API,几乎其它任何运行库都会依赖于glibc。Glibc除了封装Linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于glibc囊括了几乎所有的UNIX通行的标准,可以想见其内容包罗万象。而就像其他的UNIX系统一样,其内含的档案群分散于系统的树状目录结构中,像一个支架一般撑起整个操作系统。在 GNU/Linux系统中,其C函数库发展史点出了GNU/Linux演进的几个重要里程碑,用glibc作为系统的C函数库,是GNU/Linux演进的一个重要里程碑。

Glibc有几个辅助程序运行的运行库,分别是/usr/lib/crt1.o、/usr/lib/crti.o和/usr/lib/crtn.o,这些目标文件的作用分别是启动、初始化和结束,它们通常会被自动链接到应用程序中。其中crt1.o中包含程序的入口函数_start以及两个未定义的符号__libc_start_mainmain,由_start负责调用__libc_start_main初始化libc,然后调用应用程序中定义的main函数。由于类似于全局静态对象这样的代码需要在main函数之前执行,crti.ocrtn.o负责辅助启动这些代码。同样,在gcc中还有crtbegin.o和crtend.o这两个目标程序用于配合glibc来实现C++的全局构造和析构。

注:crt1.o是crt0.o的后续演进版本。

crt1.o中有非常重要的.init段、.fini段以及_start函数的入口。.init段和.fini段实际上是靠crti.o以及crtn.o来实现的,.init段是main函数之前的初始化工作代码, 比如全局变量的构造。.fini段则负责main函数之后的清理工作。

2. 举例说明

将源程序hello.c在Linux环境下按下面步骤编译运行。

编译为.o

gcc -c -o test.o test.c

链接:

ld -dynamic-linker/lib64/ld-linux-x86-64.so.2 -o hello /usr/lib64/crt1.o /usr/lib64/crti.o/usr/lib64/crtn.o hello.o  -lc

运行:./hello

如果在链接时不选择crt1.o,则链接错,找不到_start。

如果在链接时不选择crti.o,则在函数__libc_csu_init中找不到_init,链接错。

如果在链接时不选择crtn.o ,链接通过,但执行时出现“Segmentation fault (core dumped)”错。

如果在链接时不选择hello.o ,出现错误,在crt1.o中函数_start找不到main。

如果在链接时不选择-lc,即c库,libc,链接错误,找不到__libc_start_main 等参数。

总结:在crt1.o中,包含有代码的运行入口_start,程序进入_start后进行初始化后会调用main,而main在crt1.o中未定义,它是在hello.o中定义,由此可见,main主函数的执行是由于_start的调用而引起的。crt1.o还有未定义符号__libc_start_main .__libc_csu_...等,这些符号是在libc中定义的。libc并不像其它目标文件一样链接到可执行文件main中,而是在运行时做动态链接的。

crt1.o的前身叫crt0.o, 它的作用是作为连接的首个模块。为了实现C++的全局构造和析构。改进crt0.o 为crt1.o。运行库引入了.init和.finit段,.init在main函数前运行,.finit在main函数后运行。链接器将所有目标文件的init段和finit段合并,并产生两个函数:_init()和_finit()。.init段,.finit段所需要的一些辅助代码,分别位于crti.o和crtn.o。

程序的执行始于crti.o,终止于crtn.o,中间才是真正程序的运行。简单描述如下:

_start函数调用__libc_start_main函数

__libc_start_main调用__libc_csu_init, main,__libc_csu_fini函数。

__libc_csu_init, 负责调用_init()

__libc_csu_fini, 负责调用_finit()

参考资料: 

[1] https://www.cnblogs.com/iTeck/p/4159202.html

[2] https://blog.csdn.net/hejinjing_tom_com/article/details/32325749

CRT (C run-time library)简介相关推荐

  1. CRT(C Runtime Library)—— C/C++运行时库

    C runtime library(part of the C standard library) 任何一个 C 程序,它的背后都有一套庞大的代码来进行支撑,使得该程序得以运行在更高级别上,而不必担心 ...

  2. Cannot run program /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java

    Cannot run program "/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin/java&qu ...

  3. Big Faceless Java PDF Viewer library简介

    虽然BFO的东西不是开源的,但的确是一种不错的解决方案. 详情见 Big Faceless Org 慧都控件网 BFO提供了三种产品: 1.Java Report Geneator     Big F ...

  4. Microsoft Enterprise Library 简介与请大家下载Microsoft Enterprise Library 5.0体验微软最新技术应用于企业信息平台

    什么是Enterprise Library     Enterprise Library是一组应用程序块(Application Block)的集合.他们是可重用的软件组件,被设计用来帮助开发者面对常 ...

  5. 带你玩转Visual Studio(八)——带你跳出坑爹的Runtime Library坑

    在Windows下进行C++的开发,不可避免的要与Windows的底层库进行交互,然而VS下的一项设置MT.MTd.MD和MDd却经常让人搞迷糊,相信不少人都被他坑过,特别是你工程使用了很多第三库的时 ...

  6. 一文带你弄懂Visual Studio:运行时库及MT/MTD、MD/MDD

    一文带你弄懂Visual Studio:运行时库及MT/MTD.MD/MDD 引子 什么是Runtime Library? Runtime Library和运行库 MT MTD MD MDD的关系 静 ...

  7. MSVC编译链接问题

    LNK4098: 默认库"MSVCRT"与其他库的使用冲突 修改的方法:在项目属性中,在连接器-输入选项中,在忽略特定库中添加相应的库,具体添加那些苦请参照下面的表格. 下面的内容 ...

  8. Enterprise Library 4.0简介及改进

    Enterprise Library简介 Enterprise Library 4.0 – May 2008是Microsoft patterns & practices Enterprise ...

  9. C语言标准及C标准库、运行时库简介

    1.C语言标准: 1978 年,Dennis Ritchie 和 Brian Kernighan 合作推出了<The C Programming Language>的第一版(著作简称为 K ...

最新文章

  1. idea上java接口自动化_Java接口自动化之IDEA创建及运行maven项目
  2. C# DateTime 日期加1天 减一天 加一月 减一月 等方法(转)
  3. 判断一颗二叉树是否是平衡二叉树
  4. python画图的模块_python强大的绘图模块matplotlib示例讲解
  5. Linux编程——入门级Makefile文件编写
  6. oracle实列关闭,Oracle单实例+ASM启动与关闭
  7. 文本监控 :oninput onchange onpropertychange 的区别
  8. leetcode 509. 斐波那契数
  9. 内卷的世界,我们是否可以换一种思维生活?
  10. Linux环境编程导引
  11. 文件比较命令:comm
  12. 关于assert和de-assert的解释
  13. 【整理操作】MQTT简单使用学习
  14. Windows Phone 开发【MSDN参考文档 目录】
  15. java调用webservice接口 几种方法
  16. SSM框架运行原理以及流程
  17. 两个自变量和一个因变量spss_两个自变量(离散)对一个因变量(连续)的影响(SPSS:双因素方差分析)...
  18. CF833D Red-Black Cobweb 点分治、树状数组
  19. HPUoj1210: OY问题 [搜索](DFS
  20. Python OpenCv 车牌检测识别(边缘检测、HSV色彩空间判断)

热门文章

  1. Jenkins --- 三种安装方式
  2. 如何跑通平头哥RISC-V E902的仿真验证
  3. 【java笔记-006】【uni-app】当前运行的基座不包含原生插件[xxx],请在manifest中配置该插件,重新制作包括该原生插件的自定义运行基座
  4. 2020中南大学研究生招生夏令营机试题
  5. 计算机上如何配置扫描设置,在 MF Toolbox 中配置扫描设置
  6. python用matplotlib画五角星_绘图:Matplotlib
  7. 【POJ】1819.Disks
  8. 5分绩点转4分_4分绩点与百分制转换方法
  9. github fatal: Authentication failed for解决方法
  10. python中fill函数_在figu中旋转matplotlib的fill函数