2013-06-25 3 views
3

Я смотрю на карликовый файл, сгенерированный из файлов C++, и я заметил, что он не показывает никакой информации об одном из конструкторов. Вот мой с файл ++ -dwarf debug info Отсутствующие данные о конструкторе

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 

Этот раздел содержит информацию о классе С, включая конструктор, который принимает 2 ints и функцию после конструкторов, но ничего о конструкторе по умолчанию. Почему это? У меня есть другой файл dwarf на почти идентичном файле 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) не определено/не используется, он может отказаться от его отладки Информация. Иногда эти схемы сокращения неиспользуемых типов также имеют ошибки в них, и они опускают информацию, которая действительно должна была быть включена. Эти типы единиц компиляции примера игрушки могут привести к особенно неожиданной отладочной информации, когда компилятор выполняет удаление неиспользуемого типа.

Для чего это стоит, работает ваш пример модуля компиляции через лязг производит следующее карликовый (это выводится 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 
+0

Ну тогда все становится еще более странно ... Я технически вызывать конструктор по умолчанию, когда я объявляю 'C c', и я * никогда * вызовите' C (целое, целое) 'конструктор. Тем не менее по какой-то причине 'C (int, int)' определяется в Dwarf, а 'C()' не является. Изменится ли настройка оптимизатора, как выглядит внешний вид файла Dwarf? Возможно, 'C()' не будет отключен? –

+0

Это не то, чего я ожидал бы, но я был бы осторожен в том, чтобы делать выводы из единиц компиляции образцов игрушек, если ваш компилятор может выполнять удаление дублирования типов. Прочитайте аргументы командной строки вашего компилятора, чтобы узнать, как отключить их. Это похоже на создание тестовой программы, которая делает что-то вроде 'char getChar() {return" hello "[2]; } 'и удивляюсь, что компилятор не выдавал« привет »в любом месте программы - компилятору пришлось бы не просто возвращать константу 108 (' 'l''). –