Perl6(nqp)とMoarVMのデバッグを行う手順

背景

皆さんお元気ですか.私はげんきです. さて人間生きているとPerl,とりわけPerl6に興味が出てくると思います. Perl6に興味を持ったが最後,実際の内部処理などが気になり夜も眠れない日が続くと思います.

今日はそんなみなさんにPerl6の実装であるMoarVMとRakudoのサブセットであるnqpのデバッグについてお教えします.

MoarVMの用意

MoarVMは現在GitHubにて公開されています. 通常使う文にはrakudo-starなどがありますが今回はデバッグソースコードから落としてきます.

$ git clone https://github.com/MoarVM/MoarVM.git

Configure.pl

落としてきたMoarVMですが,ここでPerl製のMakefile生成ツールであるConfigure.plを使います. なおこのツールですがカレントディレクトリにConfigure.plがないと実行できないという技があります.気をつけましょう.

Configure.plにはいくつかオプションがありますが,今回利用するものをピックアップします

  • cc
  • debug
    • debugオプション
  • --no-optimize
  • compiler
  • toolchain
    • "posix", "gnu", "bsd" and "msvc"のツールチェインを選択可能
  • prefix
    • make installの先を指定

なので例えば次のようになります. これは独自gccコンパイラを指定している感じです.

$ ./Configure.pl --cc /usr/local/x86-cbc/bin/gcc --debug --no-optimize --compiler gcc --prefix=src/build_perl6/MoarVM

make install

ここまで来たら make と make installを実行します

$ make && make install

ここまで来るとローカルとbuildのprefixさきに moarというバイナリが生成されています. こちらがmoarVMのバイナリとなっています.

さてMoarVMは用意できましたが動かすnqpをinstallしていません.別途installします.

NQP

NQPとは Not Quite Perl の略でPerl6のサブセット.つまりPerl6の簡易版であり,コンパイラ開発者用に設計された単純なPerl6です.

こちらもGitHubで展開されています.

NQPの用意

まずは同じようにgit cloneしましょう

$git clone git://github.com/perl6/nqp.git

これも同じようにConfigure.plがあります. 今回はバックエンドとして先程buildしたmoarを使うので指定を行います

$ ./Configure.pl --prefix=src/build_perl6/nqp --backends=moar --with-moar=src/build_perl6/MoarVM/bin/moar
  • オプション
  • prefix
    • ビルド先
  • backends
    • NQPが走るVMを選択する
  • --with-moar
    • MoarVMを使う場合MoarVMのパス

ここまで出来たら

$ make && make install

を実行しましょう.

NQPの実態

さてbuildできたnqpですが,実はこれはバイナリファイルではありません. 証拠にファイルの種類を確認するfileコマンドを入力してみましょう

$file nqp
nqp: POSIX shell script, ASCII text executable

なんとnqpはただのシェルスクリプトなのです.

中身は主に二種類あり,ソースコード側では

#!/bin/sh
exec src/build_perl6/MoarVM/bin/moar nqp.moarvm "$@"

prefix先では

 cat nqp
#!/bin/sh
exec src/build_perl6/MoarVM/bin/moar --libpath=src/build_perl6/nqp/share/nqp/lib src/build_perl6/nqp/share/nqp/lib/nqp.moarvm "$@"

となっています.デバッグ用のlldb/gdbではシェルスクリプトをかませることが出来ないのでここは

exec以下をコピーして

lldb src/build_perl6/MoarVM/bin/moar nqp.moarvm のように実行します

anatofuz lldb  src/build_perl6/MoarVM/bin/moar nqp.moarvm
Current executable set to 'src/build_perl6/MoarVM/bin/moar' (x86_64).

ここまでいくとデバッグできるので例えばmainにデバックポイントをかけて

(lldb) b main
Breakpoint 2: where = moar`main + 24 at main.c:144, address = 0x00000000004012dc
(lldb) run
Process 107353 launched: 'src/build_perl6/MoarVM/bin/moar' (x86_64)
Process 107353 stopped
* thread #1: tid = 107353, 0x00000000004012dc moar`main(argc=2, argv=0x00007fff6aebbea8) + 24 at main.c:144, name = 'moar', stop reason = breakpoint 2.1
    frame #0: 0x00000000004012dc moar`main(argc=2, argv=0x00007fff6aebbea8) + 24 at main.c:144
   141     {
   142         MVMInstance *instance;
   143         const char  *input_file;
-> 144        const char  *executable_name = NULL;
   145         const char  *lib_path[8];
   146
   147     #ifdef _WIN32
]

などと出来ます! これでPerl6のデバッグが出来て夜も眠れますね!