Skip to content

Commit

Permalink
Implement basic gdb server functionality.
Browse files Browse the repository at this point in the history
This commit introduces basic gdbserver support to the zmu ARM simulator,
enabling remote debugging with a gdb client.

The following features are implemented:

* Breakpoints: Users can set, clear, and manage breakpoints during program execution.
* Continue: Execution can be resumed from the current breakpoint or paused state.
* Step Instruction: Users can step through program instructions for detailed debugging.

This functionality significantly enhances the debugging capabilities of zmu,
making it more versatile for developers.

To start the gdbserver just call zmu with the --gdb flag:

$ zmu.exe run --gdb binary.elf

A gdb server will be open on localhost port 9001

Signed-off-by: Diego Asanza <[email protected]>
  • Loading branch information
Diego Asanza committed Jan 4, 2025
1 parent 5986099 commit 7715cb6
Show file tree
Hide file tree
Showing 10 changed files with 1,283 additions and 135 deletions.
341 changes: 206 additions & 135 deletions Cargo.lock

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use zmu_cortex_m::Processor;

use zmu_cortex_m::system::simulation::simulate_trace;
use zmu_cortex_m::system::simulation::{simulate, SimulationError};
use zmu_cortex_m::gdb::server::GdbServer;

mod errors {
// Create the Error, ErrorKind, ResultExt, and Result types
Expand All @@ -59,6 +60,7 @@ fn run_bin(
trace: bool,
option_trace_start: Option<u64>,
itm_file: Option<Box<dyn io::Write + 'static>>,
gdb: bool,
) -> Result<u32> {
let res = Object::parse(buffer).unwrap();

Expand Down Expand Up @@ -122,6 +124,22 @@ fn run_bin(
let trace_start = option_trace_start.unwrap_or(0);
let semihost_func = Box::new(get_semihost_func(Instant::now()));

if gdb {
let gdb = GdbServer::new(
&flash_mem,
semihost_func,
if flash_start_address != 0 {
Some(MemoryMapConfig::new(flash_start_address, 0, flash_size))
} else {
None
},
flash_size,
);

let exit_code = gdb?.start().expect("GDB server failed");
return Ok(exit_code);
}

let statistics = if trace {
debug!("Configuring tracing.");

Expand Down Expand Up @@ -234,6 +252,7 @@ fn run(args: &ArgMatches) -> Result<u32> {
run_matches.get_flag("trace"),
trace_start,
itm_output,
run_matches.get_flag("gdb"),
)?
}
Some((_, _)) => unreachable!(),
Expand Down Expand Up @@ -289,6 +308,13 @@ fn main() {
.help("List of free arguments to pass to runtime as parameters")
.index(2)
.action(ArgAction::Append),
)
.arg(
Arg::new("gdb")
.action(ArgAction::SetTrue)
.long("gdb")
.help("Enable the gdb server")
.num_args(0)
),
)
.get_matches();
Expand Down
Loading

0 comments on commit 7715cb6

Please sign in to comment.