2016-08-25 11 views
4

Linux에서 GCC (v.6.1.1)에 의해 컴파일 된 공유 C++ 라이브러리의 거대한 크기를 분석 할 수 있습니다.C++ 기호 분석 : 정적 초기화를 수행하는 방법을 결정하는 방법은 무엇입니까?

readelf -sW libfoo.so는 예컨대 __static_initialization_and_destruction_0라는 특히 큰 기능이있는 것을 저에게 말한다 : 나는 링커 맵 파일을 생성하는 -Wl,-Map,foo.mapCXX에 플래그를 추가

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

. 그 맵 파일 수익률 0x000000000026c420 찾고 :

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

을 그래서 지금 내가 bar.cpp 정적 초기화를 일으키는 원인이되는 번역 단위는 것을 알고 있지만 파일이 어떤 static 변수를 포함하지 않는 말했다. 그러나 많은 헤더가 포함됩니다.

정확히 어떤 변수가 해당 함수에서 정적으로 초기화되어 있는지 어떻게 알 수 있습니까? 와 프로그램 컴파일

+0

_ #이 _'정적 ios_base :: 초기화 __ioinit을 정의 을 포함한다. – Viatorus

답변

2

:

-adhln -g3 -Wa을, 당신은 소스 코드와 어셈블리 코드를 얻을 것이다.

_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