From 081deea3fe025799133c875081eb751b1b7270c7 Mon Sep 17 00:00:00 2001 From: FlyingCanoe Date: Sun, 25 Jul 2021 10:46:20 -0400 Subject: [PATCH] Add source location breakpoints to repl this commit add the ability to set a breakpoints by specifying the file name, the line number and (optional) the column number of the source code. While it work, it is not very polish. The error handling is sloppy. It does no path canonization. I have not update the UI the advertise the capability. There are no path auto-completion. In other word, it still is a prototype, but it work. --- examples/repl.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/examples/repl.rs b/examples/repl.rs index 4307169..ecffe53 100644 --- a/examples/repl.rs +++ b/examples/repl.rs @@ -398,9 +398,21 @@ mod example { if let Some(addr) = parse_address(location).or(parse_symbol(&location, context)) { Ok(vec![addr]) } else { - Err(format!( + if let Some(source_location) = parse_source_location(location) { + Ok(context + .debuginfo + .as_ref() + .unwrap() // this unwrap cannot fail due to the call to load_debuginfo_if_necessary + .find_location_addr(&source_location) + .unwrap() // todo: this unwrap could fail if the debugee contain invalid debug info. + .into_iter() + .map(|(_, addr)| addr as usize) + .collect()) + } else { + Err(format!( "Breakpoints must be set on a symbol or at a given address. For example `b main` or `b 0x0000555555559394` or even `b 93824992252820`" ))? + } } } @@ -427,6 +439,27 @@ mod example { context.debuginfo().get_symbol_address(&location) } + fn parse_source_location(location: &str) -> Option { + use addr2line::Location; + + let mut iter = location.split(":"); + let file = iter.next(); + let line = iter + .next() + .map_or(None, parse_address) + .map_or(None, |num| NonZeroU32::new(num as u32)); + let column = iter + .next() + .map_or(None, parse_address) + .map_or(None, |num| NonZeroU32::new(num as u32)); + + if let (Some(file), Some(line)) = (file, line) { + Some(Location { file, line, column }) + } else { + None + } + } + fn show_backtrace(context: &mut Context, bt_type: &BacktraceType) -> CrabResult<()> { let call_stack: Vec<_> = get_call_stack(context, bt_type)?; for func in call_stack {