Mosh のスタックトレース改善に関して悩み中
スタックトレースの途中に落ちてしまうことがあるのでそれを改善したい。
原因は単純で関数の呼び出しフレームを過去にさかのぼる際に、1つ前のフレームの位置が正しくつかめておらず、たまにアクセスしてはいけないところにアクセスしてしまっている。
なぜアクセスしてはいけないかというと、実装上の理由で、 Direct threaded とか tag bit 不足が原因。
さて何らかのエラーが起きたときはその時点 fp (フレームポインタレジスタ)から巻きもどしてソースコード情報や呼び出し履歴を表示するのだけど。
今の Mosh のフレームは
========================================== 固定長のFrame ヘッダ(let と call でサイズが違う) closure, fp などのレジスタが push されている ========================================== arg0 ========================================== arg1 ========================================== arg2 ========================================== <== fp
こんな感じ。まあ普通。
この fp から1つ前の fp をどう見つけるか?
実は固定長のヘッダには 1つ前の fp が入っていて、 現在の fp から arg の数 + 固定オフセットの位置にある。
ただしエラーが起きたときには、可変長の arg の個数は(現在の実装では)知りようがない。
ので正確に fp をたどることができない。
雑にやるならば、argの個数を覚えるレジスタを追加する(←えー)。
他には fp が「引数を参照することにしか使われていない」という状況を利用して
========================================== 固定長のFrame ヘッダ(let と call でサイズが違う) closure, fp などのレジスタが push されている ========================================== <== fp arg0 ========================================== arg1 ========================================== arg2 ==========================================
のように fp の場所を変えるとか。
ただしこれをやるには、let に突入したときの fp を設定するタイミングで、let の変数の個数という情報が必要になり命令が長くなる。
うーん。何か見落としているかなあ。