llvm-dwarfdump コマンドの使い方メモ
はじめに
最近デバッガについて少し理解したいと思っています。
今回はllvm-dwarfdumpコマンドの使い方について記載をします。
DWARF
DWARFとはデバッグ用データフォーマットの規格のこと。
公式サイトは以下。
llvm-dwarfdump
llvm-dwarfdumpは
DWARFの情報をダンプするツールです。
当然ですが、ダンプするバイナリにDWARFの情報がないといけません。
サンプルとして以下のようなコードを用意します。
#include <stdio.h>
int main(void){
printf("hello\n");
return 0;
}
clang
で以下のようにコンパイルします。
ポイントは-g
オプションを付けて、デバッグ情報を付加することです。
-gdwarf-5
についてはDWARFのバージョンを指定することができます。
(-gdwarf-5
でVer5。Ver5が最新のようです)
-gembed-source
についてはよくわかりません。
DWARF内にコードの内容を埋め込むことができるのでしょうか。
公式のドキュメントはこちら
$ clang -g -gdwarf-5 -gembed-source -o sample001 sample001.c
llvm-dwarfdumpで情報を表示します。
-a
オプションですべての情報を出力します。
$ llvm-dwarfdump -a sample001
今回は出力結果の以下の部分について説明をします。
llvm-dwarfdump
の出力結果の内容に以下のようなものが出力されます。
$ llvm-dwarfdump -a sample001
<省略>
file_names[ 0]:
name: "sample001.c"
dir_index: 0
md5_checksum: f2c9e6c49dc46644f6dbcdb88625f856
source: "#include <stdio.h>\n\nint main(void){\n printf(\"hello\\n\");\n return 0;\n}\n"
Address Line Column File ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x0000000000401130 3 0 0 0 0 is_stmt
0x000000000040113f 4 5 0 0 0 is_stmt prologue_end
0x0000000000401150 5 5 0 0 0 is_stmt
0x0000000000401158 5 5 0 0 0 is_stmt end_sequence
<省略>
ここに記載されているAddress(0x0000000000401130, 0x000000000040113f,
0x0000000000401150, 0x0000000000401158)がなにかというと
コンパイル後の命令が置かれるアドレスになります。
llvm-objdump
コマンドで確認をしてみます。
以下の★箇所を見ると上記llvm-dwarfdump
で出力されたアドレスと一致しています。
$ llvm-objdump -d -S sample001 | grep -A 20 main
0000000000401130 <main>:
; int main(void){
401130★: 55 pushq %rbp
401131: 48 89 e5 movq %rsp, %rbp
401134: 48 83 ec 10 subq $16, %rsp
401138: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
; printf("hello\n");
40113f★: 48 bf 04 20 40 00 00 00 00 00 movabsq $4202500, %rdi
401149: b0 00 movb $0, %al
40114b: e8 e0 fe ff ff callq 0x401030 <printf@plt>
; return 0;
401150★: 31 c0 xorl %eax, %eax
401152: 48 83 c4 10 addq $16, %rsp
401156: 5d popq %rbp
401157: c3 retq
401158★: 0f 1f 84 00 00 00 00 00 nopl (%rax,%rax)
ここで、もう一度llvm-dwarfdump
の結果を確認します。
$ llvm-dwarfdump -a sample001
<省略>
Address Line Column File ISA Discriminator Flags
------------------ ------ ------ ------ --- ------------- -------------
0x0000000000401130 3 0 0 0 0 is_stmt
0x000000000040113f 4 5 0 0 0 is_stmt prologue_end
0x0000000000401150 5 5 0 0 0 is_stmt
0x0000000000401158 5 5 0 0 0 is_stmt end_sequence
<省略>
二列目のLineについてはコードの行数になります。
最初に例として書いたコードをもう一度記載します(コメントに行数を書いています。)
#include <stdio.h> // 1
// 2
int main(void){ // 3
printf("hello\n"); // 4
return 0; // 5
} // 6
もう一度 llvm-dwarfdump
の出力を確認します。
今度はコード部の箇所に★とコード上の行数を記載しました。
$ llvm-objdump -d -S sample001 | grep -A 20 main
0000000000401130 <main>:
; int main(void){★ // 3
401130: 55 pushq %rbp
401131: 48 89 e5 movq %rsp, %rbp
401134: 48 83 ec 10 subq $16, %rsp
401138: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
; printf("hello\n");★ // 4
40113f: 48 bf 04 20 40 00 00 00 00 00 movabsq $4202500, %rdi
401149: b0 00 movb $0, %al
40114b: e8 e0 fe ff ff callq 0x401030 <printf@plt>
; return 0;★ // 5
401150: 31 c0 xorl %eax, %eax
401152: 48 83 c4 10 addq $16, %rsp
401156: 5d popq %rbp
401157: c3 retq
401158: 0f 1f 84 00 00 00 00 00 nopl (%rax,%rax)
llvm-objdump
の出力とllvm-dwarfdump
の情報が一致していることがわかりました。
まとめ
デバッガで、指定した行でブレークポイントを設定する、ということを
やりますが、そのときは今回書いたDWARFの情報(llvm-dwarfdump
で出力された情報)を
使用しているのでしょう(きっと)。
関連
Discussion