2013-06-25 3 views
3

C++ 파일에서 생성 된 왜성 파일을보고 있는데 생성자 중 하나에 정보가 표시되지 않는 것으로 나타났습니다. 여기 내 C++ 파일 -드워프 디버그 정보에 생성자 데이터가 누락되었습니다.

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 

주요 섹션은 다음과 같다 - - 여기

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; 

그리고 내 난쟁이 파일입니다

<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 개의 int와 함수를 취하는 생성자를 포함하지만 기본 생성자에 대해서는 아무것도 포함하지 않습니다. 왜 그런가요? 거의 동일한 C++ 파일에 두 개의 dwarf 파일이 있습니다. (두 int 생성자는 하나의 int 생성자입니다.) 이 기본 생성자에 대한 정보를 표시합니다. 두 파일 모두에 정보가없는 이유는 무엇입니까? 참고 : 다른 파일은 약간 다른 컴파일러로 컴파일되었습니다.

편집 : 궁금한 점이 있더라도, 난장이 파일을 생성하는 데 사용한 명령은 - g++ -g -c test.cpp -o test.o이고 그 다음은 readelf --debug-dump=info >test.txt입니다.

답변

1

내가 여기에 대해 몇 가지 다른 질문이 있습니다. 만약 당신의 생성자 C :: void (컴파일러에 의해 합성 된 사소한 것 대신에)가 소스 코드로 구현 되었다면, DWARF에서 기술 된 것을 볼 수있을 것입니다. 이 함수를 사용하면 메서드의 인수 및 블록에 대한 기호 정보를 볼 수 있습니다. C :: C (void)가 컴파일러에서 제공하는 것이라면 DWARF에 언급되지 않은 버그로 플래그를 지정할지 모르겠습니다.

많은 컴파일러는 디버그 정보의 크기를 줄이기 위해 DWARF에서 사용되지 않는 유형을 제거하려고합니다. C :: C (int, int)를 선언하지만이를 정의하거나 호출하지 마십시오. 이 코드는 작은 예제 코드이기 때문에 확실합니다.하지만 컴파일러가 C :: C (int, int)가 정의되지 않았거나 사용되지 않는다고 생각하면 디버그에서 생략 할 수도 있습니다 정보. 때로는 이러한 사용되지 않는 유형 축소 스키마에는 버그가 포함되어 있으며 실제로 포함되어 있어야하는 정보는 생략됩니다. 이러한 종류의 장난감 예제 컴파일 단위는 컴파일러에서 사용되지 않는 형식 제거를 수행 할 때 특히 예기치 않은 디버그 정보를 초래할 수 있습니다.

clang을 통해 예제 컴파일 단위를 실행하면 다음 dwarf가 생성됩니다 (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()는 그렇지 않습니다. 옵티 마이저 설정을 변경하면 드워프 파일이 결국 어떻게 보이나요? 아마'C()'는 잘리지 않을 것입니까? –

+0

그것은 내가 기대할 수있는 것이 아니지만 컴파일러가 형식 중복 제거를 수행하는 경우 장난감 샘플 컴파일 단위에서 결론을 내릴 때주의해야합니다. 컴파일러의 커맨드 라인 인수를 통해 이들을 끄는 방법을 살펴보십시오. 이것은'char getChar() {return "hello"[2];와 같은 것을 수행하는 테스트 프로그램을 만드는 것과 같습니다. 컴파일러는 상수 108 (''l '')을 리턴하지 못하게 될 것입니다. –