Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling ConsoleOutput in more places #51

Open
daniel5151 opened this issue May 2, 2021 · 1 comment
Open

Enabling ConsoleOutput in more places #51

daniel5151 opened this issue May 2, 2021 · 1 comment
Labels
API-non-breaking Non-breaking API change design-required Getting this right will require some thought new-api Add a new feature to the API (possibly non-breaking)

Comments

@daniel5151
Copy link
Owner

daniel5151 commented May 2, 2021

At the moment, gdbstub only exposes ConsoleOutput in one place: as part of the handle_monitor_cmd interface. That said, this functionality of "print text from the target to the client terminal" isn't some special feature of the monitor command interface, and is also supported as a bog-standard Stop Reply Packet (namely, the O XX... packet).

Moreover, based on a very brief skim through the gdb client source code, it seems that the GDB client might be resilient enough to accept O packets at any time, not just as a response to qRcmd and as a stop reply packet! Note that this behavior is not formalized by the spec, but if it works, then it opens the door to some very cool functionality...

EDIT: of course, there's also the Host I/O packet interface, which enables writing to the host console via a standard write(1, buf, len) interface. Admittedly, this can only be used in the same context as regular O xx stop reply packets, so aside from the benefit of using less bandwidth (as it uses the binary data transfer protocol vs. the 2-char ascii per byte protocol), it's not that much better.

With these bits of info in mind, there are a few ways gdbstub could expand expose ConsoleOutput in more places:

1. Exposing ConsoleOutput as part of the current resume() interfaces.

This should be pretty straightforward, and could be implemented similar to the current monitor command ConsoleOutput (i.e: using a callback).

Note that this will require an API change to add the additional function parameter.

2. Exposing a "global" handle to send O XX... packets.

At the time of writing, I don't have a concrete idea of how to implement this (especially for no_std targets), but I was thinking the API could look something like this:

let connection: TcpStream = wait_for_gdb_connection(9001);
let mut debugger = GdbStub::new(connection);

// get an instance of the global `ConsoleOutput` handle
let console_out_handle = debugger.console_output_handle();
let mut target = MyTarget::new(console_out_handle)?;
target.set_console_out_handle(console_out_handle); // or maybe the target supports late-binding

match debugger.run(&mut target) { ... }

// ..
// later, in the target implementation...
// ..

impl MultiThreadOps for MyTarget {
    fn read_registers(
        &mut self,
        regs: &mut gdbstub_arch::arm::reg::ArmCoreRegs,
        tid: Tid,
    ) -> TargetResult<(), Self> {
        outputln!(self.console_out_handle, "reading regs for tid {:?}", tid);
        // ...
    }
}

IMPORTANT NOTE: because the underlying GDB protocol doesn't support sending console output packets at totally arbitrary points during execution (e.g: in the middle of writing out some other, longer packet), calling output! will require buffering + differing output until such a time when it's reasonable to flush. In other words, the global output! interface will have to be non blocking. This is in contrast to the qRcmd or the resume implementations, which can immediately output the data.

Two final comments:

  • I have a strong suspicion that this feature will have to be std/alloc only, as my gut feeling is that it'll be incredibly tricky to get the lifetimes / locking right without the use of Arc. That said, this is just a gut feeling, and it very well might be the case that once someone takes a crack at an implementation, a more obvious solution will present itself.
  • If a no_std implementation is possible, it may need to be feature-gated to avoid ballooning the binary size.
@daniel5151 daniel5151 added the new-api Add a new feature to the API (possibly non-breaking) label May 2, 2021
@daniel5151 daniel5151 changed the title Expanding the ConsoleOutput-like interface Enabling ConsoleOutput in more places Jun 3, 2021
@daniel5151
Copy link
Owner Author

On a somewhat related note, I recently opened a issue on the GDB bugzilla regarding support for host console IO in non-stop mode:

https://sourceware.org/bugzilla/show_bug.cgi?id=27910

Obviously, gdbstub doesn't currently support non-stop mode, but if/when it does, it would be nice to avoid gating this console output feature.

@daniel5151 daniel5151 added API-non-breaking Non-breaking API change design-required Getting this right will require some thought labels Jul 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API-non-breaking Non-breaking API change design-required Getting this right will require some thought new-api Add a new feature to the API (possibly non-breaking)
Projects
None yet
Development

No branches or pull requests

1 participant