From cbe41e5304bee049fa9fa7293c2486b13b4a856e Mon Sep 17 00:00:00 2001 From: Fenrir Date: Tue, 25 Jul 2017 10:49:26 -0600 Subject: [PATCH] Enable old panic behavior for Citra --- ctr-std/Cargo.toml | 3 +++ ctr-std/src/panicking.rs | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/ctr-std/Cargo.toml b/ctr-std/Cargo.toml index 1a883f5..c4cbce4 100644 --- a/ctr-std/Cargo.toml +++ b/ctr-std/Cargo.toml @@ -15,3 +15,6 @@ default-features = false [dependencies.ctru-sys] path = "../ctru-sys" + +[features] +citra = [] diff --git a/ctr-std/src/panicking.rs b/ctr-std/src/panicking.rs index 6d47fd3..097be6f 100644 --- a/ctr-std/src/panicking.rs +++ b/ctr-std/src/panicking.rs @@ -57,8 +57,37 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments, file_line_col: &(&'static str, u32, begin_panic(s, file_line_col); } -/// We don't have stack unwinding, so all we do is print the panic message -/// and then crash or hang the application +// Citra doesn't support the Error applet yet +#[cfg(feature = "citra")] +#[unstable(feature = "libstd_sys_internals", + reason = "used by the panic! macro", + issue = "0")] +#[inline(never)] #[cold] +pub fn begin_panic(msg: M, file_line_col: &(&'static str, u32, u32)) -> ! { + let msg = Box::new(msg); + let (file, line, col) = *file_line_col; + + // 3DS-specific code begins here + use libctru::{consoleInit, gfxScreen_t}; + + unsafe { + // set up a new console, overwriting whatever was on the top screen + // before we started panicking + let _console = consoleInit(gfxScreen_t::GFX_TOP, ptr::null_mut()); + + println!("thread '{}' panicked at '{}', {}:{}:{}", + "", msg, file, line, col); + + // Citra seems to ignore calls to svcExitProcess, and libc::abort() + // causes it to lock up and fill the console with endless debug statements. + // So instead of terminating the program, we just let it spin in the following + // loop. This means that any background threads might continue to run after + // this thread panics, but there's not a lot we can do about that currently. + loop { } + } +} + +#[cfg(not(feature = "citra"))] #[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "0")] @@ -75,14 +104,14 @@ pub fn begin_panic(msg: M, file_line_col: &(&'static st unsafe { // Setup error payload let error_text = format!("thread '{}' panicked at '{}', {}:{}:{}", - "", msg, file, line, col); + "", msg, file, line, col); let mut error_conf: errorConf = mem::uninitialized(); errorInit(&mut error_conf, errorType::ERROR_TEXT_WORD_WRAP, CFG_Language::CFG_LANGUAGE_EN); errorText(&mut error_conf, error_text.as_ptr() as *const libc::c_char); - // Display error via Error applet + // Display error errorDisp(&mut error_conf); // Now that we're all done printing, it's time to exit the program.