基于wxlua和remebug实现的简易lua调试器

来源:互联网 发布:截至到现在淘宝总额 编辑:程序博客网 时间:2024/05/21 11:26

近期在研究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

有兴趣的可以一起讨论。

原创粉丝点击