gpt4 book ai didi

C++构造函数问题(linux)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:19:14 24 4
gpt4 key购买 nike

  • 环境:linux,通过 g++ 从几个 C++ 文件创建的用户空间应用程序(结果是一个 ELF)

  • 遍历构造函数列表时出现问题(SIGSEGV)

    ( __CTOR_LIST__ )

(注意:通过这个列表调用的代码是对每个类的一种系统初始化, 不是我写的构造函数代码)

  • 当我正确理解每个编译单元时(每个从 .cpp 创建的 .o)在
  • 中创建一个条目
    __CTOR_LIST__ 
  • 通过GDB单步执行程序时,问题(SIGSEGV)不存在

  • 为了调试这个,我正在寻找一种方法来添加自己的代码 before

  • 的调用
    "_do_global_ctors_aux"

有什么提示吗?

谢谢,

乌维

最佳答案

这有很多可能的原因。从您访问尚未创建的对象(因为跨不同翻译单元的对象创建顺序未定义)开始,我认为在这种情况下很可能发生这种情况,并且在您的构建环境中出现错误。

要使自己的函数在其他构造函数之前被调用,您有一个 constructor (priority) 属性描述 here . 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: warning: constructor priorities from 0 to 100 are reserved for the implementation

我通过中断 doitdothat 来测试它,它按照我们期望的顺序调用它们。玩得开心!

关于C++构造函数问题(linux),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/420350/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com