gpt4 book ai didi

C++符号分析: how to determine which static initialization is performed?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:08:07 26 4
gpt4 key购买 nike

我想分析是什么原因导致我在 Linux 上由 GCC (v.6.1.1) 编译的共享 C++ 库的大小。

readelf -sW libfoo.so 告诉我特别大的函数叫做 __static_initialization_and_destruction_0,例如:

000000000026c420 10272 FUNC    LOCAL  DEFAULT   12 __static_initialization_and_destruction_0(int, int) [clone .constprop.1774]

我将 -Wl,-Map,foo.map 添加到 CXX 标志以生成链接器映射文件。在该映射文件中查找 0x000000000026c420 会产生:

.text.startup  0x000000000026c420     0x2825 CMakeFiles/foo.dir/bar.cpp.o

所以现在我知道 bar.cpp 是导致静态初始化的翻译单元,但该文件不包含任何 static 变量。但是,它包含很多 header 。

我如何准确找出哪些变量在这些函数中被静态初始化?

最佳答案

编译你的程序:-g3 -Wa,-adhln

您将获得带有源代码的汇编代码。在汇编代码中,您会发现类似以下内容:

_Z41__static_initialization_and_destruction_0ii:

在下一次返回 (ret) 之前,您的代码中定义静态变量的所有部分都将被提及。

示例

来源:

struct Foo {
Foo() {}
};

static Foo a;
static Foo b;

编译:

g++ text.cpp -c -O0 -g3 -Wa,-ahln > out.txt

程序集:

35              _Z41__static_initialization_and_destruction_0ii:
36 .LFB3:
3:text.cpp **** };
4:text.cpp ****
5:text.cpp **** static Foo a;
6:text.cpp **** static Foo b;
37 .loc 1 6 0
38 .cfi_startproc
39 0000 55 pushq %rbp
40 .cfi_def_cfa_offset 16
41 .cfi_offset 6, -16
42 0001 4889E5 movq %rsp, %rbp
43 .cfi_def_cfa_register 6
44 0004 4883EC10 subq $16, %rsp
45 0008 897DFC movl %edi, -4(%rbp)
46 000b 8975F8 movl %esi, -8(%rbp)
47 .loc 1 6 0
48 000e 837DFC01 cmpl $1, -4(%rbp)
49 0012 751D jne .L4
50 .loc 1 6 0 is_stmt 0 discriminator 1
51 0014 817DF8FF cmpl $65535, -8(%rbp)
51 FF0000
52 001b 7514 jne .L4
5:text.cpp **** struct Foo {
Foo() {}
};

static Foo a;
static Foo b;

53 .loc 1 5 0 is_stmt 1 discriminator 3
54 001d BF000000 movl $_ZL1a, %edi
54 00
55 0022 E8000000 call _ZN3FooC1Ev
55 00
56 .loc 1 6 0 discriminator 3
57 0027 BF000000 movl $_ZL1b, %edi
57 00
58 002c E8000000 call _ZN3FooC1Ev
58 00
59 .L4:
60 .loc 1 6 0 is_stmt 0
61 0031 90 nop
62 0032 C9 leave
63 .cfi_def_cfa 7, 8
64 0033 C3 ret
65 .cfi_endproc

这两个

54 001d BF000000        movl    $_ZL1a, %edi
57 0027 BF000000 movl $_ZL1b, %edi

是你的静态变量。使用 c++filt 您可以获得正确的变量名。

构造函数:

call    _ZN3FooC1Ev

关于C++符号分析: how to determine which static initialization is performed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39141765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com