当前位置:  开发笔记 > 编程语言 > 正文

C++ ctor问题(linux)

如何解决《C++ctor问题(linux)》经验,为你挑选了1个好方法。

这有很多可能的原因.你访问尚未创建的对象的范围(因为不同的翻译单元创建对象的顺序是未定义的),我认为在这种情况下很可能,并且在构建环境中存在错误.

要在其他构造函数之前调用自己的函数,您可以在此处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加载器加载时通常执行的原始函数(查看-initld 的选项).自从我搞砸了它已经有一段时间了,但我记得它必须做一些初始化的细节,所以我不会尝试替换它.尝试使用我链接到的构造函数属性.但是,要非常小心.您的代码可能会在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的构造函数优先级保留给实现

我打破上测试它doitdothat和它在我们预计的顺序叫他们.玩得开心!



1> Johannes Sch..:

这有很多可能的原因.你访问尚未创建的对象的范围(因为不同的翻译单元创建对象的顺序是未定义的),我认为在这种情况下很可能,并且在构建环境中存在错误.

要在其他构造函数之前调用自己的函数,您可以在此处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加载器加载时通常执行的原始函数(查看-initld 的选项).自从我搞砸了它已经有一段时间了,但我记得它必须做一些初始化的细节,所以我不会尝试替换它.尝试使用我链接到的构造函数属性.但是,要非常小心.您的代码可能会在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的构造函数优先级保留给实现

我打破上测试它doitdothat和它在我们预计的顺序叫他们.玩得开心!

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有