yhara.jp

Recent Posts

lldbでLLVMプログラムをデバッグする

2021-02-28
Tech

Rust + LLVMで自作プログラミング言語Shiikaを作っているのだが、開発中に遭遇するエラーには以下の種類がある。

  1. rustcがエラーを吐く(=.rsに問題がある)。
  2. rustcは通ったが、Shiikaのエラーが出る(=.skに問題があるorバグで問題があると誤判定している)。
  3. rustcは通ったが、llcがエラーを吐く(=.llの生成に問題がある)。
  4. llcが実行ファイルを生成したが、実行すると期待通りに動かない。

一番面倒なのはもちろん最後のケースだが、これもさらにいくつかの種類に分けられる。

  1. 期待通りに動かないが、最後まで実行はできる(=Shiikaで書いたプログラムに間違いがある)。
  2. 最後まで実行できず、途中で落ちてしまう。

前者は普通にShiikaのpメソッドとかでデバッグするだけだが、後者は.llの生成に問題があり、しかもllcがエラーを検知できないというケース。こういうときはlldbを使う。

lldb

lldb examples/a.sk.out みたいにして起動。run で実行するとこんな感じの情報が出る。

(lldb) run
Process 56119 launched: '/Users/yhara/Dropbox/proj/shiika/examples/a.sk.out' (x86_64)
expected 99
i: 1 j: 4
Process 56119 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
    frame #0: 0x0000000100010422 a.sk.out`lambda_31 + 818
a.sk.out`lambda_31:
->  0x100010422 <+818>: ud2
    0x100010424 <+820>: nopw   %cs:(%rax,%rax)
    0x10001042e <+830>: nop

a.sk.out`main:
    0x100010430 <+0>:   pushq  %rax

btでバックトレースを表示できる。

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
  * frame #0: 0x0000000100010422 a.sk.out`lambda_31 + 818
    frame #1: 0x00000001000064e3 a.sk.out`Array#each + 259
    frame #2: 0x000000010000ce32 a.sk.out`lambda_30 + 290
    frame #3: 0x000000010000e0cb a.sk.out`lambda_21 + 139
    frame #4: 0x00000001000064e3 a.sk.out`Array#each + 259
    frame #5: 0x00000001000073dc a.sk.out`Array#map + 268
    frame #6: 0x0000000100001466 a.sk.out`Meta:A#return_from_block + 262
    frame #7: 0x000000010000ff3a a.sk.out`user_main + 650
    frame #8: 0x0000000100010440 a.sk.out`main + 16
    frame #9: 0x00007fff6d3e3cc9 libdyld.dylib`start + 1

ということで.llの@lambda_31のところを見てみると、unreachable命令のところに到達してしまっていることがわかった。

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author