1
7
Fork
You've already forked debugger.lua
0

Interacting with debugger commands at runtime from C++ #87

Open
opened 2024年11月08日 14:38:09 +01:00 by gsisinna · 2 comments
gsisinna commented 2024年11月08日 14:38:09 +01:00 (Migrated from github.com)
Copy link

Hi everyone,

First, I want to thank you all for the incredible work on this project—it's outstanding!

I followed the guide for embedding debugger.lua into C++ code and generated the necessary header file to define the setup and configuration. Currently, I’d like to interact with the debugger at runtime directly from C++, without requiring user input (e.g., typing "s" for step and pressing ENTER). I’ve tried using the read and write handlers, but I still end up in scenarios where the debugger shell opens, and I have to manually continue with "c".

Could anyone provide guidance on the best approach for handling debugger input and output in a Lua state created from C++? My goal is to redirect debugger I/O through JSON packets.

Thank you very much!

Hi everyone, First, I want to thank you all for the incredible work on this project—it's outstanding! I followed the guide for embedding debugger.lua into C++ code and generated the necessary header file to define the setup and configuration. Currently, I’d like to interact with the debugger at runtime directly from C++, without requiring user input (e.g., typing "s" for step and pressing ENTER). I’ve tried using the read and write handlers, but I still end up in scenarios where the debugger shell opens, and I have to manually continue with "c". Could anyone provide guidance on the best approach for handling debugger input and output in a Lua state created from C++? My goal is to redirect debugger I/O through JSON packets. Thank you very much!
slembcke commented 2024年11月13日 17:54:09 +01:00 (Migrated from github.com)
Copy link

Hrm. Can you share some of your code maybe? While not a particularly interesting example, I do use this functionality to run the automated tests. There's not really much to it, it just just uses the overridden I/O to send commands from a list and check for expected output:
https://github.com/slembcke/debugger.lua/blob/master/test/test_util.lua#L32

Hrm. Can you share some of your code maybe? While not a particularly interesting example, I do use this functionality to run the automated tests. There's not really much to it, it just just uses the overridden I/O to send commands from a list and check for expected output: https://github.com/slembcke/debugger.lua/blob/master/test/test_util.lua#L32
gsisinna commented 2024年11月14日 12:52:37 +01:00 (Migrated from github.com)
Copy link

Yes thank you, I'll try to give an idea of what I would like to achieve.

I tried modifying the debugger.lua a bit to receive JSON packets as input instead of just writing from terminal and then pressing ENTER:

local socket = require("socket")
local json = require("json")
print("Starting server...")
local server = assert(socket.bind("127.0.0.1", 12345))
print("Server started, waiting for client connection...")
local client = server:accept()
print("Client connected")
local dbg
... (rest of the code)

After this I modified the default functions to read and write using JSON encoding:

local function dbg_write(str)
 print("dbg_write called with input: ", str) -- Debug print to see the input
 local output = json.encode({ result = str })
 print("Encoded JSON: ", output) -- Debug print to check the JSON encoding
 client:send(output .. "\n")
end

and

local function dbg_read(prompt)
 print("dbg_read called with prompt: ", prompt) -- Debug print to see the input prompt
 dbg.write(prompt)
 local input = client:receive()
 print("Received input: ", input) -- Debug print to see the raw input received from the client
 local success, command = pcall(json.decode, input)
 if success then
 print("Decoded JSON: ", command) -- Debug print to check the decoded JSON object
 return command
 else
 dbg_writeln(COLOR_RED.."Invalid JSON input"..COLOR_RESET)
 print("JSON decoding failed.") -- Debug print to indicate failure
 return nil
 end
end

What I want to do now is match the already implemented methods (like step and locals) given the JSON data, and I was thinking on something like this:

(... all debugger.lua code)
-- Function to process and match commands
local function process_command(command)
 -- Check if the command is a table with a 'cmd' attribute
 if type(command) == "table" and command.cmd then
 local func, arg = match_command(command.cmd) -- Match the command
 if func then
 return func(arg) -- Execute the command and return the result
 else
 return "Unknown command" -- Return an error message for unrecognized commands
 end
 -- If the command is a string, directly match and process it
 elseif type(command) == "string" then
 local func, arg = match_command(command) -- Match the command
 if func then
 return func(arg) -- Execute the command and return the result
 else
 return "Unknown command" -- Return an error message for unrecognized commands
 end
 end
end
-- Function to read and process commands in the main loop
local function main_loop()
 while true do
 -- Read command from the client
 local command = dbg_read(GREEN_CARET)
 if command then
 -- Debug: print received command for inspection
 print("Received command: ", command)
 -- Process the command and get the result
 local result = process_command(command)
 -- Debug: print the result for inspection
 print("Result of command: ", result)
 -- Write the result back to the client
 dbg_writeln(result)
 end
 end
end
-- Start the main loop to continuously read commands and process them
main_loop()
return dbg

I came to this conclusion after having not a little difficulty integrating c++-side interaction with the debugger shell in an automated way, so I moved to the Lua side. I would like to be able to have the debugger always listening for JSON commands without the need to interact with the shell.

Thanks again!

Yes thank you, I'll try to give an idea of what I would like to achieve. I tried modifying the `debugger.lua` a bit to receive JSON packets as input instead of just writing from terminal and then pressing ENTER: ```lua local socket = require("socket") local json = require("json") print("Starting server...") local server = assert(socket.bind("127.0.0.1", 12345)) print("Server started, waiting for client connection...") local client = server:accept() print("Client connected") local dbg ... (rest of the code) ``` After this I modified the default functions to read and write using JSON encoding: ```lua local function dbg_write(str) print("dbg_write called with input: ", str) -- Debug print to see the input local output = json.encode({ result = str }) print("Encoded JSON: ", output) -- Debug print to check the JSON encoding client:send(output .. "\n") end ``` and ```lua local function dbg_read(prompt) print("dbg_read called with prompt: ", prompt) -- Debug print to see the input prompt dbg.write(prompt) local input = client:receive() print("Received input: ", input) -- Debug print to see the raw input received from the client local success, command = pcall(json.decode, input) if success then print("Decoded JSON: ", command) -- Debug print to check the decoded JSON object return command else dbg_writeln(COLOR_RED.."Invalid JSON input"..COLOR_RESET) print("JSON decoding failed.") -- Debug print to indicate failure return nil end end ``` What I want to do now is match the already implemented methods (like step and locals) given the JSON data, and I was thinking on something like this: ```lua (... all debugger.lua code) -- Function to process and match commands local function process_command(command) -- Check if the command is a table with a 'cmd' attribute if type(command) == "table" and command.cmd then local func, arg = match_command(command.cmd) -- Match the command if func then return func(arg) -- Execute the command and return the result else return "Unknown command" -- Return an error message for unrecognized commands end -- If the command is a string, directly match and process it elseif type(command) == "string" then local func, arg = match_command(command) -- Match the command if func then return func(arg) -- Execute the command and return the result else return "Unknown command" -- Return an error message for unrecognized commands end end end -- Function to read and process commands in the main loop local function main_loop() while true do -- Read command from the client local command = dbg_read(GREEN_CARET) if command then -- Debug: print received command for inspection print("Received command: ", command) -- Process the command and get the result local result = process_command(command) -- Debug: print the result for inspection print("Result of command: ", result) -- Write the result back to the client dbg_writeln(result) end end end -- Start the main loop to continuously read commands and process them main_loop() return dbg ``` I came to this conclusion after having not a little difficulty integrating c++-side interaction with the debugger shell in an automated way, so I moved to the Lua side. I would like to be able to have the debugger always listening for JSON commands without the need to interact with the shell. Thanks again!
Sign in to join this conversation.
No Branch/Tag specified
master
no-extras
dev
patch-1
media
simple-term
slembcke
error-hook
standalone
No results found.
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
slembcke/debugger.lua#87
Reference in a new issue
slembcke/debugger.lua
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?