2016-08-25 6 views
4

Ich möchte analysieren, was die riesige Größe meiner freigegebenen C++ - Bibliothek verursacht, die von GCC (v.6.1.1) unter Linux kompiliert wird.C++ - Symbolanalyse: Wie ermittelt man, welche statische Initialisierung durchgeführt wird?

readelf -sW libfoo.so sagt mir, dass besonders große Funktionen genannt __static_initialization_and_destruction_0, z:

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

I -Wl,-Map,foo.map-CXX Flags hinzugefügt, um eine Linker-Map-Datei zu erzeugen. der Suche nach 0x000000000026c420 dass Kartendatei ergibt:

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

So, jetzt weiß ich, dass bar.cpp die Übersetzungseinheit ist, die die statische Initialisierung verursacht, aber die Datei keine static Variablen enthält. Es enthält jedoch viele Header.

Wie finde ich genau heraus, welche Variablen in diesen Funktionen statisch initialisiert werden?

+0

Sie wahrscheinlich verwenden _ # include _ die 'statische ios_base definiert :: Init __ioinit;'. – Viatorus

Antwort

2

Kompilieren Sie Ihr Programm mit: -g3 -Wa, -adhln

Sie den Assembler-Code mit Quellcode erhalten. Im Innern des Assembler-Code Sie so etwas wie finden:

_Z41__static_initialization_and_destruction_0ii: 

Und alle Teile des Codes, die eine statische Variable definieren wird es (ret) bis zur nächsten Rückkehr erwähnen werden.

Beispiel

Quelle:

struct Foo { 
    Foo() {} 
}; 

static Foo a; 
static Foo b; 

Compile:

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

Montage:

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 

Diese zwei

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

sind Ihre statischen Variablen. Mit C++ filt können Sie den richtigen Variablennamen erhalten.

Der Konstruktor:

call _ZN3FooC1Ev 
Verwandte Themen