libobs_wrapper\crash_handler/
mod.rs1use std::{ffi::c_void, sync::Mutex};
6
7use lazy_static::lazy_static;
8
9#[cfg(feature = "dialog_crash_handler")]
10pub mod dialog;
11
12pub trait ObsCrashHandler: Send {
20 fn handle_crash(&self, message: String);
23}
24
25pub struct ConsoleCrashHandler {
26 _private: (),
27}
28
29impl Default for ConsoleCrashHandler {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl ConsoleCrashHandler {
36 pub fn new() -> Self {
37 Self { _private: () }
38 }
39}
40impl ObsCrashHandler for ConsoleCrashHandler {
41 fn handle_crash(&self, message: String) {
42 #[cfg(not(feature = "logging_crash_handler"))]
43 eprintln!("OBS crashed: {}", message);
44 #[cfg(feature = "logging_crash_handler")]
45 log::error!("OBS crashed: {}", message);
46 }
47}
48
49lazy_static! {
50 static ref CRASH_HANDLER: Mutex<Box<dyn ObsCrashHandler>> = {
52 #[cfg(feature="dialog_crash_handler")]
53 {
54 Mutex::new(Box::new(dialog::DialogCrashHandler::new()))
55 }
56 #[cfg(not(feature="dialog_crash_handler"))]
57 {
58 Mutex::new(Box::new(ConsoleCrashHandler::new()))
59 }
60 };
61}
62
63pub(crate) unsafe extern "C" fn main_crash_handler<V>(
67 format: *const std::os::raw::c_char,
68 args: *mut V,
69 _params: *mut c_void,
70) {
71 let Ok(message) = vsprintf::vsprintf(format, args) else {
72 eprintln!("Failed to format crash handler message");
73 return;
74 };
75 let handler = CRASH_HANDLER
76 .lock()
77 .unwrap_or_else(|poisoned| poisoned.into_inner());
78 handler.handle_crash(message);
79}