Restart crash handler on disconnect

Julia Ryan created

Change summary

crates/crashes/src/crashes.rs | 70 +++++++++++++++++++-----------------
1 file changed, 37 insertions(+), 33 deletions(-)

Detailed changes

crates/crashes/src/crashes.rs 🔗

@@ -32,34 +32,7 @@ const CRASH_HANDLER_CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
 #[cfg(target_os = "macos")]
 static PANIC_THREAD_ID: AtomicU32 = AtomicU32::new(0);
 
-pub async fn init(crash_init: InitCrashHandler) {
-    let gen_var = match env::var("ZED_GENERATE_MINIDUMPS") {
-        Ok(v) => {
-            if v == "false" || v == "0" {
-                Some(false)
-            } else {
-                Some(true)
-            }
-        }
-        Err(_) => None,
-    };
-
-    match (gen_var, *RELEASE_CHANNEL) {
-        (Some(false), _) | (None, ReleaseChannel::Dev) => {
-            let old_hook = panic::take_hook();
-            panic::set_hook(Box::new(move |info| {
-                unsafe { env::set_var("RUST_BACKTRACE", "1") };
-                old_hook(info);
-                // prevent the macOS crash dialog from popping up
-                std::process::exit(1);
-            }));
-            return;
-        }
-        (Some(true), _) | (None, _) => {
-            panic::set_hook(Box::new(panic_hook));
-        }
-    }
-
+pub async fn spawn_sidecar(crash_init: InitCrashHandler) -> Client {
     let exe = env::current_exe().expect("unable to find ourselves");
     let zed_pid = process::id();
     // TODO: we should be able to get away with using 1 crash-handler process per machine,
@@ -68,14 +41,15 @@ pub async fn init(crash_init: InitCrashHandler) {
     // used by the crash handler isn't destroyed correctly which causes it to stay on the file
     // system and block further attempts to initialize crash handlers with that socket path.
     let socket_name = paths::temp_dir().join(format!("zed-crash-handler-{zed_pid}"));
-    let _crash_handler = Command::new(exe)
+    let crash_handler = Command::new(exe)
         .arg("--crash-handler")
         .arg(&socket_name)
         .spawn()
         .expect("unable to spawn server process");
-    #[cfg(target_os = "linux")]
-    let server_pid = _crash_handler.id();
-    info!("spawning crash handler process");
+
+    let server_pid = crash_handler.id();
+    info!("spawned crash handler process with pid: {server_pid}");
+    server_pid
 
     let mut elapsed = Duration::ZERO;
     let retry_frequency = Duration::from_millis(100);
@@ -93,8 +67,38 @@ pub async fn init(crash_init: InitCrashHandler) {
     client
         .send_message(1, serde_json::to_vec(&crash_init).unwrap())
         .unwrap();
+    client
+}
+
+pub async fn init(crash_init: InitCrashHandler) {
+    let gen_var = match env::var("ZED_GENERATE_MINIDUMPS") {
+        Ok(v) => {
+            if v == "false" || v == "0" {
+                Some(false)
+            } else {
+                Some(true)
+            }
+        }
+        Err(_) => None,
+    };
+
+    match (gen_var, *RELEASE_CHANNEL) {
+        (Some(false), _) | (None, ReleaseChannel::Dev) => {
+            let old_hook = panic::take_hook();
+            panic::set_hook(Box::new(move |info| {
+                unsafe { env::set_var("RUST_BACKTRACE", "1") };
+                old_hook(info);
+                // prevent the macOS crash dialog from popping up
+                std::process::exit(1);
+            }));
+            return;
+        }
+        (Some(true), _) | (None, _) => {
+            panic::set_hook(Box::new(panic_hook));
+        }
+    }
 
-    let client = Arc::new(client);
+    let client = Arc::new(spawn_sidecar(crash_init.clone()).await);
     let handler = CrashHandler::attach(unsafe {
         let client = client.clone();
         crash_handler::make_crash_event(move |crash_context: &crash_handler::CrashContext| {