2013-06-25 66 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'')。 –

相关问题