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

时间:2015-12-07 22:05:43

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

我正在尝试使用对象转储来打印构造静态C ++对象的顺序。我找到了-h标题,但我似乎无法进一步了解。

在没有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?

现在在Display initialization order of static C++ objects in a library or program?

的Binutils邮件列表上有一个未解决的问题

1 个答案:

答案 0 :(得分:2)

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

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

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