Я смотрю на файл 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 целых числа, и функцию после конструкторов, но ничего о конструкторе по умолчанию. Это почему? У меня есть другой файл dwarf в почти идентичном файле c ++ (конструктор двух int является конструктором one int), который делает показать информацию о конструкторе по умолчанию, так почему же информация не появляется в обоих файлах? Примечание: другой файл был скомпилирован с немного другим компилятором.
Изменить: Если вам было любопытно, команды, которые я использовал для создания файла карлика были — g++ -g -c test.cpp -o test.o
а потом readelf --debug-dump=info >test.txt
,
У меня есть несколько разных вопросов по этому поводу. Если ваш конструктор 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
Других решений пока нет …