背景
皆さんお元気ですか.私はげんきです. さて人間生きていると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
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のデバッグが出来て夜も眠れますね!