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

3
我想要获取对象转储以打印静态C++对象构建的顺序。我发现-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 ++对象的初始化顺序?

我知道可以使用objdump -hreadelf-S来获取有关C ++静态对象初始化顺序的<验证方法>。例如,我可以看到与对象文件相关联的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 并按照应该初始化的确切顺序布置对象文件,我们也无法在正确的时间初始化特定的字符串(请参见如何强制链接器遵守对象文件顺序?)。
现在,在 Binutils 邮件列表上有一个开放性问题,即 在库或程序中显示静态 C++ 对象的初始化顺序?

1个回答

2

可执行映像中已经初始化了一个POD

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

要确定初始化顺序,您需要反汇编.init()函数,并根据此确定它。


感谢Sam(对于晚回复我很抱歉)。肯定有比反汇编图像更好的方法。那似乎太荒谬了。我在Binutils邮件列表上问了同样的问题,链接为Display initialization order of static C++ objects in a library or program? - jww
不,这并不荒谬。它只是“未定义”的。C++标准没有指定静态对象初始化的明确顺序。虽然从某种程度上说,特定的C++实现公开此信息没有问题,但绝对没有要求这样做的必要性,因此我不明白为什么缺乏方便的机制来执行首先不需要的操作是“荒谬”的。然而,确切地说“荒谬”的是应用程序依赖于特定的初始化顺序。那才是荒谬的。 - Sam Varshavchik
C++委员会与问答和安全测试与评估(ST&E)所必需的工具有什么关系?我看不出联系。我猜对我们来说,幸运的是,我们有像***objdumpnm***这样的工具,尽管没有委员会的帮助。 - jww
我不知道 objdump 和 nm 是安全测试工具,很抱歉。 - Sam Varshavchik
是的,我们使用所有可用的工具(而不仅仅是C++委员会批准的工具)。 - jww

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接