这有很多可能的原因.你访问尚未创建的对象的范围(因为不同的翻译单元创建对象的顺序是未定义的),我认为在这种情况下很可能,并且在构建环境中存在错误.
要在其他构造函数之前调用自己的函数,您可以在此处constructor (priority)
描述属性.GCC为每个文件的构造函数输入节保留优先级.它按照这些优先顺序将它们联系起来.在我的linux系统的链接器脚本中,该代码看起来像这样(使用它输出):ld -verbose
.ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) }
您可能希望给它一个低优先级,使其在具有更高优先级编号的其他已注册的ctor函数之前执行.然而从它的外观来看,似乎首先执行没有数字的构造函数.不完全确定.最好你试一试.如果你想在_do_global_ctors_aux之前调用你的函数,你必须释放_init
当你的程序由ELF加载器加载时通常执行的原始函数(查看-init
ld 的选项).自从我搞砸了它已经有一段时间了,但我记得它必须做一些初始化的细节,所以我不会尝试替换它.尝试使用我链接到的构造函数属性.但是,要非常小心.您的代码可能会在cout
构建其他重要对象之前执行.
更新:我做了一个测试,它实际上反过来执行ctor功能.因此,首先链接的ctor函数将在稍后执行.此代码恰好位于gcc源代码的crtstuff.c中:
func_ptr *p; for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) (*p) ();
我做了一点测试:
void dothat() { } struct f { f() { dothat(); } } f_; void doit() __attribute__((constructor (0))); void doit() { } int main() { }
将--print-map
产量与产量联系起来:
.ctors 0x080494f4 0x10 *crtbegin.o(.ctors) .ctors 0x080494f4 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtbegin.o *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) .ctors 0x080494f8 0x4 /tmp/ccyzWBjs.o *(SORT(.ctors.*)) .ctors.65535 0x080494fc 0x4 /tmp/ccyzWBjs.o *(.ctors) .ctors 0x08049500 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtend.o
请注意.ctors.65535
我们的属性优先级是如何隐式创建的部分0
.现在,如果你给予它优先权,gcc警告并且完全正确:p
test.cpp:7:警告:从0到100的构造函数优先级保留给实现
我打破上测试它doit
并dothat
和它在我们预计的顺序叫他们.玩得开心!
这有很多可能的原因.你访问尚未创建的对象的范围(因为不同的翻译单元创建对象的顺序是未定义的),我认为在这种情况下很可能,并且在构建环境中存在错误.
要在其他构造函数之前调用自己的函数,您可以在此处constructor (priority)
描述属性.GCC为每个文件的构造函数输入节保留优先级.它按照这些优先顺序将它们联系起来.在我的linux系统的链接器脚本中,该代码看起来像这样(使用它输出):ld -verbose
.ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) }
您可能希望给它一个低优先级,使其在具有更高优先级编号的其他已注册的ctor函数之前执行.然而从它的外观来看,似乎首先执行没有数字的构造函数.不完全确定.最好你试一试.如果你想在_do_global_ctors_aux之前调用你的函数,你必须释放_init
当你的程序由ELF加载器加载时通常执行的原始函数(查看-init
ld 的选项).自从我搞砸了它已经有一段时间了,但我记得它必须做一些初始化的细节,所以我不会尝试替换它.尝试使用我链接到的构造函数属性.但是,要非常小心.您的代码可能会在cout
构建其他重要对象之前执行.
更新:我做了一个测试,它实际上反过来执行ctor功能.因此,首先链接的ctor函数将在稍后执行.此代码恰好位于gcc源代码的crtstuff.c中:
func_ptr *p; for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) (*p) ();
我做了一点测试:
void dothat() { } struct f { f() { dothat(); } } f_; void doit() __attribute__((constructor (0))); void doit() { } int main() { }
将--print-map
产量与产量联系起来:
.ctors 0x080494f4 0x10 *crtbegin.o(.ctors) .ctors 0x080494f4 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtbegin.o *crtbegin?.o(.ctors) *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) .ctors 0x080494f8 0x4 /tmp/ccyzWBjs.o *(SORT(.ctors.*)) .ctors.65535 0x080494fc 0x4 /tmp/ccyzWBjs.o *(.ctors) .ctors 0x08049500 0x4 /usr/lib/gcc/i686-pc-linux-gnu/4.3.2/crtend.o
请注意.ctors.65535
我们的属性优先级是如何隐式创建的部分0
.现在,如果你给予它优先权,gcc警告并且完全正确:p
test.cpp:7:警告:从0到100的构造函数优先级保留给实现
我打破上测试它doit
并dothat
和它在我们预计的顺序叫他们.玩得开心!