- 论坛徽章:
- 0
|
从程序员角度看ELF[z
★3.1 在c++中全局的构造函数和析构函数
在c++中全局的构造函数和析构函数必须非常小心的处理碰到的语言规范问题。
构造函数必须在main函数之前被调用。析构函数必须在main函数返回之后
被调用。例如,除了一般的两个辅助启动文件crti.o和crtn.o外,GNU C/C++
编译器--gcc还提供两个辅助启动文件一个称为crtbegin.o,还有一个被称为
crtend.o。结合.ctors和.dtors两个section,c++全局的构造函数和析构函数
能以运行时最小的负载,正确的顺序执行。
.ctors
该section保存着程序的全局的构造函数的指针数组。
.dtors
该section保存着程序的全局的析构函数的指针数组。
ctrbegin.o
有四个section:
1 .ctors section
local标号__CTOR_LIST__指向全局构造函数的指针数组头。在
ctrbegin.o中的该数组只有一个dummy元素。
[译注:
# objdump -s -j .ctors
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtbegin.o
/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtbegin.o:
file format elf32-i386
Contents of section .ctors:
0000 ffffffff ....
这里说的dummy元素应该就是指的是ffffffff
]
2 .dtors section
local标号__DTOR_LIST__指向全局析构函数的指针数组头。在
ctrbegin.o中的该数组仅有也只有一个dummy元素。
3 .text section
只包含了__do_global_dtors_aux函数,该函数遍历__DTOR_LIST__
列表,调用列表中的每个析构函数。
函数如下:
- Disassembly of section .text:
- 00000000 <__do_global_dtors_aux>;:
- 0: 55 push %ebp
- 1: 89 e5 mov %esp,%ebp
- 3: 83 3d 04 00 00 00 00 cmpl $0x0,0x4
- a: 75 38 jne 44 <__do_global_dtors_aux+0x44>;
- c: eb 0f jmp 1d <__do_global_dtors_aux+0x1d>;
- e: 89 f6 mov %esi,%esi
- 10: 8d 50 04 lea 0x4(%eax),%edx
- 13: 89 15 00 00 00 00 mov %edx,0x0
- 19: 8b 00 mov (%eax),%eax
- 1b: ff d0 call *%eax
- 1d: a1 00 00 00 00 mov 0x0,%eax
- 22: 83 38 00 cmpl $0x0,(%eax)
- 25: 75 e9 jne 10 <__do_global_dtors_aux+0x10>;
- 27: b8 00 00 00 00 mov $0x0,%eax
- 2c: 85 c0 test %eax,%eax
- 2e: 74 0a je 3a <__do_global_dtors_aux+0x3a>;
- 30: 68 00 00 00 00 push $0x0
- 35: e8 fc ff ff ff call 36 <__do_global_dtors_aux+0x36>;
- 3a: c7 05 04 00 00 00 01 movl $0x1,0x4
- 41: 00 00 00
- 44: c9 leave
- 45: c3 ret
- 46: 89 f6 mov %esi,%esi
复制代码 |
|