Why am I not getting the backtrace from the thread that panicked first?
(the “launchpad” thread, that caused “attempt to subtract with overflow”)
panic occured: Some("called `Result::unwrap()` on an `Err` value: \"SendError(..)\"")
stack backtrace:
0: 0x7ff6a0023b8d - backtrace::backtrace::trace<closure>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.
3\src\backtrace\mod.rs:41
1: 0x7ff6a0022ceb - backtrace::capture::Backtrace::new_unresolved
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.
3\src\capture.rs:97
2: 0x7ff6a0022c63 - backtrace::capture::Backtrace::new
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.
3\src\capture.rs:64
3: 0x7ff69fc5a495 - myproject::main::{{closure}}
at D:\projects\myproject\src\main.rs:119
4: 0x7ff6a0034064 - std::panicking::rust_panic_with_hook
at C:\projects\rust\src\libstd\panicking.rs:577
5: 0x7ff6a0033e51 - std::panicking::begin_panic<alloc::string::String>
at C:\projects\rust\src\libstd\panicking.rs:537
6: 0x7ff6a0033da2 - std::panicking::begin_panic_fmt
at C:\projects\rust\src\libstd\panicking.rs:521
7: 0x7ff6a0033d1a - std::panicking::rust_begin_panic
at C:\projects\rust\src\libstd\panicking.rs:497
8: 0x7ff6a0048cbd - core::panicking::panic_fmt
at C:\projects\rust\src\libcore\panicking.rs:71
9: 0x7ff69fc1442b - core::result::unwrap_failed<std::sync::mpsc::SendError<window::MsgCoreToWi
n>>
at C:\projects\rust\src\libcore\macros.rs:23
10: 0x7ff69fc38ca9 - core::result::Result<(), std::sync::mpsc::SendError<window::MsgCoreToWin>>
::unwrap<(),std::sync::mpsc::SendError<window::MsgCoreToWin>>
at C:\projects\rust\src\libcore\result.rs:782
11: 0x7ff69fc39fa2 - myproject::daw::Daw::load
at D:\projects\myproject\src\daw.rs:144
12: 0x7ff69fc3e12e - myproject::daw::thread_fn_daw
at D:\projects\myproject\src\daw.rs:736
13: 0x7ff69fc7b13b - myproject::thread_fn_main::{{closure}}
at D:\projects\myproject\src\main.rs:198
14: 0x7ff69fc7ab5d - std::sys_common::backtrace::__rust_begin_short_backtrace<closure,core::res
ult::Result<(), alloc::boxed::Box<Error>>>
at C:\projects\rust\src\libstd\sys_common\backtrace.rs:137
15: 0x7ff69fc6f7ed - std::thread::{{impl}}::spawn::{{closure}}::{{closure}}<closure,core::resul
t::Result<(), alloc::boxed::Box<Error>>>
at C:\projects\rust\src\libstd\thread\mod.rs:407
16: 0x7ff69fc6f53d - std::panic::{{impl}}::call_once<core::result::Result<(), alloc::boxed::Box
<Error>>,closure>
at C:\projects\rust\src\libstd\panic.rs:294
17: 0x7ff69fc448f8 - std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure>,core::r
esult::Result<(), alloc::boxed::Box<Error>>>
at C:\projects\rust\src\libstd\panicking.rs:479
18: 0x7ff6a0046152 - panic_unwind::__rust_maybe_catch_panic
at C:\projects\rust\src\libpanic_unwind\lib.rs:102
19: 0x7ff69fc4466b - std::panicking::try<core::result::Result<(), alloc::boxed::Box<Error>>,std
::panic::AssertUnwindSafe<closure>>
at C:\projects\rust\src\libstd\panicking.rs:463
20: 0x7ff69fc6f71d - std::panic::catch_unwind<std::panic::AssertUnwindSafe<closure>,core::resul
t::Result<(), alloc::boxed::Box<Error>>>
at C:\projects\rust\src\libstd\panic.rs:360
21: 0x7ff69fc1afba - std::thread::{{impl}}::spawn::{{closure}}<closure,core::result::Result<(),
alloc::boxed::Box<Error>>>
at C:\projects\rust\src\libstd\thread\mod.rs:410
22: 0x7ff69fc1c483 - alloc::boxed::{{impl}}::call_box<(),closure>
at C:\projects\rust\src\liballoc\boxed.rs:789
23: 0x7ff6a002d70c - std::sys_common::thread::start_thread
at C:\projects\rust\src\libstd\sys_common\thread.rs:24
24: 0x7ff6a0036407 - std::sys::windows::thread::{{impl}}::new::thread_start
at C:\projects\rust\src\libstd\sys\windows\thread.rs:57
25: 0x7ff86e1f13d2 - BaseThreadInitThunk
INFO:myproject: thread_daw Err(Any)
ERROR:myproject: thread_launchpad Some("attempt to subtract with overflow")
INFO:webui: terminating ui_state
INFO:webui: terminating webui
When another non-main thread crashes, I DO get the backtrace from that thread, just not with this one. But they are spawned the same way:
fn main() {
{
use std::panic;
use error_chain::Backtrace;
panic::set_hook(box |panic_info| {
println!("panic occured: {:?}", panic_info.payload().downcast_ref::<String>());
println!("{:?}", Backtrace::new());
});
}
// ...
let terminate = Arc::new(AtomicBool::new(false));
let terminate_ctrlc = terminate.clone();
ctrlc::set_handler(move || terminate_ctrlc.store(true, Ordering::SeqCst)).unwrap();
let terminate_ui = terminate.clone();
let (tx_core_to_ui, rx_core_to_ui) = channel();
let (tx_ui_to_core, rx_ui_to_core) = channel();
let tx_win_to_core = tx_ui_to_core.clone();
let tx_launch_to_core = tx_ui_to_core.clone();
let thread_webui = thread::Builder::new().name("webui".to_string()).spawn(move || {
webui::thread_fn_main(CFG.ws_port, terminate_ui, rx_core_to_ui, tx_ui_to_core);
trace!("terminating webui");
}).unwrap();
let terminate_window = terminate.clone();
let (tx_core_to_win, rx_core_to_win) = channel();
let (_tx_core_to_win_unused, rx_core_to_win_unused) = channel();
let thread_window = thread::Builder::new().name("window".to_string()).spawn(move || {
thread_fn_window(terminate_window, rx_core_to_win_unused, tx_win_to_core);
trace!("terminating window");
}).unwrap();
let terminate_launchpad = terminate.clone();
let thread_launchpad = thread::Builder::new().name("launchpad".to_string()).spawn(move || {
thread_fn_launchpad(terminate_launchpad, rx_core_to_win, tx_launch_to_core);
trace!("terminating launchpad");
}).unwrap();
thread_fn_main(terminate, rx_ui_to_core, tx_core_to_ui, tx_core_to_win);
if let Err(e) = thread_launchpad.join() {
error!("thread_launchpad {:?}", e.downcast_ref::<String>());
}
if let Err(e) = thread_window.join() {
error!("thread_window {:?}", e.downcast_ref::<String>());
}
if let Err(e) = thread_webui.join() {
error!("thread_webui {:?}", e.downcast_ref::<String>());
}
db::disk_cache::save().unwrap();
trace!("terminating main");
}
How can I find out why I’m not getting the backtrace?
Thanks
(Btw, any suggestions for improving the error handling? Sometimes the panic payload is not a String, what can I do to handle all payload types in a more generic way?)