mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Print the entire backtrace
This commit is contained in:
parent
8453b46eab
commit
3f374f3e9c
|
@ -1,6 +1,6 @@
|
|||
use std::{fs, path::PathBuf, str::FromStr};
|
||||
use std::{fs, path::PathBuf};
|
||||
|
||||
use addr2line::object;
|
||||
use addr2line::{gimli, object};
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
|
@ -35,9 +35,20 @@ fn main() -> anyhow::Result<()> {
|
|||
|
||||
let ctx = addr2line::Context::new(&object)?;
|
||||
|
||||
let mut frames = ctx
|
||||
.find_frames(parse_address(&cli.dump)?)
|
||||
.skip_all_loads()?;
|
||||
for address in cli.dump.split('-') {
|
||||
let mut address = u64::from_str_radix(address, 16)?;
|
||||
if address <= 0xFFFF {
|
||||
address += 0x0800_0000;
|
||||
}
|
||||
|
||||
print_address(&ctx, address)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_address(ctx: &addr2line::Context<impl gimli::Reader>, address: u64) -> anyhow::Result<()> {
|
||||
let mut frames = ctx.find_frames(address).skip_all_loads()?;
|
||||
|
||||
while let Some(frame) = frames.next()? {
|
||||
let function_name = if let Some(func) = frame.function {
|
||||
|
@ -54,19 +65,8 @@ fn main() -> anyhow::Result<()> {
|
|||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
println!(
|
||||
"{}:{} ({})",
|
||||
location.filename, location.line, function_name
|
||||
);
|
||||
println!("{function_name} ({}:{})", location.filename, location.line);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_address(input: &str) -> Result<u64, <u64 as FromStr>::Err> {
|
||||
if let Some(input) = input.strip_prefix("0x") {
|
||||
u64::from_str_radix(input, 16)
|
||||
} else {
|
||||
input.parse()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ struct Context {
|
|||
registers: [u32; 11],
|
||||
}
|
||||
|
||||
pub struct Frame {
|
||||
pub address: u32,
|
||||
pub struct Frames {
|
||||
frames: Vec<u32>,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
|
@ -37,7 +37,7 @@ impl Index<Register> for Context {
|
|||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub(crate) fn unwind_exception() -> Vec<Frame> {
|
||||
pub(crate) fn unwind_exception() -> Frames {
|
||||
let mut context = Context::default();
|
||||
|
||||
unsafe {
|
||||
|
@ -77,10 +77,33 @@ pub(crate) fn unwind_exception() -> Vec<Frame> {
|
|||
break;
|
||||
}
|
||||
|
||||
frames.push(Frame { address: lr });
|
||||
frames.push(lr);
|
||||
|
||||
frame_pointer = sp;
|
||||
}
|
||||
|
||||
frames
|
||||
Frames { frames }
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Frames {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let mut is_first = true;
|
||||
|
||||
for frame in &self.frames {
|
||||
if !is_first {
|
||||
write!(f, "-")?;
|
||||
}
|
||||
|
||||
if frame & 0xFFFF_0000 == 0x0800_0000 {
|
||||
let frame = frame & 0xFFFF;
|
||||
write!(f, "{frame:x}")?;
|
||||
} else {
|
||||
write!(f, "{frame:x}")?;
|
||||
}
|
||||
|
||||
is_first = false;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -323,12 +323,10 @@ pub mod test_runner {
|
|||
if let Some(mut mgba) = mgba::Mgba::new() {
|
||||
let _ = mgba.print(format_args!("[failed]"), mgba::DebugLevel::Error);
|
||||
|
||||
for frame in frames {
|
||||
let _ = mgba.print(
|
||||
format_args!("{:#08x}", frame.address),
|
||||
format_args!("debug data: {frames}"),
|
||||
mgba::DebugLevel::Error,
|
||||
);
|
||||
}
|
||||
|
||||
let _ = mgba.print(format_args!("Error: {info}"), mgba::DebugLevel::Fatal);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue