DWARF debugging formatを利用する
はじめに
DWARFはデバッグ情報を格納するためのデータフォーマットです。
デバッグ情報を取り出して、利用する方法を紹介します。
コンパイル後のデバッグ情報を使って
網羅的にstruct / class の 情報を取り出せるため便利です。
sample
具体例を使って説明します。
class parent {
char pvalue;
};
class child : public parent {
short cvalue;
};
struct record {
int rvalue;
};
int main()
{
class parent p;
class child c;
struct record r;
return 0;
}
-gオプションをつけてコンパイルすることでデバッグ情報をつけて実行ファイルを作成します
$ gcc -g -O0 test.cpp
objdumpを使ってDWARFの情報を出力します。
$ LANG=C objdump -W ./a.out | grep "DWARF Version"
DWARF Version: 2
$ LANG=C objdump -Wi ./a.out
./a.out: file format elf64-x86-64
Contents of the .debug_info section:
Compilation Unit @ offset 0x0:
Length: 0xe5 (32-bit)
Version: 4
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_producer : (indirect string, offset: 0x46): GNU C++ 4.8.4 -mtune=generic -march=x86-64 -g -O0 -fstack-protector
<10> DW_AT_language : 4 (C++)
<11> DW_AT_name : (indirect string, offset: 0x37): test.cpp
<15> DW_AT_comp_dir : (indirect string, offset: 0x8a): /home/user/tmp
<19> DW_AT_low_pc : 0x4004ed
<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 : (indirect string, offset: 0x29): parent
<32> DW_AT_byte_size : 1
<33> DW_AT_decl_file : 1
<34> DW_AT_decl_line : 1
<35> DW_AT_sibling : <0x46>
<2><39>: Abbrev Number: 3 (DW_TAG_member)
<3a> DW_AT_name : (indirect string, offset: 0x30): pvalue
<3e> DW_AT_decl_file : 1
<3f> DW_AT_decl_line : 2
<40> DW_AT_type : <0x46>
<44> DW_AT_data_member_location: 0
<2><45>: Abbrev Number: 0
<1><46>: Abbrev Number: 4 (DW_TAG_base_type)
<47> DW_AT_byte_size : 1
<48> DW_AT_encoding : 6 (signed char)
<49> DW_AT_name : (indirect string, offset: 0x1d): char
<1><4d>: Abbrev Number: 2 (DW_TAG_class_type)
<4e> DW_AT_name : (indirect string, offset: 0x40): child
<52> DW_AT_byte_size : 4
<53> DW_AT_decl_file : 1
<54> DW_AT_decl_line : 5
<55> DW_AT_sibling : <0x6d>
<2><59>: Abbrev Number: 5 (DW_TAG_inheritance)
<5a> DW_AT_type : <0x2d>
<5e> DW_AT_data_member_location: 0
<5f> DW_AT_accessibility: 1 (public)
<2><60>: Abbrev Number: 3 (DW_TAG_member)
<61> DW_AT_name : (indirect string, offset: 0x0): cvalue
<65> DW_AT_decl_file : 1
<66> DW_AT_decl_line : 6
<67> DW_AT_type : <0x6d>
<6b> DW_AT_data_member_location: 2
<2><6c>: Abbrev Number: 0
<1><6d>: Abbrev Number: 4 (DW_TAG_base_type)
<6e> DW_AT_byte_size : 2
<6f> DW_AT_encoding : 5 (signed)
<70> DW_AT_name : (indirect string, offset: 0x13): short int
<1><74>: Abbrev Number: 6 (DW_TAG_structure_type)
<75> DW_AT_name : (indirect string, offset: 0x22): record
<79> DW_AT_byte_size : 4
<7a> DW_AT_decl_file : 1
<7b> DW_AT_decl_line : 9
<7c> DW_AT_sibling : <0x8d>
<2><80>: Abbrev Number: 3 (DW_TAG_member)
<81> DW_AT_name : (indirect string, offset: 0xc): rvalue
<85> DW_AT_decl_file : 1
<86> DW_AT_decl_line : 10
<87> DW_AT_type : <0x8d>
<8b> DW_AT_data_member_location: 0
<2><8c>: Abbrev Number: 0
<1><8d>: Abbrev Number: 7 (DW_TAG_base_type)
<8e> DW_AT_byte_size : 4
<8f> DW_AT_encoding : 5 (signed)
<90> DW_AT_name : int
<1><94>: Abbrev Number: 8 (DW_TAG_subprogram)
<95> DW_AT_external : 1
<95> DW_AT_name : (indirect string, offset: 0x7): main
<99> DW_AT_decl_file : 1
<9a> DW_AT_decl_line : 13
<9b> DW_AT_type : <0x8d>
<9f> DW_AT_low_pc : 0x4004ed
<a7> DW_AT_high_pc : 0xb
<af> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<b1> DW_AT_GNU_all_call_sites: 1
<2><b1>: Abbrev Number: 9 (DW_TAG_lexical_block)
<b2> DW_AT_low_pc : 0x4004f1
<ba> DW_AT_high_pc : 0x5
<3><c2>: Abbrev Number: 10 (DW_TAG_variable)
<c3> DW_AT_name : p
<c5> DW_AT_decl_file : 1
<c6> DW_AT_decl_line : 15
<c7> DW_AT_type : <0x2d>
<cb> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<3><ce>: Abbrev Number: 10 (DW_TAG_variable)
<cf> DW_AT_name : c
<d1> DW_AT_decl_file : 1
<d2> DW_AT_decl_line : 16
<d3> DW_AT_type : <0x4d>
<d7> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<3><da>: Abbrev Number: 10 (DW_TAG_variable)
<db> DW_AT_name : r
<dd> DW_AT_decl_file : 1
<de> DW_AT_decl_line : 17
<df> DW_AT_type : <0x74>
<e3> DW_AT_location : 2 byte block: 91 60 (DW_OP_fbreg: -32)
<3><e6>: Abbrev Number: 0
<2><e7>: Abbrev Number: 0
<1><e8>: Abbrev Number: 0
struct / class の 情報
DWARFにはstruct / class の 情報があります。
struct / classの名前やデータサイズを知りたいというケースで役立ちます。
次のタグでstruct / classの情報であるかどうかを判定できます。
DW_TAG_base_typeは組み込み型を表します。
DW_TAG_base_type
DW_TAG_structure_type
DW_TAG_class_type
具体例は以下の通りです。class name = parent, size = 1 であることが分かります。
<1><2d>: Abbrev Number: 2 (DW_TAG_class_type)
<2e> DW_AT_name : (indirect string, offset: 0x29): parent
<32> DW_AT_byte_size : 1
rubyを使ってtype / name / sizeを取り出します。
#!/usr/bin/ruby
while str = STDIN.gets
if str.match(/DW_TAG_(.*)_type/) then
if $1 == "class" or $1 == "structure" then
# type
type = $1
# name
str = STDIN.gets
str.match(/.*: (.*)/)
name = $1.strip
# byte size
str = STDIN.gets
str.match(/.*: (.*)/)
byte_size = $1.strip
# print
print type + "\t" + name + "\t" + byte_size + "\n"
end
end
end
$ ruby --version
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
$ LANG=C objdump -Wi ./a.out | ./extract.rb
class parent 1
class child 4
structure record 4
Author And Source
この問題について(DWARF debugging formatを利用する), 我々は、より多くの情報をここで見つけました https://qiita.com/tobira-code/items/de16088be23021e75c74著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .