DWARF 거의 컴파일러는 소스 프로그램에 대해 알고있는 것의 표현이다. 따라서이 질문에 대한 일반적인 대답은 : 소스에서 "로컬"크기를 찾을 수 있다면 그렇습니다. 그렇지 않으면 아니오.
그러나이 경우 프로그램에서 ...
을 제거하고 컴파일하면 readelf
을 사용하여 직접 DWARF를 읽을 수 있습니다.
입니다
<2><5c>: Abbrev Number: 3 (DW_TAG_variable)
<5d> DW_AT_name : (indirect string, offset: 0x5): testarray
<61> DW_AT_decl_file : 1
<62> DW_AT_decl_line : 7
<63> DW_AT_type : <0x7f>
<67> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
...
<1><7f>: Abbrev Number: 7 (DW_TAG_array_type)
<80> DW_AT_type : <0x78>
<84> DW_AT_sibling : <0x8f>
<2><88>: Abbrev Number: 8 (DW_TAG_subrange_type)
<89> DW_AT_type : <0x8f>
<8d> DW_AT_upper_bound : 5
<2><8e>: Abbrev Number: 0
<1><8f>: Abbrev Number: 6 (DW_TAG_base_type)
<90> DW_AT_byte_size : 8
<91> DW_AT_encoding : 7 (unsigned)
<92> DW_AT_name : (indirect string, offset: 0x60): sizetype
, 그것은 6 개 문자의 배열은 다음과 같습니다
는 다음과 같은 main
에 testarray
보이는거야. 따라서이 경우 길이를 찾을 수 있습니다. 정확히 소스를 읽을 때 기대할 수있는 길이입니다. - 즉, 길이가 정적으로 알려져 있지 않다
<2><4e>: Abbrev Number: 3 (DW_TAG_variable)
<4f> DW_AT_name : (indirect string, offset: 0xf): teststr
<53> DW_AT_decl_file : 1
<54> DW_AT_decl_line : 6
<55> DW_AT_type : <0x72>
<59> DW_AT_location : 2 byte block: 91 68 (DW_OP_fbreg: -24)
...
<1><72>: Abbrev Number: 5 (DW_TAG_pointer_type)
<73> DW_AT_byte_size : 8
<74> DW_AT_type : <0x78>
<1><78>: Abbrev Number: 6 (DW_TAG_base_type)
<79> DW_AT_byte_size : 1
<7a> DW_AT_encoding : 6 (signed char)
<7b> DW_AT_name : (indirect string, offset: 0x7d): char
이 그냥 포인터 - 투 - 문자 말한다 : 그러나 teststr
및 func
에서 변수
더처럼 보인다. gdb와 같은 디버거는 프로그램에서와 같이 열등한 메모리를 읽어서 런타임에서 길이를 찾을 수 있습니다.
고마워요! testarray가 위의 DWARF 정보에서 6 글자의 배열이라고 말할 수있는 방법을 설명해 주시겠습니까? 올바르게 추측하면 "DW_AT_upper_bound"에서 알 수 있습니다. 그럼 내 질문은 main에 여러 배열이 있다면, 어떻게 각각 다른 "DW_AT_upper_bound"와 해당 배열을 일치시킬 수 있습니까? –
모든 유형을 기반으로합니다. 먼저 변수'testarray' - DIE 0x5c에 대한 항목을 찾을 수 있습니다. 그런 다음 배열의 유형 인 DIE 0x7f를 살펴보십시오. 유형은 배열 유형이므로 경계를 살펴보십시오. 하한은 0 (명시 적이 아니지만 CU의 언어를 기반으로 알 수 있습니다)이며 상한은 5이므로 길이가 6입니다. 함수의 다른 배열은 자체 제한이있는 고유 한 유형을 갖습니다 . –