c++ - 在程序中显示静态 C++ 对象的初始化顺序?

标签 c++ static-initialization static-order-fiasco

我正在尝试获取对象转储以打印静态 C++ 对象的构造顺序。我找到了 header 的 -h,但我似乎无法让 objdump 更进一步。

没有 init_priority 编译的程序

$ objdump -h cryptest.exe    
cryptest.exe:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       0000001c  0000000000400238  0000000000400238  00000238  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  0000000000400254  0000000000400254  00000254  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 ...
 10 .init         0000001a  000000000040efd8  000000000040efd8  0000efd8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 ...

使用init_priority编译的程序

$ objdump -h cryptest.exe    
cryptest.exe:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       0000001c  0000000000400238  0000000000400238  00000238  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  0000000000400254  0000000000400254  00000254  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 ...
 10 .init         0000001a  000000000040efd8  000000000040efd8  0000efd8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 ...
 19 .init_array   000000a8  00000000008e4008  00000000008e4008  002e4008  2**3
                  CONTENTS, ALLOC, LOAD, DATA

我很确定我的下一步是检查 .init.init_array,但我似乎无法获取对象转储来执行此操作:

$ objdump -d .init cryptest.exe 
objdump: '.init': No such file

cryptest.exe:     file format elf64-x86-64
...

如何在已编译的程序中显示静态 C++ 对象的初始化顺序?


来自 How to verify init_priorty for C++ static object initialization order?我知道我可以使用 objdump -hreadelf -S 获取有关它的一些信息。

例如,我可以看到与目标文件关联的 init_priority 值:

$ objdump -h cryptlib.o
509 .init_array.00275 00000008  0000000000000000  0000000000000000  00007da8  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
510 .init_array.00276 00000008  0000000000000000  0000000000000000  00007db0  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, DATA
511 .init_array.00280 00000008  0000000000000000  0000000000000000  00007db8  2**3

上面,我看到 init_priority 及其值存在于对象文件 (.init_array.00275) 中,但它没有告诉我有关变量或链接到程序后的最终顺序。


我们最近切换到 GCC 的 init_priority,因此我尝试添加一个 QA 步骤以确保对象的顺序在生效时符合指定的顺序。我还想在 init_priority 无效时查看对象的顺序。


这对我们来说仍然是一个问题;由于添加了新的自测试,我们无法在正确的时间初始化特定的字符串,即使使用 init_priority 并按照它们应该初始化的确切顺序布置目标文件(参见 How to force the linker to honor object file order? ).

Binutils 邮件列表中现在有一个悬而未决的问题 Display initialization order of static C++ objects in a library or program?

最佳答案

POD 已在可执行镜像中初始化。

看到那个.init symbol()了吗?非POD 静态类实例由编译器生成的初始化函数进行初始化,该函数仅调用每个静态对象的构造函数。 .init() 函数在加载可执行文件(或共享对象)时被调用。它的编译器生成的代码继续调用每个静态对象的构造函数。

要弄清楚初始化顺序,您必须反汇编 .init() 函数,并根据它弄清楚。

关于c++ - 在程序中显示静态 C++ 对象的初始化顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34144185/

相关文章:

c++ - 静态成员显式定义

java - 为什么在执行静态 block 时这个Float常量为null?

c++ - 此代码会产生未定义的行为还是仅仅是未指定的行为?

c++ - Static Initialization Order Fiasco 为什么这样称呼?

c++ - 静脉:如何验证重新路由是否使用用户设置算法

c++ - 由于类型为QLineSeries,所以单击了QAbstractSeries信号

c++ - Clang:覆盖之前在命令行中指定的所有警告和警告为错误的标志

c++ - 在 C++ 中初始化静态 std::map<int, unique_ptr<int>>

c++ - C++ 库中静态 STL 容器的双重初始化

c++ - STL 中 "end"指针非常量的基本原理