Luaデバッガの使い方 - yappy/Qol GitHub Wiki

コマンド一覧

(help のコピペ)

help [<cmd>...]
        コマンドリスト、コマンド詳細説明表示
conf
        Lua バージョンとコンパイル時設定表示
mem [-gc]
        メモリ使用状況表示
bt
        バックトレース(コールスタック)表示
fr [<frame_no>]
        カレントフレームの変更、カレントフレームの情報表示
eval <lua_script>
        Lua スクリプトの実行
watch [<lua_script> | -d <number>]
        ウォッチ式の登録
src [-f <file>] [<line>] [-n <numlines>] [-all]
        ソースファイルの表示
c
        続行(continue)
s
        ステップイン(step)
n
        ステップオーバー(next)
out
        ステップアウト
bp [-d] [-f <filename>] [<line>...]
        ブレークポイントの設置/削除/表示

困ったら

help コマンドで上記のコマンド一覧を表示できます。

help <コマンド名> でそのコマンドの詳細な説明を表示できます。

デバッガの起動

F12キーで止める

サンプルは F12 キーが押されていると Lua コードの最初で止まるようにしてあります。 メインチャンクの最初で止めたい場合は起動中に F12 を押しっぱなしにしてください。

エラーで止める

Lua の実行時エラーが発生すると自動でデバッガに入ります。 error() 関数や assert() 関数で自発的にエラーを起こす手もあります。

状況の確認

(自動で大まかな情報が出ることもありますが)まずは現在の実行位置を把握しましょう。

例: エラーが起きました(わざと起こしました)。

[LuaDbg] ***** Lua error occurred *****
../sampledata/sub.lua:6: test error
stack traceback:
        [C]: in function 'error'
        ../sampledata/sub.lua:6: in local 'test_error'
        ../sampledata/sub.lua:8: in local 'test_func'
        ../sampledata/sub.lua:10: in main chunk
        [C]: in field 'include'
        ../sampledata/test.lua:15: in main chunk
[LuaDbg] Check "bt" and "fr <callstack>"
[LuaDbg] "help" command for usage

バックトレースの確認

バックトレース(関数の呼び出し履歴)は bt コマンドで表示できます。

[LuaDbg] > bt
[frame #0] ? (C) =[C]:-1
[frame #1] error (C) =[C]:-1
[frame #2] test_error (Lua) @../sampledata/sub.lua:6
[frame #3] test_func (Lua) @../sampledata/sub.lua:8
[frame #4] ? (main) @../sampledata/sub.lua:10
[frame #5] include (C) =[C]:-1
[frame #6] ? (main) @../sampledata/test.lua:15

一番上 (frame #0) が今いる位置です。

Lua では関数は値の一種なので限界はありますが、一番左が関数名と思われるデータです(変数に入った関数を呼び出した場合、その変数名が入る)。 分からない場合は ? になることもあります。 (main) は Lua チャンク(ファイル全体からなる1関数)、(Lua) が Lua 関数、(C) が C 関数を表します。 @ 以下はファイル名と行番号です。

カレントフレームの設定と情報表示

バックトレースを確認したら、次に情報を見たいフレーム番号を指定して fr <frame_no> コマンドを実行します。 fr <frame_no> コマンドはカレントフレームを指定した番号に設定し、そのフレームの情報を表示します。 パラメータなしで fr を呼ぶと、カレントフレームの情報を再度表示します。 カレントフレームはデバッガに入るたびにスタックトップ (frame #0) に自動的に設定されます。

先ほどの bt で Lua の一番上が frame #2 だったので、fr 2 を確認してみます。

[LuaDbg] > fr 2
[frame #2] test_error (Lua) @../sampledata/sub.lua:6
 o     1: print("print test");
 o     2: trace.write("alice", "takenoko", "takenoko", "alice");
       3:
       4: local function test_func()
       5:   local function test_error()
>o     6:     error("test error");
 o     7:   end
 o     8:   test_error();
 o     9: end
 o    10: test_func();
      11:
      12: -- inf loop test
      13: -- while true do end
      14:
      15: -- file test
 o    16: local a, b, c = sys.readFile("takenoko.txt");
Local variables:
Upvalues:
[  1] _ENV = (table)

test.lua からの呼び出し箇所は fr 6

[LuaDbg] > fr 6
[frame #6] ? (main) @../sampledata/test.lua:15
       5:   int cx = 0, int cy = 0, float angle = 0.0f,
       6:   float scaleX = 1.0f, float scaleY = 1.0f, float alpha = 1.0f);
       7:
       8: void drawString(resourceSetId, resourceId,
       9:   str *str, int dx, int dy,
      10:   uint32_t color = 0x000000, int ajustX = 0,
      11:   float scaleX = 1.0f, float scaleY = 1.0f, float alpha = 1.0f,
      12:   /* int *nextx = nullptr, int *nexty = nullptr */);
      13: ]]--
      14:
>o    15: sys.include("../sampledata/sub.lua");
      16:
 o    17: trace.write("sinki", "sinki", "return", "sinki", "sinki", "gg");
      18:
 o    19: local dbg_x, dbg_y = 3, 5;
      20: local function dbg_test(t)
 o    21:   if t > 0 then
 o    22:     trace.write(dbg_y);
 o    23:     return dbg_test(t - 1);
      24:   end
 o    25: end
Local variables:
Upvalues:
[  1] _ENV = (table)

ブレークポイントの設定

ブレークポイント(実行中に特定の行で止まる機能)の使い方を説明します。 一旦エラーが起きるコードはやめて、起動時 F12 でチャンク実行開始時に止めます。

ソースファイルのもっと別の場所を見たい場合は src コマンドを使います。 <line> は中心となる行番号、<numlines>' は表示する行数、-all` をつけると全行を出力します。 ファイル名と行番号はデフォルトではカレントフレームのものが使われます。

行の見方

  • o はブレークポイント設置可能行を表します。
  • * はブレークポイント設置行を表します。
  • > は現在実行中の行を表します。
[LuaDbg] > help src
ソースファイルの表示
Usage: src [-f <file>] [<line>] [-n <numlines>] [-all]

[LuaDbg] > src -all
(略)
 o    64: function update(keyinput)
 o    65:   trace.perf("update start");
      66:
 o    67:   frame = frame + 1;
      68:
 o    69:   local amount = 4;
 o    70:   if keyinput["UP"] then
 o    71:     unyopos.y = unyopos.y - amount;
      72:   end
 o    73:   if keyinput["DOWN"] then
 o    74:     unyopos.y = unyopos.y + amount;
      75:   end
 o    76:   if keyinput["LEFT"] then
 o    77:     unyopos.x = unyopos.x - amount;
      78:   end
 o    79:   if keyinput["RIGHT"] then
 o    80:     unyopos.x = unyopos.x + amount;
      81:   end
(略)

70 行目にブレークポイントを設置してみましょう。 ブレークポイント操作には bp コマンドを使います。 やはりデフォルト値はカレントフレームのものが使われます。

[LuaDbg] > help bp
ブレークポイントの設置/削除/表示
Usage: bp [-d] [-f <filename>] [<line>...]

ブレークポイントを設定します。引数を指定しない場合、ブレークポイント一覧を表示し
ます。-d を指定すると削除します。

[LuaDbg] > bp 70
Breakpoints:
[@../sampledata/test.lua]
70

ブレークポイントを設定したら、c (continue) コマンドで実行を再開します。 (F12 が複数の関数に効いてしまう場合は目当てのブレークポイントで止まるまで c コマンドを実行してください)

[LuaDbg] ***** break *****
? (Lua) @../sampledata/test.lua:70
 o    60: function exit()
 o    61:   sound.stopBgm();
 o    62: end
      63:
 o    64: function update(keyinput)
 o    65:   trace.perf("update start");
      66:
 o    67:   frame = frame + 1;
      68:
 o    69:   local amount = 4;
>*    70:   if keyinput["UP"] then
 o    71:     unyopos.y = unyopos.y - amount;
      72:   end
 o    73:   if keyinput["DOWN"] then
 o    74:     unyopos.y = unyopos.y + amount;
      75:   end
 o    76:   if keyinput["LEFT"] then
 o    77:     unyopos.x = unyopos.x - amount;
      78:   end
 o    79:   if keyinput["RIGHT"] then
 o    80:     unyopos.x = unyopos.x + amount;
[LuaDbg] "help" command for usage
[LuaDbg] >

スタックトップの状況を fr で確認すると

[LuaDbg] > fr
[frame #0] ? (Lua) @../sampledata/test.lua:70
 o    60: function exit()
 o    61:   sound.stopBgm();
 o    62: end
      63:
 o    64: function update(keyinput)
 o    65:   trace.perf("update start");
      66:
 o    67:   frame = frame + 1;
      68:
 o    69:   local amount = 4;
>*    70:   if keyinput["UP"] then
 o    71:     unyopos.y = unyopos.y - amount;
      72:   end
 o    73:   if keyinput["DOWN"] then
 o    74:     unyopos.y = unyopos.y + amount;
      75:   end
 o    76:   if keyinput["LEFT"] then
 o    77:     unyopos.x = unyopos.x - amount;
      78:   end
 o    79:   if keyinput["RIGHT"] then
 o    80:     unyopos.x = unyopos.x + amount;
Local variables:
[  1] keyinput = (table)
[  2] amount = (number) 4
Upvalues:
[  1] _ENV = (table)
[  2] frame = (number) 1
[  3] unyopos = (table)
[  4] add_co = (function)
[  5] colist = (table)

現在位置のほかに、この関数フレームの持っているローカル変数や upvalue 情報が表示されています。

ローカル変数

この関数内で local x; のようにローカル宣言した変数の他、この関数の引数もローカル変数として扱われています。

upvalue (上位値)

この関数の外側の関数で宣言されたローカル変数です。 ある関数が、どの外側の変数に参照を持つかはコンパイル時に決定され、この関数内で使わなかった外部変数はここに表示されることもないことに注意してください。 _ENV はグローバル変数テーブルです(グローバル変数へのアクセスは _ENV.var のようにコンパイルされるのでした)。

実行再開コマンドの種類

  • c 続行(continue) 実行を再開します。ブレークポイントやエラーが発生するまで停止しません。
  • s ステップイン(step) 次の行まで実行します。関数の中に入った場合、その中の最初の行で停止します。
  • n ステップオーバー(next) 次の行まで実行します。関数の中に入った場合、そこから返ってくるまで停止しません。
  • out ステップアウト 現在いる関数から抜けるまで実行します。

値の評価 (eval)

では、ローカル変数(グローバル変数も可)の中身を覗いてみましょう。 値の評価(といよりも Lua コードの実行)には eval コマンドを使います。

[LuaDbg] > help eval
Lua スクリプトの実行
Usage: eval <lua_script>

引数を連結して Lua スクリプトとしてカレントフレーム上にいるかのように実行します。
Local variables:
[  1] keyinput = (table)
[  2] amount = (number) 4
Upvalues:
[  1] _ENV = (table)
[  2] frame = (number) 1
[  3] unyopos = (table)
[  4] add_co = (function)
[  5] colist = (table)
[LuaDbg] > eval keyinput
(table)
K   (string) MUTE
V   (boolean) false
K   (string) RCONTROL
V   (boolean) false
K   (string) COMMA
V   (boolean) false
K   (string) NUMLOCK
V   (boolean) false
K   (string) CAPITAL
V   (boolean) false
K   (string) WEBHOME
V   (boolean) false
K   (string) KANA
V   (boolean) false
K   (string) Z
V   (boolean) false
(略)

keyinput 引数には、キーボードの名前を表す文字列をキー、押されているかを表す boolean 値を値とするテーブルが渡されていることが分かりました。

[LuaDbg] > eval unyopos
(table)
K   (string) y
V   (number) 350
K   (string) x
V   (number) 500

関数の外側 (チャンクローカル) で宣言したテーブル変数の中身も見えます。 うにょうにょの座標ですね。

Lua 式の実行 (eval)

eval コマンドは Lua コードの実行であり、値の書き換えにも使えます(取り扱い注意)。

`unyopos.x, unyopos.y' にそれそれ 0 を代入してみます。

[LuaDbg] > eval unyopos.x, unyopos.y = 0, 0;
OK (No return values)

[LuaDbg] > eval unyopos
(table)
K   (string) y
V   (number) 0
K   (string) x
V   (number) 0

テーブルの内容が変わっています。 ブレークポイントを bp -d で消して c コマンドで再開してみると、うにょうにょの座標が (0, 0) に変わっています(画像略)。

[LuaDbg] > bp -d 70
Breakpoints:
[@../sampledata/sub.lua]
(No breakpoints)
[@../sampledata/test.lua]
(No breakpoints)

[LuaDbg] > c
[LuaDbg] continue...

ウォッチ式

ブレーク時に自動で eval される式を登録できます。

⚠️ **GitHub.com Fallback** ⚠️