Skip to content

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

Open

Description

@gsisinna

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!

Activity

  1. slembcke commented on Nov 13, 2024

    @slembcke
    Owner

    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

  2. gsisinna commented on Nov 14, 2024

    @gsisinna
    Author

    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!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions