From e8fe0eb2e60774bd7d27276ba15431564b5c6174 Mon Sep 17 00:00:00 2001 From: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> Date: Mon, 21 Apr 2025 14:25:38 -0400 Subject: [PATCH] debugger: Fix restarting terminated child sessions (#29173) This fixes a bug where terminated child session failed to restart because they were using the wrong configuration/binary to start a new session Release Notes: - N/A --- crates/project/src/debugger/dap_store.rs | 26 +++++++----- crates/project/src/debugger/session.rs | 50 ++++++++++-------------- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/crates/project/src/debugger/dap_store.rs b/crates/project/src/debugger/dap_store.rs index eb3524a77b556abcb9cd6d92d6ec952817562ca1..cd3d87491428fe1cee4196f5808ce1095a4dcba0 100644 --- a/crates/project/src/debugger/dap_store.rs +++ b/crates/project/src/debugger/dap_store.rs @@ -902,15 +902,6 @@ fn create_new_session( this.shutdown_session(session_id, cx).detach_and_log_err(cx); } SessionStateEvent::Restart => { - let Some((config, binary)) = session.read_with(cx, |session, _| { - session - .configuration() - .map(|config| (config, session.binary().clone())) - }) else { - log::error!("Failed to get debug config from session"); - return; - }; - let mut curr_session = session; while let Some(parent_id) = curr_session.read(cx).parent_id() { if let Some(parent_session) = this.sessions.get(&parent_id).cloned() { @@ -921,6 +912,15 @@ fn create_new_session( } } + let Some((config, binary)) = curr_session.read_with(cx, |session, _| { + session + .configuration() + .map(|config| (config, session.root_binary().clone())) + }) else { + log::error!("Failed to get debug config from session"); + return; + }; + let session_id = curr_session.read(cx).session_id(); let task = curr_session.update(cx, |session, cx| session.shutdown(cx)); @@ -931,7 +931,13 @@ fn create_new_session( this.update(cx, |this, cx| { this.sessions.remove(&session_id); - this.new_session(binary, config, worktree, None, cx) + this.new_session( + binary.as_ref().clone(), + config, + worktree, + None, + cx, + ) })? .1 .await?; diff --git a/crates/project/src/debugger/session.rs b/crates/project/src/debugger/session.rs index 0783b85c4faa01727e3db13c722b0d37bab6058b..c7ae32c6e129a9355b06e2647ad4657c98ed718e 100644 --- a/crates/project/src/debugger/session.rs +++ b/crates/project/src/debugger/session.rs @@ -164,6 +164,7 @@ pub struct LocalMode { client: Arc, definition: DebugTaskDefinition, binary: DebugAdapterBinary, + root_binary: Option>, pub(crate) breakpoint_store: Entity, tmp_breakpoint: Option, worktree: WeakEntity, @@ -194,36 +195,18 @@ impl LocalMode { binary: DebugAdapterBinary, messages_tx: futures::channel::mpsc::UnboundedSender, cx: AsyncApp, - ) -> Task> { - Self::new_inner( - session_id, - parent_session, - breakpoint_store, - worktree, - config, - binary, - messages_tx, - async |_, _| {}, - cx, - ) - } - - fn new_inner( - session_id: SessionId, - parent_session: Option>, - breakpoint_store: Entity, - worktree: WeakEntity, - config: DebugTaskDefinition, - binary: DebugAdapterBinary, - messages_tx: futures::channel::mpsc::UnboundedSender, - on_initialized: impl AsyncFnOnce(&mut LocalMode, AsyncApp) + 'static, - cx: AsyncApp, ) -> Task> { cx.spawn(async move |cx| { let message_handler = Box::new(move |message| { messages_tx.unbounded_send(message).ok(); }); + let root_binary = if let Some(parent_session) = parent_session.as_ref() { + Some(parent_session.read_with(cx, |session, _| session.root_binary().clone())?) + } else { + None + }; + let client = Arc::new( if let Some(client) = parent_session .and_then(|session| cx.update(|cx| session.read(cx).adapter_client()).ok()) @@ -244,18 +227,15 @@ impl LocalMode { }, ); - let mut session = Self { + Ok(Self { client, breakpoint_store, worktree, tmp_breakpoint: None, definition: config, + root_binary, binary, - }; - - on_initialized(&mut session, cx.clone()).await; - - Ok(session) + }) }) } @@ -840,6 +820,16 @@ impl Session { &self.capabilities } + pub(crate) fn root_binary(&self) -> Arc { + let Mode::Local(local_mode) = &self.mode else { + panic!("Session is not local"); + }; + local_mode + .root_binary + .clone() + .unwrap_or_else(|| Arc::new(local_mode.binary.clone())) + } + pub fn binary(&self) -> &DebugAdapterBinary { let Mode::Local(local_mode) = &self.mode else { panic!("Session is not local");