デバッガとサンドボックス
スタックトレース、ブレークポイントとステップ実行、使えない標準ライブラリ
エラーとスタックトレース
捕まえられなかったエラー(pcall の外で起きたもの)は、メッセージの下にスタックトレースの先頭が付いてダイアログに出ます。
/lua/apps/demo/main.lua:12: attempt to index a nil value (field 'pos')
main.lua:12 move
main.lua:30 loop
トレースの全部はシステムログと、SDの /crash/lua_NNNN.txt(1回の起動で8件まで)に残ります。ファイルアプリで開けます。
自分でトレースを取りたいときは pico.traceback() を使います。
デバッガ
設定アプリの「その他」→「Luaデバッガ」を入れると、次に開いたLuaアプリから使えます。
止まるきっかけ:
| きっかけ | 書き方 |
|---|---|
| スクリプトの中で止める | pico.breakpoint("ここ") |
| 行のブレークポイント | pico.set_breakpoint("main.lua", 42)、またはPCから dbg b main.lua:42(下) |
| 捕まえられなかったエラー | 何もしなくてよい。エラーの起きた場所で止まり、変数を見られる(続けるとエラーとして進む) |
止まると画面がデバッガになります。
- 上: 止まった理由・場所(
main.lua:42 update)・メッセージ - ソース: SDのファイルから前後2行。止まった行は黄色
- スタック: タップすると、その段の変数を表示
- 変数: ローカル変数と、関数が使っている外側の
local(^countのように^付き)。タップで次のページ - ボタン: 続行 / 1行(関数の中にも入る)/ 次へ(関数は飛ばす)/ 抜ける(今の関数から戻るまで)/ 停止(スクリプトを打ち切る)
物理キーボードなら c(続行)s(1行)n(次へ)o(抜ける)q(停止)、コントローラーなら A(続行)・下(1行)・右(次へ)・上(抜ける)・HOME(停止)でも操作できます。
止まっている間はOS全体が止まります(音だけは鳴り続けます)。値は表示用に短くしたもので、テーブルは table(#要素数) とだけ出ます(メタメソッドは呼びません)。
PCからのコマンド(USBシリアル)
本体のUSBシリアル(PC版なら標準入力)へ1行ずつ送ります。
| コマンド | 意味 |
|---|---|
dbg b main.lua:42 | ブレークポイントを置く |
dbg d main.lua:42 / dbg d | 外す / 全部外す |
dbg l | 一覧 |
dbg pause | 次に実行する行で止める |
dbg c dbg s dbg n dbg o dbg q | (止まっている間)続行・1行・次へ・抜ける・停止 |
dbg bt / dbg locals [段] | (止まっている間)スタックと変数をシリアルへ出す |
ソースの行を出せるのは、SDから読み込んだファイル(アプリの main.lua 等)だけです。load(pico.sd_read(path)) で読んだファイルの行も出したいときは、2番目の引数に "@" .. path を渡してください(load(src, "@" .. path))。
サンドボックス
Luaアプリから使えない標準の機能があります。
| 使えないもの | 代わり |
|---|---|
debug ライブラリ | pico.traceback()、デバッガ |
io / dofile / loadfile / require / package | pico.sd_read() 等(SDカード)+ load() |
os.exit / os.execute / os.remove / os.rename / os.getenv / os.tmpname / os.setlocale | (os.time / os.clock / os.date / os.difftime は使える) |
string.dump、load() へのバイトコード | load() はテキストだけ読む |
__gc を持つメタテーブル(setmetatable がエラーにする) | 後片付けは画面を閉じる前に自分で行う |
__gc が使えないのは、ガベージコレクタから呼ばれる関数は命令数の上限で止められず、終わらないループがあるとOSごと固まってしまうためです。
print() はシステムログへ出ます(pico.log と同じ)。