3

我正在查看从 c++ 文件生成的 dwarf 文件,我注意到它没有显示有关其中一个构造函数的任何信息。这是我的 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++ 文件上有另一个 dwarf 文件(两个 int 构造函数是一个 int 构造函数),它确实显示了有关默认构造函数的信息,那么为什么两个文件中都没有信息?注意:另一个文件是用稍微不同的编译器编译的。

编辑:如果你很好奇,我用来生成 dwarf 文件的命令是 -g++ -g -c test.cpp -o test.o然后是readelf --debug-dump=info >test.txt.

4

1 回答 1

1

我对此有几个不同的问题。如果您的构造函数 C::C(void) 是在源代码中实现的(而不是由编译器合成的微不足道的),我希望看到它在 DWARF 中描述,如果没有其他原因,您可能会介入这个函数,你会想看到关于你的方法的参数和块的符号信息。如果 C::C(void) 是编译器提供的,我不知道我是否会将其标记为 DWARF 中未提及的错误。

许多编译器还尝试从 DWARF 中删除未使用的类型以减少调试信息的大小。您声明 C::C(int,int) 但不定义/调用它。我确定这只是因为这是一小段代码示例 - 但请记住,如果编译器认为 C::C(int,int) 未定义/未使用,它可能会选择从调试中省略它信息。有时,这些未使用类型的减少方案中也存在错误,并且它们忽略了真正应该包含的信息。当编译器执行未使用的类型删除时,这些类型的玩具示例编译单元可能会导致特别意外的调试信息。

对于它的价值,通过 clang 运行您的示例编译单元会产生以下 dwarf(这是dwarfdump在 Mac OS X 上输出的 - 它省略了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
于 2013-06-26T10:23:58.980 回答