2013-06-25 97 views
3

我看着一個C++文件生成的矮人文件,我注意到它沒有顯示任何一個構造函數的信息。這裏是我的C++文件 -矮人調試信息缺少構造函數的數據

class C { 
public: 
    C(); 
    C(int x, int y); 
    int getX(); 
private: 
    int x; 
    int y; 
}; 

class SubC : public C { 
    int z; 
}; 

int f() {return 0;} 

C c; 
SubC subC; 

int i; 
double d; 

這裏是我的侏儒文件 -

The section .debug_info contains: 

    Compilation Unit @ offset 0x0: 
    Length:  0x134 (32-bit) 
    Version:  2 
    Abbrev Offset: 0 
    Pointer Size: 8 
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit) 
    <c> DW_AT_producer : (indirect string, offset: 0xd): GNU C++ 4.3.0 20080428 (Red Hat 4.3.0-8) 
    <10> DW_AT_language : 4 (C++) 
    <11> DW_AT_name  : (indirect string, offset: 0x75): test.cpp  
    <15> DW_AT_comp_dir : (indirect string, offset: 0x4d): /home/dwarf 
    <19> DW_AT_low_pc  : 0x0 
    <21> DW_AT_high_pc  : 0xb 
    <29> DW_AT_stmt_list : 0x0 
<1><2d>: Abbrev Number: 2 (DW_TAG_class_type) 
    <2e> DW_AT_name  : C  
    <30> DW_AT_byte_size : 8  
    <31> DW_AT_decl_file : 1  
    <32> DW_AT_decl_line : 1  
    <33> DW_AT_sibling  : <0x86> 
<2><37>: Abbrev Number: 3 (DW_TAG_member) 
    <38> DW_AT_name  : x  
    <3a> DW_AT_decl_file : 1  
    <3b> DW_AT_decl_line : 7  
    <3c> DW_AT_type  : <0x86> 
    <40> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) 
    <43> DW_AT_accessibility: 3 (private) 
<2><44>: Abbrev Number: 3 (DW_TAG_member) 
    <45> DW_AT_name  : y  
    <47> DW_AT_decl_file : 1  
    <48> DW_AT_decl_line : 8  
    <49> DW_AT_type  : <0x86> 
    <4d> DW_AT_data_member_location: 2 byte block: 23 4 (DW_OP_plus_uconst: 4) 
    <50> DW_AT_accessibility: 3 (private) 
<2><51>: Abbrev Number: 4 (DW_TAG_subprogram) 
    <52> DW_AT_external : 1  
    <53> DW_AT_name  : C  
    <55> DW_AT_decl_file : 1  
    <56> DW_AT_decl_line : 4  
    <57> DW_AT_declaration : 1  
    <58> DW_AT_sibling  : <0x6d> 
<3><5c>: Abbrev Number: 5 (DW_TAG_formal_parameter) 
    <5d> DW_AT_type  : <0x8d> 
    <61> DW_AT_artificial : 1  
<3><62>: Abbrev Number: 6 (DW_TAG_formal_parameter) 
    <63> DW_AT_type  : <0x86> 
<3><67>: Abbrev Number: 6 (DW_TAG_formal_parameter) 
    <68> DW_AT_type  : <0x86> 
<2><6d>: Abbrev Number: 7 (DW_TAG_subprogram) 
    <6e> DW_AT_external : 1  
    <6f> DW_AT_name  : (indirect string, offset: 0x70): getX  
    <73> DW_AT_decl_file : 1  
    <74> DW_AT_decl_line : 5  
    <75> DW_AT_MIPS_linkage_name: (indirect string, offset: 0x0): _ZN1C4getXEv  
    <79> DW_AT_type  : <0x86> 
    <7d> DW_AT_declaration : 1  
<3><7e>: Abbrev Number: 5 (DW_TAG_formal_parameter) 
    <7f> DW_AT_type  : <0x8d> 
    <83> DW_AT_artificial : 1  
<1><86>: Abbrev Number: 8 (DW_TAG_base_type) 
    <87> DW_AT_byte_size : 4  
    <88> DW_AT_encoding : 5 (signed) 
    <89> DW_AT_name  : int 
<1><8d>: Abbrev Number: 9 (DW_TAG_pointer_type) 
    <8e> DW_AT_byte_size : 8  
    <8f> DW_AT_type  : <0x2d> 
<1><93>: Abbrev Number: 10 (DW_TAG_class_type) 
    <94> DW_AT_name  : (indirect string, offset: 0x41): SubC  
    <98> DW_AT_byte_size : 12 
    <99> DW_AT_decl_file : 1  
    <9a> DW_AT_decl_line : 11 
    <9b> DW_AT_sibling  : <0xb6> 
<2><9f>: Abbrev Number: 11 (DW_TAG_inheritance) 
    <a0> DW_AT_type  : <0x2d> 
    <a4> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) 
    <a7> DW_AT_accessibility: 1 (public) 
<2><a8>: Abbrev Number: 3 (DW_TAG_member) 
    <a9> DW_AT_name  : z  
    <ab> DW_AT_decl_file : 1  
    <ac> DW_AT_decl_line : 12 
    <ad> DW_AT_type  : <0x86> 
    <b1> DW_AT_data_member_location: 2 byte block: 23 8 (DW_OP_plus_uconst: 8) 
    <b4> DW_AT_accessibility: 3 (private) 
<1><b6>: Abbrev Number: 12 (DW_TAG_subprogram) 
    <b7> DW_AT_external : 1  
    <b8> DW_AT_name  : f  
    <ba> DW_AT_decl_file : 1  
    <bb> DW_AT_decl_line : 15 
    <bc> DW_AT_MIPS_linkage_name: (indirect string, offset: 0x36): _Z1fv 
    <c0> DW_AT_type  : <0x86> 
    <c4> DW_AT_low_pc  : 0x0 
    <cc> DW_AT_high_pc  : 0xb 
    <d4> DW_AT_frame_base : 0x0 (location list) 
<1><d8>: Abbrev Number: 13 (DW_TAG_variable) 
    <d9> DW_AT_name  : c  
    <db> DW_AT_decl_file : 1  
    <dc> DW_AT_decl_line : 17 
    <dd> DW_AT_type  : <0x8d> 
    <e1> DW_AT_external : 1  
    <e2> DW_AT_location : 9 byte block: 3 0 0 0 0 0 0 0 0 (DW_OP_addr: 0) 
<1><ec>: Abbrev Number: 14 (DW_TAG_variable) 
    <ed> DW_AT_name  : (indirect string, offset: 0x3c): subC  
    <f1> DW_AT_decl_file : 1  
    <f2> DW_AT_decl_line : 18 
    <f3> DW_AT_type  : <0x102> 
    <f7> DW_AT_external : 1  
    <f8> DW_AT_location : 9 byte block: 3 8 0 0 0 0 0 0 0 (DW_OP_addr: 8) 
<1><102>: Abbrev Number: 9 (DW_TAG_pointer_type) 
    <103> DW_AT_byte_size : 8 
    <104> DW_AT_type  : <0x93> 
<1><108>: Abbrev Number: 13 (DW_TAG_variable) 
    <109> DW_AT_name  : i 
    <10b> DW_AT_decl_file : 1 
    <10c> DW_AT_decl_line : 20 
    <10d> DW_AT_type  : <0x86> 
    <111> DW_AT_external : 1 
    <112> DW_AT_location : 9 byte block: 3 10 0 0 0 0 0 0 0 (DW_OP_addr: 10) 
<1><11c>: Abbrev Number: 13 (DW_TAG_variable) 
    <11d> DW_AT_name  : d 
    <11f> DW_AT_decl_file : 1 
    <120> DW_AT_decl_line : 21 
    <121> DW_AT_type  : <0x130> 
    <125> DW_AT_external : 1 
    <126> DW_AT_location : 9 byte block: 3 18 0 0 0 0 0 0 0 (DW_OP_addr: 18) 
<1><130>: Abbrev Number: 15 (DW_TAG_base_type) 
    <131> DW_AT_byte_size : 8 
    <132> DW_AT_encoding : 4 (float) 
    <133> DW_AT_name  : (indirect string, offset: 0x46): double 

的關鍵部分如下 -

<1><2d>: Abbrev Number: 2 (DW_TAG_class_type) 
    <2e> DW_AT_name  : C  
    <30> DW_AT_byte_size : 8  
    <31> DW_AT_decl_file : 1  
    <32> DW_AT_decl_line : 1  
    <33> DW_AT_sibling  : <0x86> 
<2><37>: Abbrev Number: 3 (DW_TAG_member) 
    <38> DW_AT_name  : x  
    <3a> DW_AT_decl_file : 1  
    <3b> DW_AT_decl_line : 7  
    <3c> DW_AT_type  : <0x86> 
    <40> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) 
    <43> DW_AT_accessibility: 3 (private) 
<2><44>: Abbrev Number: 3 (DW_TAG_member) 
    <45> DW_AT_name  : y  
    <47> DW_AT_decl_file : 1  
    <48> DW_AT_decl_line : 8  
    <49> DW_AT_type  : <0x86> 
    <4d> DW_AT_data_member_location: 2 byte block: 23 4 (DW_OP_plus_uconst: 4) 
    <50> DW_AT_accessibility: 3 (private) 
<2><51>: Abbrev Number: 4 (DW_TAG_subprogram) 
    <52> DW_AT_external : 1  
    <53> DW_AT_name  : C  
    <55> DW_AT_decl_file : 1  
    <56> DW_AT_decl_line : 4  
    <57> DW_AT_declaration : 1  
    <58> DW_AT_sibling  : <0x6d> 
<3><5c>: Abbrev Number: 5 (DW_TAG_formal_parameter) 
    <5d> DW_AT_type  : <0x8d> 
    <61> DW_AT_artificial : 1  
<3><62>: Abbrev Number: 6 (DW_TAG_formal_parameter) 
    <63> DW_AT_type  : <0x86> 
<3><67>: Abbrev Number: 6 (DW_TAG_formal_parameter) 
    <68> DW_AT_type  : <0x86> 
<2><6d>: Abbrev Number: 7 (DW_TAG_subprogram) 
    <6e> DW_AT_external : 1  
    <6f> DW_AT_name  : (indirect string, offset: 0x70): getX  
    <73> DW_AT_decl_file : 1  
    <74> DW_AT_decl_line : 5  
    <75> DW_AT_MIPS_linkage_name: (indirect string, offset: 0x0): _ZN1C4getXEv  
    <79> DW_AT_type  : <0x86> 
    <7d> DW_AT_declaration : 1 

本節包含了C類信息,包括在構造函數之後使用2個整數和函數的構造函數,但沒有涉及默認構造函數。這是爲什麼?我有一個幾乎相同的C++文件(兩個int構造函數是一個int構造函數)上的另一個矮文件顯示有關默認構造函數的信息,所以如何在兩個文件中的信息是不是?注意:另一個文件是用稍微不同的編譯器編譯的。

編輯:因爲你好奇,我用來生成矮人文件的命令是 - g++ -g -c test.cpp -o test.o,然後是readelf --debug-dump=info >test.txt

回答

1

我對此有幾個不同的問題。如果你的構造函數C :: C(void)是在源代碼中實現的(而不是由編譯器合成的一個簡單的實現),我期望看到它在DWARF中描述,如果沒有其他原因,你可能會介入這個函數,你會希望看到有關你的方法的參數和塊的符號信息。如果C :: C(void)是編譯器提供的,我不知道是否將它標記爲DWARF中未提及的錯誤。

許多編譯器還嘗試從DWARF中刪除未使用的類型以減少調試信息的大小。你聲明C :: C(int,int),但是不要定義/調用它。我確信這只是因爲這是一小段代碼 - 但是請記住,如果編譯器認爲C :: C(int,int)未定義/未使用,它可能會選擇從調試中忽略它信息。有時候這些未使用類型的簡化方案也存在缺陷,並且會忽略真正應該包含的信息。這些類型的玩具示例編譯單元在編譯器沒有使用類型刪除時會導致特別意外的調試信息。

對於它的價值,通過鐺運行你的榜樣編譯單元產生以下侏儒(這是在Mac OS X通過dwarfdump輸出 - 它忽略了對名DW_前綴這是一個有點古怪,但否則它很可讀。)

0x00000032:  TAG_class_type [4] * 
       AT_name("C") 
       AT_byte_size(0x08) 
       AT_decl_file("/private/tmp/b.cc") 
       AT_decl_line(1) 

0x0000003a:   TAG_member [5] 
        AT_name("x") 
        AT_type({0x00000026} (int)) 
        AT_decl_file("/private/tmp/b.cc") 
        AT_decl_line(7) 
        AT_data_member_location(+0) 
        AT_accessibility(DW_ACCESS_private) 

0x00000049:   TAG_member [5] 
        AT_name("y") 
        AT_type({0x00000026} (int)) 
        AT_decl_file("/private/tmp/b.cc") 
        AT_decl_line(8) 
        AT_data_member_location(+4) 
        AT_accessibility(DW_ACCESS_private) 

0x00000058:   TAG_subprogram [6] * 
        AT_name("C") 
        AT_decl_file("/private/tmp/b.cc") 
        AT_decl_line(3) 
        AT_declaration(0x01) 
        AT_external(0x01) 
        AT_accessibility(DW_ACCESS_public) 

0x00000062:    TAG_formal_parameter [7] 
         AT_type({0x0000002d} (C*)) 
         AT_artificial(0x01) 

0x00000068:    NULL 

0x00000069:   TAG_subprogram [6] * 
        AT_name("C") 
        AT_decl_file("/private/tmp/b.cc") 
        AT_decl_line(4) 
        AT_declaration(0x01) 
        AT_external(0x01) 
        AT_accessibility(DW_ACCESS_public) 

0x00000073:    TAG_formal_parameter [7] 
         AT_type({0x0000002d} (C*)) 
         AT_artificial(0x01) 

0x00000079:    TAG_formal_parameter [8] 
         AT_type({0x00000026} (int)) 

0x0000007e:    TAG_formal_parameter [8] 
         AT_type({0x00000026} (int)) 

0x00000083:    NULL 
+0

那好吧事情變得更奇怪......我叫技術上的默認構造函數,當我宣佈'C C',我*不要*調用'C(INT,INT)'構造。但由於某種原因,C(int,int)在Dwarf中定義,而C()不是。更改優化器設置是否會改變Dwarf文件最終的外觀?也許'C()'不會被切斷? –

+0

這不是我所期望的 - 但是如果您的編譯器可能正在進行類型重複消除,我會小心從玩具樣本編譯單元得出結論。通讀您的編譯器的命令行參數,以瞭解如何關閉這些參數。這就像創建一個測試程序,它可以像'char getChar(){return「hello」[2]; }'並且驚訝於編譯器在程序中的任何地方都沒有發出''hello''',編譯器將不得不不停地返回常量108(''l'')。 –

相關問題