yhara.jp

Recent Posts

LLVM本体にデバッグログを入れる

2021-10-01
Tech

LLVMのエラーメッセージはあまり親切でない。Rustの異常な親切さに慣れてきたのでそう思うのかもしれないが。

例えばllvm-disの出したエラーがこれ:

Assertion failed: (InitVal->getType() == getValueType() && "Initializer type must match GlobalVariable type"), function setInitializer, file /Users/yhara/research/llvm-12.0.1.src/lib/IR/Globals.cpp, line 405.

型が違うことはなんとか分かるが、せめて何と何だったのかくらいは教えてくれないとデバッグのしようがない。

まあ不正なデータでも食わせない限りLLVMのエラーを見ることはないかもしれないが、LLVMを使った処理系を書いていると不正なデータが生成されてしまったりするのである。

ということでllvm-disにデバッグログを入れてみた。ありがたいことにファイル名と行番号が出ているので、そこにコードを足す。

    if (InitVal->getType() != getValueType()) {
      InitVal->getType()->print(dbgs());
      getValueType()->print(dbgs());
    }
    assert(InitVal->getType() == getValueType() &&
           "Initializer type must match GlobalVariable type");

LLVMの作法は全然わかっていないが、Typeについてはprintというメソッドで調べられるようだ。dbgsは何らかのIOだと思うが、--debugオプションを付けないと表示されないので注意。

この状態で改めて実行してみるとこうなった。(コンパイル方法については一つ前の記事を参照)

$ ./bin/llvm-dis --debug ~/proj/shiika/examples/a.sk.bc
Args: ./bin/llvm-dis --debug /Users/yhara/proj/shiika/examples/a.sk.bc
%"Meta:A"**%"Meta:A"*Assertion failed: (InitVal->getType() == getValueType() && "Initializer type must match GlobalVariable type"), function setInitializer, file /Users/yhara/research/llvm-12.0.1.src/lib/IR/Globals.cpp, line 405.

改行がなくて分かりづらいが、 InitVal->getType()%"Meta:A"**で、getValueType()%"Meta:A"*であることが分かった。これでなんとかデバッグが続けられそうだ。

おまけ

ちなみにどんな原因でこのエラーが出ていたかというと、これが原因だった。

-            let null = self.llvm_type(ty).ptr_type(AddressSpace::Generic).const_null();
+            let null = self.llvm_type(ty).into_pointer_type().const_null();

上は%"Meta:A"** nullで、下は%"Meta:A"* nullになる。(と思う)

同じコードで生成した.llではどっちも

@"::A" = global %"Meta:A"* null

になるのが不思議だが。

More posts

Posts

(more...)

Articles

(more...)

Category

Ads

About

About the author