В информации об отладке карлика отсутствуют данные в конструкторе

Я смотрю на файл карлика, созданный из файлов С++, и я заметил, что он не показывает никакой информации об одном из конструкторов. Вот мой файл С++ -

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 целых числа, и функцию после конструкторов, но ничего о конструкторе по умолчанию. Это почему? У меня есть другой файл dwarf в почти идентичном файле C++ (конструктор с двумя int - это конструктор с одним int), который действительно показывает информацию о конструкторе по умолчанию, так почему же информации нет в обоих файлах? Примечание: другой файл был скомпилирован немного другим компилятором.

Редактировать: Если вам интересно, команды, которые я использовал для создания файла карлика, были - g++ -g -c test.cpp -o test.o, а затем readelf --debug-dump=info >test.txt.


person David says Reinstate Monica    schedule 25.06.2013    source источник


Ответы (1)


У меня есть несколько разных вопросов по этому поводу. Если ваш конструктор C::C(void) реализован в исходном коде (вместо тривиального, синтезированного компилятором), я ожидаю увидеть его описание в DWARF, хотя бы по той причине, что вы можете вмешаться в эту функцию, и вы захотите увидеть символическую информацию об аргументах и ​​блоках вашего метода. Если C::C(void) предоставлен компилятором, я не знаю, помечаю ли я его как ошибку, которая не упоминается в DWARF.

Многие компиляторы также пытаются удалить неиспользуемые типы из DWARF, чтобы уменьшить размер отладочной информации. Вы объявляете C::C(int,int), но не определяете/не вызываете его. Я уверен, что это только потому, что это небольшой пример кода, но все же имейте в виду, что если компилятор считает, что C::C(int,int) не определен/не используется, он может исключить его из отладки. Информация. Иногда в этих схемах сокращения неиспользуемых типов также есть ошибки, и они пропускают информацию, которая действительно должна была быть включена. Такие единицы компиляции игрушечных примеров могут привести к особенно неожиданной отладочной информации, когда компилятор выполняет удаление неиспользуемого типа.

Что бы это ни стоило, запуск вашего примера модуля компиляции через clang создает следующий карлик (это выводится 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
person Jason Molenda    schedule 26.06.2013
comment
Что ж, тогда все становится еще более странным... Технически я вызываю конструктор по умолчанию, когда объявляю C c, и я никогда не вызываю конструктор C(int, int). Но по какой-то причине C(int, int) определяется в Dwarf, а C() — нет. Повлияет ли изменение настроек оптимизатора на внешний вид файла Dwarf? Может быть, C() не обрезается? - person David says Reinstate Monica; 26.06.2013
comment
Это не то, чего я ожидал, но я был бы осторожен, делая выводы из единиц компиляции игрушечных образцов, если ваш компилятор может выполнять устранение дублирования типов. Прочтите аргументы командной строки вашего компилятора, чтобы узнать, как их отключить. Это похоже на создание тестовой программы, которая делает что-то вроде char getChar () { return "hello"[2]; }, и удивление тем, что компилятор нигде в программе не выдал "hello" — компилятору пришлось бы приложить все усилия, чтобы не просто вернуть константу 108 ('l'). - person Jason Molenda; 26.06.2013