2016-08-25 51 views
4

我想分析在Linux上由GCC(v.6.1.1)编译的共享C++库的大小是什么原因。C++符号分析:如何确定执行哪个静态初始化?

readelf -sW libfoo.so告诉我,是特别大的函数调用__static_initialization_and_destruction_0,e.g:

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

我加-Wl,-Map,foo.mapCXX标志可生成一个链接器映射文件。 寻找在地图文件的产量0x000000000026c420

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

所以,现在我知道bar.cpp是翻译单元从而导致静态初始化,但他说文件不包含任何static变量。但是,它包含许多标题。

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

+0

你可能使用_#包括 _定义'静态的ios_base ::初始化__ioinit;'。 – Viatorus

回答

2

编译与程序: -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