近期在研究lua调试器。Lua examples中有editor.wx.wlua,如下
这个调试器可以打开编辑lua文件,但是调试时就会出现致命错误,导致调试器崩溃
wxlua中用C++实现了debug库,不过也没有时间去研究它的具体实现,于是考虑使用remdebug调试引擎替换wxlua中的调试引擎。
这样做的好处:1. remdebug是用lua写的 2. remdebug是基于socket的调试器。完全基于lua写出一个调试器感觉还是蛮有趣的。
remdebug去这里下载http://www.keplerproject.org/remdebug/
简易调试器的基本结构就是:基于wxlua的编辑器 + remdebug。
编辑器怎么搭建可以参考examples中的editor.wx.wlua
remdebug中要稍作修改:
1. controller.lua中
--[[
print("Lua Remote Debugger")
print("Run the program you wish to debug")
local server = socket.bind("*", 8171)
local client = server:accept()
local breakpoints = {}
local watches = {}
client:send("STEP/n")
client:receive()
local breakpoint = client:receive()
local _, _, file, line = string.find(breakpoint, "^202 Paused%s+([%w%p]+)%s+(%d+)$")
if file and line then
print("Paused at file " .. file )
print("Type 'help' for commands")
else
local _, _, size = string.find(breakpoint, "^401 Error in Execution (%d+)$")
if size then
print("Error in remote application: ")
print(client:receive(size))
end
end
]]
将上述代码注释掉。因为正常使用remdebug时需要启两个终端,一个作client,一个作server。
2. 在可视化的调试器中,我们只要将controller放入主程序中,engine启在后台就可以了。我的实现如下:
--frame是主窗口
frame:Connect(ID_START_DEBUG, wx.wxEVT_COMMAND_MENU_SELECTED,
function (event)
local editor = GetEditor()
-- test compile it before we run it
if not CompileProgram(editor) then
return
end
--启动 remdebug controller
debuggerServer = socket.bind("*", 8171)
--debuggerServer = socket.bind("localhost", 8171)
DisplayOutput("luadbg "..tostring(debuggerServer))
breakpoints = {}
watches = {}
--创建 debug client , 这里用了协程,先让server挂起,等engine启动后再唤醒
local waiting_svr_accept = coroutine.create(function() client = debuggerServer:accept() coroutine.yield() end)
local id = editor:GetId();
local document = openDocuments[id]
--启动engine
local cmd = '"'..programName..'" '.."-l".." ./remDebug/remdebug "..document.filePath
DisplayOutput(cmd)
local pid = wx.wxExecute(cmd, wx.wxEXEC_ASYNC)
if pid == -1 then
DisplayOutput("Unknown ERROR Running program!/n", true)
else
DisplayOutput("Process id is: "..tostring(pid).."/n", true)
end
coroutine.resume(waiting_svr_accept)
--engine启动成功
DisplayOutput("accepted client")
--单步进入lua程序
client:send("STEP/n")
client:receive()
local breakpoint = client:receive()
print(breakpoint)
local _, _, file, line = string.find(breakpoint, "^202 Paused%s+([%w%p]+)%s+(%d+)$")
if file and line then
DisplayOutput("Paused at file " .. file )
--print("Type 'help' for commands")
else
local _, _, size = string.find(breakpoint, "^401 Error in Execution (%d+)$")
if size then
print("Error in remote application: ")
print(client:receive(size))
end
end
end)
简易调试器贴图:右侧是函数列表
再看看单步调试时的图片:绿色光标指示脚本执行的当前位置,下面的log窗口中同步显示执行到哪一行,当然log也要显示其他信息,还要重定向print的内容到log窗口中的(这个还没有实现)。
最后再看一下观察变量的窗口:
很简陋的调试器,献丑了。欢迎拍砖:-D
有兴趣的可以一起讨论。