Skip to content

Conversation

@moteus
Copy link
Contributor

@moteus moteus commented Feb 26, 2022

I'll try to add comments in the code

if jit and jit.off then jit.off() end

local socket = require "socket"
local state = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packed local variables into state table. This is done because of the limitations of some environment. In my case I have limit to 120 local variables and I faced with it.

end
end

local Socket = {} do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class incapsulate buffered IO and IO pending detection

mobdebug.dump = serpent.dump
mobdebug.linemap = nil
mobdebug.loadstring = loadstring
mobdebug.print = print
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows to redirect print to e.g. logs inside debuggee application

or string_match(file, [[^.:]])
end

local function removebasedir(path, basedir)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just reformat code and reduce the number if nested levels

return (file:gsub("^(/?)%.%./", "%1"))
end

local function is_soucer_file_path(file)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code from debug_hook without changes

if not (
step_into or step_over or breakpoints[line] or watchescnt > 0
or is_pending(server)
) then checkcount = checkcount + 1; return end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checkcount logic movet to the Socket class

end

if is_pending(server) then handle_breakpoint(server) end
local possible_pending_io = debugger.loop_pending_io()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case this function returns true that means there exists some pending data and this data have to be processed inside main loop.
E.g. debugger receive only part of message and we do not want to wait too long inside IO. In this case this function can return false, server:is_pending() will be true, but there no reason to yield to the main loop.

state.basedir = "" -- to reset basedir in case the same module/state is reused
end

local mobdebug_debugger = {} do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submodule that implements MobDebug protocol.

if not jit then
for co, debugged in pairs(coroutines) do
if debugged then debug.sethook(co) end
function mobdebug_debugger.send_response(status, message, data)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I extract all commant parsing and sendig responses to separate functions.

-- Handling command from inside debug hook during run state
function mobdebug_debugger.pending_io()
local possible_pending_io = false
while server:is_pending() do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main changes that this loop allows to handle multiple commands.

moteus added 2 commits March 4, 2022 11:31
Fix. Honor the sync flag in the header receiving operation
@moteus moteus changed the title [WIP] Support for VSCode DAP protocol Support for VSCode DAP protocol Mar 11, 2022
@mavriq-dev
Copy link

This is a is very handy to have. Being able to support multiple debuggers is a huge win.

@muescha
Copy link

muescha commented Nov 21, 2022

whats the protocol used before by mobdebug? i would like to study the specs

@muescha
Copy link

muescha commented Nov 23, 2022

found answer to my question here:

MobDebug/src/mobdebug.lua

Lines 1541 to 1561 in f27d479

print("setb <file> <line> -- sets a breakpoint")
print("delb <file> <line> -- removes a breakpoint")
print("delallb -- removes all breakpoints")
print("setw <exp> -- adds a new watch expression")
print("delw <index> -- removes the watch expression at index")
print("delallw -- removes all watch expressions")
print("run -- runs until next breakpoint")
print("step -- runs until next line, stepping into function calls")
print("over -- runs until next line, stepping over function calls")
print("out -- runs until line after returning from current function")
print("listb -- lists breakpoints")
print("listw -- lists watch expressions")
print("eval <exp> -- evaluates expression on the current context and returns its value")
print("exec <stmt> -- executes statement on the current context")
print("load <file> -- loads a local file for debugging")
print("reload -- restarts the current debugging session")
print("stack -- reports stack trace")
print("output stdout <d|c|r> -- capture and redirect io stream (default|copy|redirect)")
print("basedir [<path>] -- sets the base path of the remote application, or shows the current one")
print("done -- stops the debugger and continues application execution")
print("exit -- exits debugger and the application")

and in #32

@muescha
Copy link

muescha commented Nov 23, 2022

i asked the question because: when the functionality is equal to both debug protocols then i would not mix the implementation into one file. when something changes then it need to implemented in both protocols on 2 places (DRY)

i would like to see some main functionality and then implement the adapter pattern either for mobdebug protocol or for debug adapter protocol.

local mobdebug = require("mobdebug").adapter("dap").start()
local mobdebug = require("mobdebug").start()

@moteus
Copy link
Contributor Author

moteus commented Dec 10, 2022

I thought about it and even tried to do such a split, but I couldn't do this.
The mobdebug.lua file is a self-contained module with a debug server and debug client simultaneously.
It contains code that depends on a file name and a call stack size.
So as a result, I got some unexplainable errors when adding additional layers to this code.
I had code with two classes, DapLoop and MobDebugLoop, but I could not fix or even understood some glitches and ended up with a more straightforward implementation.
If speaking about require("mobdebug").adapter("dap").start() right now, I see no necessity in such because it is pretty easy to detect client protocol by the first message.

PS. Right now, I use my module with ZBS, and several colleagues use it with VSCode without any issues.

@KuDeSnik33ra
Copy link

Is there some manual on how to use it with vscode? Isn't there any chance to have multiple connections from debugged application to singe vscode server to debug multiple lua VMs simultaneousely without starting multiple debugging sessions in VSCode?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants