libobs_wrapper\crash_handler/
mod.rs

1use std::{ffi::c_void, sync::Mutex};
2
3use lazy_static::lazy_static;
4
5#[cfg(feature = "dialog_crash_handler")]
6pub mod dialog;
7
8pub trait ObsCrashHandler: Send {
9    fn handle_crash(&self, message: String);
10}
11
12pub struct ConsoleCrashHandler {
13    _private: (),
14}
15
16impl ConsoleCrashHandler {
17    pub fn new() -> Self {
18        Self { _private: () }
19    }
20}
21impl ObsCrashHandler for ConsoleCrashHandler {
22    fn handle_crash(&self, message: String) {
23        eprintln!("OBS crashed: {}", message);
24    }
25}
26
27lazy_static! {
28    /// We are using this as global variable because there can only be one obs context
29    pub static ref CRASH_HANDLER: Mutex<Box<dyn ObsCrashHandler>> = {
30        #[cfg(feature="dialog_crash_handler")]
31        {
32            Mutex::new(Box::new(dialog::DialogCrashHandler::new()))
33        }
34        #[cfg(not(feature="dialog_crash_handler"))]
35        {
36            Mutex::new(Box::new(ConsoleCrashHandler {}))
37        }
38    };
39}
40
41pub(crate) unsafe extern "C" fn main_crash_handler(
42    format: *const i8,
43    args: *mut i8,
44    _params: *mut c_void,
45) {
46    let res = vsprintf::vsprintf(format, args);
47    if res.is_err() {
48        eprintln!("Failed to format crash handler message");
49        return;
50    }
51
52    let res = res.unwrap();
53    CRASH_HANDLER.lock().unwrap().handle_crash(res);
54}