Lua偵錯


Lua提供了一個偵錯庫,它提供了建立自己的偵錯器的原始函式。 即使沒有內建的Lua偵錯器,也有許多第三方Lua偵錯器,由各種開發人員建立,其中許多是開源的。

下表中列出了Lua偵錯庫中可用的功能及其用法。

編號 方法 描述
1 debug() 進入用於偵錯的互動模式,該模式保持活動狀態,直到使用者只輸入一行中的cont並按Enter鍵。 使用者可以使用其他功能在此模式下檢查變數。
2 getfenv(object) 返回物件的環境。
3 gethook(optional thread) 返回執行緒的當前掛鉤設定,有三個值 - 當前掛鉤函式,當前掛鉤掩碼和當前掛鉤計數。
4 getinfo(optional thread, function or stack level, optional flag) 返回一個包含函式資訊的表。可以直接給出函式,或者可以給一個數位作為函式的值,在給定執行緒的呼叫堆疊的級別函式上執行的函式 - 級別0為當前函式(getinfo本身); 級別1為呼叫getinfo的函式;等等。 如果function是一個大於活動函式數的數位,則getinfo返回nil
5 getlocal(optional thread, stack level, local index)
6 getmetatable(value) 返回給定物件的元表,如果沒有元表,則返回nil
7 getregistry() 返回登錄檔表,這是一個預定義的表,任何C語言程式碼都可以使用它來儲存它需要儲存的任何Lua值。
8 getupvalue(function, upvalue index) 此函式返回upvalue的名稱和值,索引為函式func。 如果給定索引沒有upvalue,則函式返回nil
9 setfenv(function or thread or userdata, environment table) 將給定物件的環境設定為給定表,返回物件。
10 sethook(optional thread, hook function, hook mask string with "c" and/or "r" and/or "l", optional instruction count) 將給定函式設定為勾點。 字串掩碼和數位計數描述了何時呼叫掛鉤。 這裡,每次Lua呼叫,返回並分別輸入函式中的每一行程式碼時,都會呼叫crl
11 setlocal(optional thread, stack level, local index, value) 使用堆疊級別的函式的索引local將值賦給區域性變數。 如果沒有具有給定索引的區域性變數,則該函式返回nil,並且當使用超出範圍的級別呼叫時引發錯誤。 否則,它返回區域性變數的名稱。
12 setmetatable(value, metatable) 將給定物件的metatable設定為給定表(可以為nil)。
13 setupvalue(function, upvalue index, value) 此函式使用函式func的索引up將值賦給upvalue。 如果給定索引沒有upvalue,則函式返回nil。 否則,它返回upvalue的名稱。
14 traceback(optional thread, optional message string, optional level argument) 使用回溯構建擴充套件錯誤訊息。

上面的列表是Lua中完整的偵錯函式列表,經常使用一個上述函式的庫,並提供更簡單的偵錯。 使用這些函式並建立我們自己的偵錯器非常複雜,並不是優選的。 下面來看一個簡單使用偵錯功能的例子。

function myfunction ()
   print(debug.traceback("Stack trace"))
   print(debug.getinfo(1))
   print("Stack trace end")

   return 10
end

myfunction ()
print(debug.getinfo(1))

當執行上面的程式時,將獲得如下所示的堆疊跟蹤 -

Stack trace
stack traceback:
    test2.lua:2: in function 'myfunction'
    test2.lua:8: in main chunk
    [C]: ?
table: 0054C6C8
Stack trace end

在上面的範例程式中,使用偵錯庫中提供的debug.trace函式列印堆疊跟蹤。 debug.getinfo獲取函式的當前表。

偵錯範例

開發人員經常為了知道函式的區域性變數以進行偵錯。 為此,可以使用getupvalue和使用setupvalue並設定這些區域性變數。 一個簡單的例子如下所示 -

function newCounter ()
   local n = 0
   local k = 0

   return function ()
      k = n
      n = n + 1
      return n
   end

end

counter = newCounter ()

print(counter())
print(counter())

local i = 1

repeat
   name, val = debug.getupvalue(counter, i)

   if name then
      print ("index", i, name, "=", val)

      if(name == "n") then
         debug.setupvalue (counter,2,10)
      end

      i = i + 1
   end -- if

until not name

print(counter())

當執行上面的程式時,將獲得如下所示的堆疊跟蹤 -

1
2
index    1    k    =    1
index    2    n    =    2
11

在此範例中,計數器每次呼叫時都會更新一次。 可以使用getupvalue函式檢視區域性變數的當前狀態。 然後,將區域性變數設定為新值。 這裡,在呼叫set操作之前n2。 使用setupvalue函式,它更新為10。現在當呼叫計數器函式時,它將返回11而不是3

偵錯型別

在Lua中,偵錯型別主要有兩種 -

  • 命令列偵錯
  • 圖形化偵錯

1. 命令列偵錯

命令列偵錯是使用命令和列印語句在命令列進行偵錯的偵錯型別。 Lua有許多命令列偵錯器,下面列出了一些。

  • RemDebug - RemDebug是Lua 5.0Lua 5.1的遠端偵錯器。 它允許遠端控制另一個Lua程式的執行,設定斷點並檢查程式的當前狀態。 RemDebug 還可以偵錯CGILua指令碼。

  • clidebugger - 它是Lua 5.1的簡單命令列介面偵錯器,用純Lua編寫。 除了標準的Lua 5.1庫之外,它不依賴於任何其他東西。 它的靈感來自RemDebug,但沒有遠端工具。

  • ctrace - 用於跟蹤Lua API呼叫的工具。
  • xdbLua - 用於Windows平台的簡單Lua命令列偵錯程式。
  • LuaInterface Debugger - 它是LuaInterface的偵錯器擴充套件。 它將內建的Lua偵錯介面提升到更高的級別。與偵錯器的互動由事件和方法呼叫完成。
  • Rldb - 它是一個通過通訊端的遠端Lua偵錯器,可在Windows和Linux上使用。 它可以為您提供比現有功能更多的功能。
  • ModDebug - 這允許遠端控制另一個Lua程式的執行,設定斷點,並檢查程式的當前狀態。

2. 圖形偵錯

在IDE下可以進行圖形偵錯,在IDE中可為各種狀態(如變數值,堆疊跟蹤和其他相關資訊)進行視覺化偵錯。 借助斷點,步入,步進和IDE中的其他按鈕,可以實現視覺化表示和逐步控制執行。

Lua有許多圖形偵錯器,它包括以下內容-

  • SciTE - Lua的預設Windows IDE提供了多個偵錯工具,如斷點,步驟,步入,步進,監視變數等。
  • Decoda - 這是一個具有遠端偵錯支援的圖形偵錯器。
  • ZeroBrane Studio - Lua IDE整合了遠端偵錯器,堆疊檢視,監視檢視,遠端控制台,靜態分析器等。 適用於LuaJIT,Love2d,Moai和其他Lua引擎; Windows,OSX和Linux。
  • akdebugger - 這是Eclipse偵錯器和編輯器的Lua外掛。
  • luaedit - 這包括遠端偵錯,本地偵錯,語法突出顯示,完成建議列表,引數命題引擎,高階斷點管理(包括斷點和命中計數的條件系統),功能列表,全域性和區域性變數列表,監視,面向解決方案的管理。