乙個簡單的lua除錯工具

2021-09-07 10:07:50 字數 3124 閱讀 2701

最近看起了lua的debug庫,想著可以簡單弄個跟gdb這樣的命令列除錯工具,於是花了幾天時間,搞了個相當簡單的除錯工具,實現了簡單的列印和斷點和下一步的功能(修改變數值的實現方式其實跟列印的操作並沒有很大區別,所以就懶得弄啦),雖然**很粗糙,使用和體驗上也相當奇葩,也勉強把,畢竟也達到了學學習,動動腦子的目的,這裡分享一下,有興趣的大佬可以在github上整下來指點指點咯

這工具主要分為兩部分,乙個是用lua實現的處理實際的除錯操作,乙個是用c++整的控制台用於接收命令和顯示輸出。

這裡就主要看下lua部分咯,目前這一塊主要實現的功能有:斷點、列印local和upvalue值。

1、斷點

首先看下怎麼把程式中斷下來進入互動除錯把。本來是準備用debug.debug()這個東西來中斷程式執行進行互動的,可是想一下這個的輸入輸出都是標準輸入輸出,而且繼續執行需要輸入cont,這多麻煩哦。於是看了一下debug.debug()的實現,實現如下:

static int db_debug (lua_state *l) 

}

其實也就是乙個進入乙個迴圈,然後等待輸入然後就各種各樣什麼的。這就沒啥好想的了,原樣整乙個完事了

while true do

if not self.isbreak then

self:print("[ddebuger] quitdebug!!")

break

endlocal data, e = self.conn:receive() --接收

if data and e ~= "closed" then

self:handlermessage(data)

else

self.conn:close()

self.conn = nil

break

endend

一旦觸發斷點就進入乙個迴圈,等待接受命令來執行特定的操作,如果連線斷開就直接退出迴圈。

接著看下判斷斷點的出發。這個當時是有兩個方案實現,乙個是直接在需要斷點的地方呼叫乙個函式進入除錯,另乙個方案當然就是通過debug.sethook()來實現了。想了一下,為了能把操作統一到乙個地方控制,還是選擇了第二種方案。具體的做法是記錄下斷點的檔案路徑和行號,在每次進入下一行的時候判斷是否需要斷下來,就這麼簡單,具體實現如下:

local hookfunc = function ()

-- 獲取當前的除錯資訊

local info = debug.getinfo(2, "nls")

if not info then

return

end-- 過濾該檔案的hook

if self:checkselffunc(info) then

return

end-- 判斷是否擊中斷點

if not self.issinglestep and not self:checkhitbreakpoint(info) then

return

end-- 進入除錯模式

self:enterdebug(info)

enddebug.sethook(hookfunc, "l")

-- 判斷是否擊中斷點

function ddebuger:checkhitbreakpoint(info)

if not info then

return

endif not self.bplist then

return

endlocal _, _, short_src = string.find(info.short_src, [[\(%a+).lua]])

if not short_src then

return

endif not self.bplist[short_src] then

return

endif not self.bplist[short_src][tostring(info.currentline)] then

return

endreturn true

end

當然具體還有一些判斷是否是當前檔案,是否是執行下一步這樣的判斷檢測,不過主要的東西也就這樣咯。

實現了這兩部分功能的**就假假的打個斷點停下來這樣啦,其他的功能也就一步步新增了,這裡主要弄了個列印local變數和upvalue的功能。這一部分的實現主要還是參考了雲風大佬的做法

大佬就是大佬,通過進入除錯狀態的時候遍歷一下將兩種變數存到乙個表裡面去,後續訪問就變得相當簡單了。具體的**如下:

function ddebuger:initlocaltablelua(level)

self.localtabel = {}

local n = 1

while true do

local key, value = debug.getlocal(level, n)

if not key then

break

endif value == nil then

value = "nil"

endself.localtabel[key] = value

n = n + 1

endend-- 初始化upvalue變數

function ddebuger:initupvaluetablelua(level)

self.upvaluetable = {}

local info = debug.getinfo(level, "nf")

local func = info.func

local n = 1

while true do

local key, value = debug.getupvalue(func, n)

if not key then

break

endif value == nil then

value = "nil"

endself.upvaluetable[key] = value

n = n + 1

endend

到這裡列印變數就不是啥問題啦,相應的要實現改變變數的操作其實核心也就是封裝一下的debug.setupvalue什麼的這些介面咯,這就不獻醜了。

發乙個較好的除錯工具

a good crackme tool,usr ptrace to debug the need crack file from tiocsti s solution to yanisto s tiny crackme,url added some comments include include ...

介紹乙個node除錯工具 nodemon

這個工具和node supervisor基本上是一致的,但是其功能比較強大,個人覺得在開發環境還是用 nodemon,因為配置比較方便,文件也很清晰。所以這裡先主要講 nodemon。nodemon 的安裝 npm install g nodemon安裝完 nodemon 後,就可以用 nodemo...

分享乙個「貧民版」除錯工具 PySnooper

一般情況下,在編寫 python 時,如果想弄清楚為什麼 python 沒有按照預期執行的原因,比如你想知道哪些是正在執行,哪些沒有執行,以及區域性變數的值是什麼.通常我們會使用包含斷點和觀察模式等功能成熟的偵錯程式,或者直接使用 print 語句列印出來。今天,猿妹和大家分享乙個 貧民版 除錯工具...