Mercurial > hg > Papers > 2019 > anatofuz-prosym
diff Paper/anatofuz.tex @ 25:7a2d604607d8
add debugging MoarVM
author | Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 09 Nov 2018 00:31:25 +0900 |
parents | d8f77d0a3452 |
children | df723be56106 |
line wrap: on
line diff
--- a/Paper/anatofuz.tex Thu Nov 08 23:16:52 2018 +0900 +++ b/Paper/anatofuz.tex Fri Nov 09 00:31:25 2018 +0900 @@ -287,19 +287,30 @@ また,明らかに異なる挙動を示す両者のmoarを利用しても同じ結果が返ってきてしまう. そのため今回のMoarVMBytecodeインタプリタの実装のデバッグにはこの方法は適さない. 従って実際に実行した命令を確認するにはgdbなどのCデバッガを利用してMoarVMを直接トレースする必要がある. -\lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt} + +CbC側はcbc\_nextにbreak pointを設定し,オリジナル側は次のオペコードの設定のマクロにダミーの関数を呼び出すように修正し,そこにbreak pointを設定する. +CbC側ではCodeSegmentの名前をデバッガ上で直接確認できるが,オリジナル版はLABLEの配列の添え字から自分でどのオペコードに対応しているかをデバッガの外で探す必要がある. + +添字を確認するためにはCode\ref{orig_b}に示すようにオリジナルのMoarVMの場合cur\_opの値をMVMuint16のポインタでキャストし,これが指す値を出力する. +break pointを掛けているダミー関数ではcur\_opにアクセスする事が出来ない為,スタックフレームを一つupする必要がある. +\lstinputlisting[label=orig_b, caption=オリジナル版MoarVMに対してのbreak point設定]{./src/origin_b_set.txt} \subsection{MoarVMの並列デバッグ手法} しかしMoarVMが実行する命令は膨大な数がある. その為gdbでMoarVMをCbCとオリジナル版での並列デバッグを人間が同時に行うことは困難である. Perlなどのスクリプトを用いて自動的に解析したいため,ログを残す為にscriptコマンドを実行した状態でgdbを起動する. -CbC側はcbc\_nextにbreak pointを設定し,オリジナル側は次のオペコードの設定のマクロにダミーの関数を呼び出すように修正し,そこにbreak pointを設定する. -CbC側ではCodeSegmentの名前を直接確認できるが,オリジナル版はLABLEの配列の添え字から自分でどのオペコードに対応しているかを探す必要がある. + + +\lstinputlisting[label=debug_origmoar, caption=オリジナル版MoarVMのバイトコードのトレース]{./src/origin_breakpoint.txt} + CbCとオリジナルのCODES,LABELの添字は対応している為,ログの解析を行う際はそれぞれの添字を抽出し違いが発生している箇所を探索する. +これらはscriptコマンドが作成したログを元に異なる箇所を発見するスクリプトを用意し自動化する. +\lstinputlisting[label=logs2, caption=バイトコードの差分検知の一部分]{./src/logs2.txt} + 違いが生じている箇所が発見できた場合,その前後のCodeSegment及びディスパッチ部分にbreak pointをかけ,それぞれの変数の挙動を比較する. 主にcbc\_return系の命令が実行されている場合は,その直前で命令を切り替えるcbc\_invoke系統の命令が呼ばれているが,この周辺で何かしらの違いが発生している可能性が高い. -またCbCコンパイラのバグが生じている可能性もある為,アセンブラレベルの命令を確認しながらデバッグを進めることとなる. +また主に次のCodeSegmentに遷移する際にCbCコンパイラのバグが生じている可能性もある為,アセンブラレベルの命令を確認しながらデバッグを進めることとなる. @@ -310,9 +321,11 @@ その為DSの構造体の値が書き換わり,CからDSにreturnした際にDSの構造体が破壊されるバグである. このバグは先程の並列デバッグを行いながらプログラムカウンタや変数の動きをトレースする事などで発見することが出来る. 現状ではCbCコンパイラがプログラマの意図と反する挙動を取るためCbCコンパイラのバグを回避するプログラミングが要求されている. -本来コンパイラ側のバグを回避するプログラミングをプログラマに要求するスタイルは好ましくない. +本来コンパイラ側のバグを回避するプログラミングをプログラマに要求する事は好ましくない. 従ってCbCコンパイラ自身の信頼性を向上させる事も今後の課題となっている. +また現在はclang上に実装したCbCコンパイラではtaill call除去のエラーが発生してしまう為コンパイルする事が出来ない. +その為現在はgcc上に実装したcbcコンパイラを利用しgdbを利用しデバッグを行う. \subsection{Threaded Code} CbCはCodeSegmentで末尾最適化(Tail call optimization)を行う. これはCodeSegmentは必ず関数呼び出しではなくgotoで次の状態に遷移する為にスタック領域の操作が必要とならない為である. @@ -330,7 +343,7 @@ これはPerl5内部で利用しているPerlバイトコードを,PerlのC APIであるXS言語の様なCのソースファイルに埋め込み,それをCコンパイルでコンパイルするというものである. perlccを利用することでPerlインタプリタが無い状況でも可動するバイナリファイルを作成する事が可能である. しかしPerlccはPerlスクリプトが複雑になるほど正確にCに移植を行う事が出来ず,現在ではPerlのコアモジュールから外されている. -PerlccはPerlのバイトコードをCに変換しただけであり,Cで実装されているPerl経由で実行した場合と処理速度はほぼ変わらない. +PerlccはPerlのバイトコードをCへの変換のみ行う為,Cで実装されているPerl経由で実行した場合と処理速度はほぼ変わらない. またPerlccで生成されたCのソースコードは難解であり,これをデバッグするのが困難でもある. MoarVMでthreaded codeを実現出来た場合,その箇所のみCbCプログラムとして切り出す事が可能である為perlccと似たツールを作成することも可能である. この場合,Perl6を通常動かした際とは異なりバイトコードインタプリタに到達する前の処理が無くなる為多少の高速化が望めると推測できる. @@ -349,7 +362,7 @@ CbCMoarVMの場合,CodeSegmentとして基本ブロックを記述出来る為オリジナルのMoarVMの様にswtich文のブロック中に書く必要性が無くなる. その為類似する命令系をコード分割し,モジュール化する事が可能である. -これは通常のインタプリタの実装と比べ可読性と言う意味とモノリシックアーキテクチャをマイクロ化出来るという意味でも利点である. +これは通常のインタプリタの実装と比べ可読性と言う意味とCodeSegmentを再利用ができ,さらに分割可能という意味でも利点である. \subsubsection{MoarVMのデバッグ} MoarVMのバイトコードインタプリタの箇所はオリジナルの実装ではラベルジャンプを用いて実装されている.