luaのエラーイベントハンドラ
lua_pcallのイベントハンドラのお話です。
エラー時点のスタック情報を欲しいなぁ〜って思いまして、リファレンスのlua_pcall項目を見ておりますと、「イベントハンドラ」「イベントハンドラ」「イベントハンドラ」と書かれております。
http://sugarpot.sakura.ne.jp/yuno/html/lua51_manual_ja.html#lua_pcall
が、イマイチよくわかりません。
とりあえず、lua関数(function型)をスタックにぶち込んで、そのスタックを第4引数に指定するんですよ〜と言うことのようです。
さて問題はこのイベントハンドラの型なんですが、「エラーメッセージを引数としてこの関数が呼ばれ、その戻り値が lua_pcall から返されるエラーメッセージとなる」とあるので、たぶんこういう事なんでしょう。
-- lua function errorhandler(s) return s; end;
これをスタックに積んでpcallするわけです。
大抵の場合は、スタックを積む前にlua_gettopでスタックインデックス値を取得したりするでしょうから、マイナス指定(相対指定)するよりも、何も考えずインデックス値に+1(絶対指定)すれば楽ですね。
// c t = lua_gettop(L); lua_getglobal(L,"errorhandler"); //errorhandler(s)を積む lua_getglobal(L,????); //cから呼ぶlua関数 ...引数をpush... lua_pcall(L, ?,?,t+1); //errorhanderのstack位置はt+1 lua_settop(t);
すると、イベントハンドラを指定しない場合と同じ結果が得られました。
そのまま返してるので当然ですね。
後は、lua側の「function errorhandler(s)」に、ローカルスタック情報や、実行時の関数情報などを取得するコードを組み込めば完成です。
その結果を文字列で返すにはちょっと膨大でしょうから、lua側にcのコールバック関数を登録しておいて、その情報をアプリにコールバックさせるのが最もシンプルでしょう。
面倒ならグローバルに置いておいて、エラー後にアプリで回収するのも悪くないかと思ったりします。
エラーの発生したluaマシンでスタック情報収集するのはとっても危険に感じられますが、これも慣れですよね。