iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
Software Development

30天 Lua重拾筆記系列 第 28

【30天Lua重拾筆記27】進階議題: debug

同步發表於個人網站

Lua本身並沒有獨立的debugger相關工具,但他有一個強大的內置套件— debug。

打印調錯訊息traceback

debug = require "debug"

do
  local ten = 0
  function div10(n)
    print(debug.traceback()) -- 打印調錯訊息
    return n / ten
  end
end

更新變數值

透過直接觀看函式內容,可以知道這個函式div10並不符合預期。

do
  local ten = 0
  function div10(n)
    return n / ten
  end
end

所以需要改變ten值,但這次不直接修改程式原始碼。我們得先了解怎麼取得閉包變數ten:

do
  local the_ten_name, the_ten_value = debug.getupvalue(div10, 1)
  print(the_ten_name, the_ten_value)
end

ten 0

debug.getupvalue會返回給定函數的特定局部變數名稱與其值,索引從1開始。可以寫一個簡單的函數來取得特定變數名稱:

function get_upvalue(fn, search_name)
  local idx = 1
  while true do
    local name, val = debug.getupvalue(fn, idx)
    if not name then break end
    if name == search_name then
      return idx, val
    end
    idx = idx + 1
  end
end

這樣一來可以更好理解怎麼取得ten的位置與值:

do
  local idx, val = get_upvalue(div10, "ten")
  print(idx, val)
end

有了位置以後才有辦法修改值:

do
  local idx = get_upvalue(div10, "ten")
  debug.setupvalue(div10, idx, 10)
end

這樣一來div10就修改完成

div10(50) --> 5.0

進入簡易除錯器

大致上除錯不外呼找到錯誤點、檢查錯誤可能發生的原因,修正錯誤。說簡單點也就是這次示範的如何找到引發錯誤的變數,並更新其值。你也可以夠過下面進入簡易的除錯器:

debug.debug ()

debug package還可以做什麼

這是一個非常強大的工具,一般而言不會用到。但最好了解可以做些什麼?在本例中只是簡單的除錯,調整變數。他也可以實現Lua 5.1的getfenvsetfenv[^1]。可以完整複製函數,並加以調整[^2]。debug裡還有其他方法,你參考中文資源[^3],也可以直接查找官方資料

撰寫當下查到的中文資源多少都與Lua 5.4官方文件有些出入。
建議兩者相互參看。

參考資料

[^1]: Implementing setfenv in Lua 5.2, 5.3, and above
[^2]: Cloning a function in Lua
[^3]: Lua 調試(Debug)


上一篇
【30天Lua重拾筆記26】進階議題: 錯誤處理
下一篇
【30天Lua重拾筆記28】進階議題: Meta Programming
系列文
30天 Lua重拾筆記36

尚未有邦友留言

立即登入留言