鍍金池/ 教程/ Java/ 調(diào)試
數(shù)據(jù)庫訪問
循環(huán)
數(shù)組
錯誤處理
面向?qū)ο?/span>
調(diào)試
游戲開發(fā)
文件 I/O
變量
迭代器
Web 編程
模塊
函數(shù)
元表
協(xié)程
垃圾回收機制
標(biāo)準(zhǔn)庫
決策
數(shù)據(jù)類型
運行環(huán)境
操作符
字符串
基本語法
概述

調(diào)試

Lua 提供一個調(diào)試庫,這個庫中提供了創(chuàng)建自己的調(diào)試器所需的所有原語函數(shù)。雖然,Lua 沒有內(nèi)置調(diào)試器,但是開發(fā)者們?yōu)?Lua 開發(fā)了許多的開源調(diào)試器。

Lua 調(diào)試庫包括的函數(shù)如下表所示。

S.N. 方法和描述
1 debug():
進入交互式調(diào)試模式,在此模式下用戶可以用其它函數(shù)查看變量的值。
2 getfenv(object):
返回對象的環(huán)境。
3 gethook(optional thread):
返回線程當(dāng)前的鉤子設(shè)置,總共三個值:當(dāng)前鉤子函數(shù)、當(dāng)前的鉤子掩碼與當(dāng)前的鉤子計數(shù)。
4 getinfo(optional thread,function or stack leve,optional flag):
返回保存函數(shù)信息的一個表。你可以直接指定函數(shù),或者你也可以通過一個值指定函數(shù),該值為函數(shù)在當(dāng)前線程的函數(shù)調(diào)用棧的層次。其中,0 表示當(dāng)前函數(shù)(getinfo 本身);層次 1 表示調(diào)用 getinfo 的函數(shù),依次類推。如果數(shù)值大于活躍函數(shù)的總量,getinfo 則返回 nil。
5 getlocal(optional thread,stack level,local index):
此函數(shù)返回在 level 層次的函數(shù)中指定索引位置處的局部變量和對應(yīng)的值。如果指定的索引處不存在局部變量,則返回 nil。當(dāng) level 超出范圍時,則拋出錯誤。
6 getmetatable(value):
返回指定對象的元表,如果不存在則返回 nil。
7 getregistry():
返回寄存器表。寄存器表是一個預(yù)定義的用于 C 代碼存儲 Lua 值的表。
8 getupvalue(func function,upvalue index):
根據(jù)指定索引返回函數(shù) func 的 upvalue 值(譯注:upvalue 值與函數(shù)局部變量的區(qū)別在于,即使函數(shù)并非活躍狀態(tài)也可能有 upvalue 值,而非活躍函數(shù)則不存在局部變量,所以其第一個參數(shù)不是棧的層次而是函數(shù))。如果不存在,則返回 nil。
9 setfenv(function or thread or userdata,environment table):
將指定的對象的環(huán)境設(shè)置為 table,即改變對象的作用域。
10 sethook(optional thread,hook function,hook mask string with "c" and/or "r" and/or "l",optional instruction count):
把指定函數(shù)設(shè)置為鉤子。字符串掩碼和計數(shù)值表示鉤子被調(diào)用的時機。這里,c 表示每次調(diào)用函數(shù)時都會執(zhí)行鉤子;r 表示每次從函數(shù)中返回時都調(diào)用鉤子;l 表示每進入新的一行調(diào)用鉤子。
11 setlocal(optional thread,stack level,local index,value):
在指定的棧深度的函數(shù)中,為 index 指定的局部變量賦予值。如果局部變量不存在,則返回 nil。若 level 超出范圍則拋出錯誤;否則返回局部變量的名稱。
12 setmetatable(value,metatable):
為指定的對象設(shè)置元表,元表可以為 nil。
13 setupvalue(function,upvalue index,value):
為指定函數(shù)中索引指定的 upvalue 變量賦值。如果 upvalue 不存在,則返回 nil。否則返回此 upvalue 的名稱。
14 traceback(optional thread,optional meesage string,opitona level argument):
用 traceback 構(gòu)建擴展錯誤消息。

上面的表中列出了 Lua 的全部調(diào)試函數(shù),我們經(jīng)常用到的調(diào)試庫都會用到上面的函數(shù),它讓調(diào)試變得非常容易。雖然提供了便捷的接口,但是想要用上面的函數(shù)創(chuàng)建一個自己的調(diào)試器并不是件容易的事。無論怎樣,我們可以看一下下面這個例子中怎么使用這些調(diào)試函數(shù)的。

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

執(zhí)行上面的程序,我們可以得到如下的棧軌跡信息:

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

上面的例子中,我們使用 debug.trace 函數(shù)輸出了棧軌跡。 debug.getinfo 函數(shù)獲得函數(shù)的當(dāng)前表。

示例二

在調(diào)試過程中,我們常常需要查看或修改函數(shù)局部變量的值。因此,我們可以用 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())

運行上面的程序,我們可以得到如下面的輸出結(jié)果:

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

在這個例子中,每次調(diào)用 counter 都會更新該閉包函數(shù)。我們可以通過 getupvalue 查看其當(dāng)前的局部變量值。隨后,我們更新局部變量的值。在為 n 設(shè)置新值之前,其值為 2。調(diào)用 setupvalue 后,n 被設(shè)置為 10。再調(diào)用 counter 時,它就會返回值 11 而不再是 3。

調(diào)試類型

  • 命令行調(diào)試
  • 圖形界面調(diào)試

命令行調(diào)試工具

命令行調(diào)試就是使用命令行命令和 print 語句來調(diào)試程序。已經(jīng)有許多現(xiàn)成的 Lua 命令行調(diào)試工具,下面列出了其中的一部分:

  • RemDebug:RemDebug 是一個遠程的調(diào)試器,它支持 Lua 5.0 和 5.1 版本。允許遠程調(diào)試 Lua 程序,設(shè)置斷點以及查看程序的當(dāng)前狀態(tài)。同時,它還能調(diào)試 CGILua 腳本。
  • clidebugger:此調(diào)試器是用純 Lua 腳本開發(fā)的命令行調(diào)試工具,支持 Lua 5.1。除了 Lua 5.1 標(biāo)準(zhǔn)庫以外,它不依賴于任何其它的 Lua 庫。雖然它受到了 RemDebug 影響而產(chǎn)生的,但是它沒有遠程調(diào)試的功能。
  • ctrace:跟蹤 Lua API 調(diào)用的小工具。
  • xdbLua:windows 平臺下的 Lua 命令行調(diào)試工具。
  • LuaInterface - Debuger:這個項目是 LuaInterface 的擴展,它對 Lua 調(diào)試接口進行進一步的抽象,允許通過事件和方法調(diào)用的方式調(diào)試程序。
  • RIdb:使用套接字的遠程 Lua 調(diào)試器,支持 Linux 和 Windows 平臺。它的特性比任何其它調(diào)試器都豐富。
  • ModDebug:允許遠程控制另外一個 Lua 程序的執(zhí)行、設(shè)置斷點以及查看程序的當(dāng)前狀態(tài)。

圖形界面調(diào)試工具

圖形界面的調(diào)試工具往往和集成開發(fā)環(huán)境(IDE)打包在一起。它允許在可視環(huán)境下進行調(diào)試,比如查看變量值,棧跟蹤等。通過 IDE 的圖形界面,你可以設(shè)置斷點單步執(zhí)行程序。

下面列出了幾種圖形界面的調(diào)試工具。

  • SciTE:Windows 系統(tǒng)上默認的 Lua 集成開發(fā)環(huán)境,它提供了豐富的調(diào)試功能,比如,斷點、單步、跳過、查看變量等等。
  • Decoda:一個允許遠程調(diào)試的圖形界面調(diào)試工具。
  • ZeroBrane Studio:一個 Lua 的集成開發(fā)環(huán)境,它集成了遠程調(diào)試器、棧視圖、遠程控制終端、靜態(tài)分析等諸多功能。它兼容各類 Lua 引擎,例如 LuaJIT,Love2d,Moai等。支持 Windows, OSX, Linux;開源。
  • akdebugger:eclipse 的 Lua 調(diào)試器和編輯器插件。
  • luaedit:支持運程調(diào)試、本地調(diào)試、語法高亮、自動補完、高級斷點管理(包括有條件地觸發(fā)斷和斷點計數(shù))、函數(shù)列表、全局和本地變量列表、面對方案的管理等。
上一篇:變量下一篇: