当用 gcc 链接一个用 c(或 asm)编写的类似 hello-world 的程序时,它会将一些内容添加到结果可执行目标文件中。我只知道运行时动态链接器和 _start 入口点,但这些添加的函数是什么样的?
00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones
0000000000400470 t __do_global_dtors_aux
0000000000400490 t frame_dummy
00000000004004e0 T __libc_csu_init
0000000000400550 T __libc_csu_fini
0000000000400554 T _fini
0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end
它们是什么,有什么用?它在某处描述了吗?谷歌搜索没有帮助。
最佳答案
其中大部分是在“主”程序本身之前或之后执行代码的各种方法,大多数都在 crtstuff.c 中。 (https://github.com/gcc-mirror/gcc/blob/master/libgcc/crtstuff.c)。
它们的存在是为了支持各种类似 C 的编程语言的特性,但也可以在 C 中访问它们。它可能看起来过于复杂,因为其中一些代表了遗留包袱,而另一些代表了支持 GCC 运行的各种不同架构所需的变体。
从您的列表中,一个接一个(或两个接两个):
00000000004003f0 t deregister_tm_clones
0000000000400430 t register_tm_clones
事务内存旨在简化线程编程。 它是基于锁的同步的替代方法。 这些例程分别拆除和设置支持这些函数的库 (libitm) 使用的表。 有关 TM 的更多信息,请点击此处 https://gcc.gnu.org/wiki/TransactionalMemory在这里 http://pmarlier.free.fr/gcc-tm-tut.html
0000000000400470 t __do_global_dtors_aux
在 .fini_array 的系统上退出程序时运行所有全局析构函数不可用。
0000000000400490 t frame_dummy
此函数位于 .init 中部分。它被定义为 void frame_dummy ( void )它生命中的全部意义就是调用__register_frame_info_bases有论点。显然用 .init 中的参数调用函数部分可能不可靠,因此这个函数所以 __register_frame_info_bases不会直接从 .init section 调用.
.eh_frame信息库用于异常处理和类似功能(例如用 __attribute__((cleanup(..))) 声明的函数)。
00000000004004e0 T __libc_csu_init
0000000000400550 T __libc_csu_fini
这些运行任何程序级别的初始化器和终结器(有点像整个程序的构造函数/析构函数)。 如果您定义如下函数:
void __attribute__ ((constructor)) mefirst () {
/* ... do something here ... */
}
void __attribute__ ((destructor)) melast () {
/* ... do something here ... */
}
它们将在main()之前和之后被调用分别由这些例程。
另见 https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
0000000000400554 T _fini
这是一种现已弃用的运行程序级(实际上是目标文件级)析构函数的方法(有关此的一些信息可以在 man dlclose 中找到)。
构造函数的相应过时函数是 __init .
0000000000600668 t __frame_dummy_init_array_entry
0000000000600668 t __init_array_start
这些标记了 .init_array 的结束和开始部分,其中包含指向所有程序级初始化程序的指针(请参阅上面的 __libc_csu_init)。
0000000000600670 t __do_global_dtors_aux_fini_array_entry
0000000000600670 t __init_array_end
这些标记了 .fini_array 的结束和开始部分,其中包含指向所有程序级终结器的指针(参见上面的 __libc_csu_fini)。
[编辑]一些附加说明:
链接 http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html (wayback machine) 来自 Jester 的问题评论包含一个漂亮的图表和一个小样本 说明这些东西运行的总体顺序以及如何运行的程序 从 C 访问其中一些功能。
术语“ctors”和“dtors”是 分别为“构造函数”和“析构函数”。
全局构造函数/析构函数和对象文件的区别 当你的程序是 由多个目标文件构建。
标记为'T'的符号(__libc_csu_init, __libc_csu_fini, _fini) 是“全局的”(外部可见),其余部分(标记为“t”)不是。
关于c - gcc给linux ELF增加了哪些功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34966097/
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您
您认为可以作为插件很好地存在于您的Rails应用程序中必须实现的哪些行为?您过去曾搜索过哪些插件功能但找不到?哪些现有的Rails插件可以改进或扩展,如何改进或扩展? 最佳答案 我希望在管理界面中看到一个引擎插件,它提供了应用程序中所有模型的仪表板摘要,以及可配置的事件图表。 关于ruby-on-rails-您希望看到哪些Rails插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questio
在Rails自动生成的功能测试(test/functional/products_controller_test.rb)中,我看到以下代码:classProductsControllerTest我的问题是:方法调用products()在哪里/如何定义?products(:one)到底是什么意思?看代码,大概意思是“创建一个产品”,但是它是如何工作的呢?注意我是Ruby/Rails的新手,如果这些是微不足道的问题,我深表歉意。 最佳答案 如果您查看test/fixtures文件夹,您会看到一个products.yml文件。这是在您创建
我目前有一个reddit克隆类型的网站。我正在尝试根据我的用户之前喜欢的帖子推荐帖子。看起来K最近邻或k均值是执行此操作的最佳方法。我似乎无法理解如何实际实现它。我看过一些数学公式(例如k表示维基百科页面),但它们对我来说并没有真正意义。有人可以推荐一些伪代码,或者可以查看的地方,以便我更好地了解如何执行此操作吗? 最佳答案 K最近邻(又名KNN)是一种分类算法。基本上,您采用包含N个项目的训练组并对它们进行分类。如何对它们进行分类完全取决于您的数据,以及您认为该数据的重要分类特征是什么。在您的示例中,这可能是帖子类别、谁发布了该项
在我的一些Controller中,我有一个before_filter检查用户是否登录?用于CRUD操作。application.rbdeflogged_in?unlesscurrent_userredirect_toroot_pathendendprivatedefcurrent_user_sessionreturn@current_user_sessionifdefined?(@current_user_session)@current_user_session=UserSession.findenddefcurrent_userreturn@current_userifdefine
require'pp'p*1..10这会打印出1-10。为什么这么简洁?您还可以用它做什么? 最佳答案 它是“splat”运算符。它可用于分解数组和范围并在赋值期间收集值。这里收集赋值中的值:a,*b=1,2,3,4=>a=1b=[2,3,4]在此示例中,内部数组([3,4])中的值被分解并收集到包含数组中:a=[1,2,*[3,4]]=>a=[1,2,3,4]您可以定义将参数收集到数组中的函数:deffoo(*args)pargsendfoo(1,2,"three",4)=>[1,2,"three",4]
我读过的关于Ruby符号的每一篇文章都在谈论符号相对于字符串的效率。但是,这不是1970年代。我的电脑可以处理一些额外的垃圾收集。我错了吗?我拥有最新最好的奔腾双核处理器和4GBRAM。我认为这应该足以处理一些字符串。 最佳答案 您的计算机可能能够处理“一点点额外的垃圾收集”,但是当“一点点”发生在运行数百万次的内部循环中时呢?如果它在内存有限的嵌入式系统上运行呢?有很多地方你可以随意使用字符串,但在某些地方你不能。这完全取决于上下文。 关于ruby-现代计算机的功能是否不足以处理字符串
我正在使用Windows并尝试运行一个现有的功能包,该功能包最初是在MacOS上构建的,这允许他们通过使用带空格的"\"来解决问题。我正在使用Ruby2.2.3和Cucumber。功能名称包含空格,我无法更改它。我尝试使用""和''来绕过空白,但每次都有同样的问题。这是问题的一个例子。如果我运行:cucumberfeatures/'Namecontainingwhitespaces.feature'它工作正常。但是当我运行时:cucumber-pmy_profile和cucumber.yml包含:my_profile:features/'Namecontainingwhitespace