runtime: print (address-only) backtraces on core device panics.

This commit is contained in:
whitequark 2017-12-25 17:55:20 +00:00
parent 3eec15c01d
commit 230f2e5e18
9 changed files with 91 additions and 20 deletions

View File

@ -13,6 +13,10 @@ dependencies = [
"board 0.0.0", "board 0.0.0",
] ]
[[package]]
name = "backtrace_artiq"
version = "0.0.0"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.0.1" version = "1.0.1"
@ -150,6 +154,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"alloc_list 0.0.0", "alloc_list 0.0.0",
"amp 0.0.0", "amp 0.0.0",
"backtrace_artiq 0.0.0",
"board 0.0.0", "board 0.0.0",
"build_artiq 0.0.0", "build_artiq 0.0.0",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -23,7 +23,7 @@ $(RUSTOUT)/libksupport.a:
ksupport.elf: $(RUSTOUT)/libksupport.a glue.o ksupport.elf: $(RUSTOUT)/libksupport.a glue.o
$(LD) $(LDFLAGS) -T $(KSUPPORT_DIRECTORY)/ksupport.ld -o $@ $^ \ $(LD) $(LDFLAGS) -T $(KSUPPORT_DIRECTORY)/ksupport.ld -o $@ $^ \
-lunwind -lcompiler-rt -lbase -lm -lunwind-elf -lcompiler-rt -lbase -lm
@chmod -x $@ @chmod -x $@
%.o: $(KSUPPORT_DIRECTORY)/%.c %.o: $(KSUPPORT_DIRECTORY)/%.c

View File

@ -0,0 +1,8 @@
[package]
authors = ["M-Labs"]
name = "backtrace_artiq"
version = "0.0.0"
[lib]
name = "backtrace_artiq"
path = "lib.rs"

View File

@ -0,0 +1,38 @@
#![feature(libc, panic_unwind, never_type)]
#![allow(non_upper_case_globals, non_camel_case_types)]
#![no_std]
extern crate unwind;
extern crate libc;
use unwind as uw;
use libc::c_void;
type _Unwind_Trace_Fn = extern "C" fn(*mut uw::_Unwind_Context, *mut c_void)
-> uw::_Unwind_Reason_Code;
extern {
fn _Unwind_Backtrace(trace_fn: _Unwind_Trace_Fn, arg: *mut c_void)
-> uw::_Unwind_Reason_Code;
}
pub fn backtrace<F>(mut f: F) -> Result<(), uw::_Unwind_Reason_Code>
where F: FnMut(usize) -> ()
{
extern fn trace<F>(context: *mut uw::_Unwind_Context, arg: *mut c_void)
-> uw::_Unwind_Reason_Code
where F: FnMut(usize) -> ()
{
unsafe {
let step_fn = &mut *(arg as *mut F);
step_fn(uw::_Unwind_GetIP(context));
uw::_URC_NO_REASON
}
}
unsafe {
match _Unwind_Backtrace(trace::<F>, &mut f as *mut _ as *mut c_void) {
uw::_URC_NO_REASON => Ok(()),
err => Err(err)
}
}
}

View File

@ -19,6 +19,7 @@ log = { version = "0.3", default-features = false }
alloc_list = { path = "../liballoc_list" } alloc_list = { path = "../liballoc_list" }
std_artiq = { path = "../libstd_artiq", features = ["alloc", "io_error_alloc"] } std_artiq = { path = "../libstd_artiq", features = ["alloc", "io_error_alloc"] }
logger_artiq = { path = "../liblogger_artiq" } logger_artiq = { path = "../liblogger_artiq" }
backtrace_artiq = { path = "../libbacktrace_artiq" }
board = { path = "../libboard", features = ["uart_console"] } board = { path = "../libboard", features = ["uart_console"] }
proto = { path = "../libproto", features = ["log"] } proto = { path = "../libproto", features = ["log"] }
amp = { path = "../libamp" } amp = { path = "../libamp" }

View File

@ -1,7 +1,13 @@
include ../include/generated/variables.mak include ../include/generated/variables.mak
include $(MISOC_DIRECTORY)/software/common.mak include $(MISOC_DIRECTORY)/software/common.mak
LDFLAGS += -L../libbase CFLAGS += \
-I$(LIBUNWIND_DIRECTORY) \
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
LDFLAGS += -L../libbase \
-L../libprintf \
-L../libunwind
RUSTFLAGS += -Cpanic=abort RUSTFLAGS += -Cpanic=abort
@ -11,13 +17,17 @@ all: runtime.bin runtime.fbi
$(RUSTOUT)/libruntime.a: $(RUSTOUT)/libruntime.a:
$(cargo) --manifest-path $(RUNTIME_DIRECTORY)/Cargo.toml $(cargo) --manifest-path $(RUNTIME_DIRECTORY)/Cargo.toml
runtime.elf: $(RUSTOUT)/libruntime.a ksupport_data.o runtime.elf: $(RUSTOUT)/libruntime.a ksupport_data.o glue.o
$(LD) $(LDFLAGS) -T $(RUNTIME_DIRECTORY)/runtime.ld -o $@ $^ $(LD) $(LDFLAGS) -T $(RUNTIME_DIRECTORY)/runtime.ld -o $@ $^ \
-lunwind-bare -lprintf-nofloat --eh-frame-hdr
@chmod -x $@ @chmod -x $@
ksupport_data.o: ../ksupport/ksupport.elf ksupport_data.o: ../ksupport/ksupport.elf
$(LD) -r -b binary -o $@ $< $(LD) -r -b binary -o $@ $<
%.o: $(RUNTIME_DIRECTORY)/%.c
$(compile)
%.bin: %.elf %.bin: %.elf
$(OBJCOPY) -O binary $< $@ $(OBJCOPY) -O binary $< $@
@chmod -x $@ @chmod -x $@

View File

@ -14,6 +14,7 @@ extern crate alloc_list;
#[macro_use] #[macro_use]
extern crate std_artiq as std; extern crate std_artiq as std;
extern crate logger_artiq; extern crate logger_artiq;
extern crate backtrace_artiq;
#[macro_use] #[macro_use]
extern crate board; extern crate board;
extern crate proto; extern crate proto;
@ -231,7 +232,9 @@ pub extern fn exception_handler(vect: u32, _regs: *const u32, pc: u32, ea: u32)
#[no_mangle] #[no_mangle]
pub extern fn abort() { pub extern fn abort() {
panic!("aborted") println!("aborted");
loop {}
} }
#[no_mangle] #[no_mangle]
@ -239,6 +242,11 @@ pub extern fn abort() {
pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u32) -> ! { pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u32) -> ! {
println!("panic at {}:{}: {}", file, line, args); println!("panic at {}:{}: {}", file, line, args);
println!("backtrace:");
let _ = backtrace_artiq::backtrace(|ip| {
println!("{:#08x}", ip);
});
if config::read_str("panic_reboot", |r| r == Ok("1")) { if config::read_str("panic_reboot", |r| r == Ok("1")) {
println!("rebooting..."); println!("rebooting...");
unsafe { board::boot::reboot() } unsafe { board::boot::reboot() }
@ -248,11 +256,3 @@ pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u3
loop {} loop {}
} }
} }
// Allow linking with crates that are built as -Cpanic=unwind even if we use -Cpanic=abort.
// This is never called.
#[allow(non_snake_case)]
#[no_mangle]
pub extern fn _Unwind_Resume() -> ! {
loop {}
}

View File

@ -20,6 +20,21 @@ SECTIONS
_etext = .; _etext = .;
} > runtime } > runtime
.eh_frame :
{
__eh_frame_start = .;
KEEP(*(.eh_frame))
__eh_frame_end = .;
} > runtime
.eh_frame_hdr :
{
KEEP(*(.eh_frame_hdr))
} > runtime
__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;
/* https://sourceware.org/bugzilla/show_bug.cgi?id=20475 */ /* https://sourceware.org/bugzilla/show_bug.cgi?id=20475 */
.got : .got :
{ {
@ -79,10 +94,4 @@ SECTIONS
. = ORIGIN(runtime) + LENGTH(runtime); . = ORIGIN(runtime) + LENGTH(runtime);
_eheap = .; _eheap = .;
} > runtime } > runtime
/DISCARD/ :
{
*(.eh_frame)
*(.gcc_except_table)
}
} }

View File

@ -15,7 +15,7 @@ requirements:
- python >=3.5.3,<3.6 - python >=3.5.3,<3.6
- setuptools 33.1.1 - setuptools 33.1.1
- migen 0.6.dev py35_50+git82b06ee - migen 0.6.dev py35_50+git82b06ee
- misoc 0.8.dev py35_15+git5c201712 - misoc 0.8.dev py35_30+gitd95f4edb
- jesd204b 0.4 - jesd204b 0.4
- binutils-or1k-linux >=2.27 - binutils-or1k-linux >=2.27
- llvm-or1k - llvm-or1k