【问题标题】:Display initialization order of static C++ objects in a program?显示程序中静态 C++ 对象的初始化顺序?
【发布时间】:2015-12-07 22:05:43
【问题描述】:

我试图让对象转储打印静态 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++ 对象的初始化顺序?


来自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?Display initialization order of static C++ objects in a library or program?Binutils 邮件列表中现在有一个未解决的问题

【问题讨论】:

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


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢 Sam(很抱歉回复晚了)。肯定有比分解图像更好的方法。这似乎荒谬可笑。我在 Binutils 邮件列表Display initialization order of static C++ objects in a library or program? 上问了同样的问题
  • 不,这并不荒谬。它只是“未定义”。 C++ 标准没有明确指定静态对象初始化的顺序。尽管提供这些信息的特定 C++ 实现没有任何问题,但在某种程度上,它绝对不需要这样做,所以我看不出缺少一种方便的机制来做一些不需要的事情第一名是“荒谬”。然而,准确描述为“荒谬”的是应用程序依赖于特定的初始化顺序。现在这太荒谬了。
  • C++ 委员会与问答和安全测试与评估 (ST&E) 必不可少的工具有什么关系?我看不到连接。我想对我们来说幸运的是,尽管有委员会,我们还是得到了像 objdumpnm 这样的工具。
  • 我不知道 objdump 和 nm 是安全测试工具,抱歉。
  • 是的,我们使用所有可用的工具(而不仅仅是 C++ 委员会批准的工具)。
猜你喜欢
  • 2021-07-12
  • 2019-09-17
  • 1970-01-01
  • 2015-06-01
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多