2016-08-25 1 views
4

Linux上でGCC(v.6.1.1)でコンパイルされた共有C++ライブラリの膨大なサイズの原因を分析します。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] 

私は、リンカマップファイルを生成するためにCXXフラグに-Wl,-Map,foo.mapを追加しました。 はそのマップファイルの収率で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 

これらの2つ

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

は静的変数です。 C++ filtでは、正しい変数名を得ることができます。

コンストラクタ:; `あなたはおそらく使用

call _ZN3FooC1Ev 
関連する問題