From 248f80d792535cde624ff64fecb64f95355d9074 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sat, 8 Feb 2025 15:47:48 -0800 Subject: [PATCH 1/9] add vscode debugger for apps --- packages/cli/src/cli/run.rs | 1 + packages/cli/src/serve/mod.rs | 4 ++++ packages/cli/src/serve/output.rs | 5 +++++ packages/cli/src/serve/runner.rs | 26 ++++++++++++++++++++++++++ packages/cli/src/serve/update.rs | 2 ++ 5 files changed, 38 insertions(+) diff --git a/packages/cli/src/cli/run.rs b/packages/cli/src/cli/run.rs index b9cd100275..daab053df8 100644 --- a/packages/cli/src/cli/run.rs +++ b/packages/cli/src/cli/run.rs @@ -60,6 +60,7 @@ impl RunArgs { ServeUpdate::Redraw => {} ServeUpdate::OpenApp => {} ServeUpdate::ToggleShouldRebuild => {} + ServeUpdate::OpenDebugger => {} } } diff --git a/packages/cli/src/serve/mod.rs b/packages/cli/src/serve/mod.rs index f19eff965d..ca4166d88f 100644 --- a/packages/cli/src/serve/mod.rs +++ b/packages/cli/src/serve/mod.rs @@ -242,6 +242,10 @@ pub(crate) async fn serve_all(mut args: ServeArgs) -> Result<()> { ) } + ServeUpdate::OpenDebugger => { + runner.open_debugger().await; + } + ServeUpdate::Exit { error } => match error { Some(err) => break Err(anyhow::anyhow!("{}", err).into()), None => break Ok(()), diff --git a/packages/cli/src/serve/output.rs b/packages/cli/src/serve/output.rs index b400cdf8d9..615482277e 100644 --- a/packages/cli/src/serve/output.rs +++ b/packages/cli/src/serve/output.rs @@ -263,6 +263,11 @@ impl Output { self.trace = !self.trace; tracing::info!("Tracing is now {}", if self.trace { "on" } else { "off" }); } + KeyCode::Char('d') => { + if key.modifiers.contains(KeyModifiers::SHIFT) { + return Ok(Some(ServeUpdate::OpenDebugger)); + } + } KeyCode::Char('c') => { stdout() diff --git a/packages/cli/src/serve/runner.rs b/packages/cli/src/serve/runner.rs index 597c47753f..5a522a879b 100644 --- a/packages/cli/src/serve/runner.rs +++ b/packages/cli/src/serve/runner.rs @@ -340,4 +340,30 @@ impl AppRunner { _ = std::fs::remove_dir_all(&cache_dir); _ = std::fs::create_dir_all(&cache_dir); } + + // todo: add a way to open the server's debugger too + pub(crate) async fn open_debugger(&self) { + let Some(handle) = self.running.as_ref() else { + return; + }; + + let Some(app) = handle.app_child.as_ref() else { + return; + }; + + let Some(id) = app.id() else { + return; + }; + + let url = format!( + "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", + id + ); + + tokio::process::Command::new("code") + .arg("--open-url") + .arg(url) + .spawn() + .unwrap(); + } } diff --git a/packages/cli/src/serve/update.rs b/packages/cli/src/serve/update.rs index 49e094adc7..b047467f48 100644 --- a/packages/cli/src/serve/update.rs +++ b/packages/cli/src/serve/update.rs @@ -10,6 +10,8 @@ pub(crate) enum ServeUpdate { NewConnection, WsMessage(WsMessage), + OpenDebugger, + /// A build update from the build engine BuildUpdate(BuildUpdate), From e2e0b2a8130f9a92736cc082cfce3a3e8df0b32b Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sat, 8 Feb 2025 16:25:03 -0800 Subject: [PATCH 2/9] todo: need to disconnect when rebuilding --- packages/cli/src/serve/handle.rs | 4 ++++ packages/cli/src/serve/output.rs | 7 ++++--- packages/cli/src/serve/runner.rs | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/serve/handle.rs b/packages/cli/src/serve/handle.rs index 8cad0fb170..b25fa62336 100644 --- a/packages/cli/src/serve/handle.rs +++ b/packages/cli/src/serve/handle.rs @@ -46,6 +46,9 @@ pub(crate) struct AppHandle { /// The virtual directory that assets will be served from /// Used mostly for apk/ipa builds since they live in simulator pub(crate) runtime_asst_dir: Option, + + /// The debugger for the app - must be enabled with the `d` key + pub(crate) app_debugger: Option, } impl AppHandle { @@ -61,6 +64,7 @@ impl AppHandle { server_stderr: None, entropy_app_exe: None, entropy_server_exe: None, + app_debugger: None, }) } diff --git a/packages/cli/src/serve/output.rs b/packages/cli/src/serve/output.rs index 615482277e..1edb38f46b 100644 --- a/packages/cli/src/serve/output.rs +++ b/packages/cli/src/serve/output.rs @@ -264,9 +264,10 @@ impl Output { tracing::info!("Tracing is now {}", if self.trace { "on" } else { "off" }); } KeyCode::Char('d') => { - if key.modifiers.contains(KeyModifiers::SHIFT) { - return Ok(Some(ServeUpdate::OpenDebugger)); - } + // if key.modifiers.contains(KeyModifiers::SHIFT) { + tracing::info!("Opening debugger"); + return Ok(Some(ServeUpdate::OpenDebugger)); + // } } KeyCode::Char('c') => { diff --git a/packages/cli/src/serve/runner.rs b/packages/cli/src/serve/runner.rs index 5a522a879b..4eed170c45 100644 --- a/packages/cli/src/serve/runner.rs +++ b/packages/cli/src/serve/runner.rs @@ -70,7 +70,10 @@ impl AppRunner { handle.app_child = None; ProcessExited { status, platform } }, - Err(_err) => todo!("handle error in process joining?"), + Err(_err) => { + futures_util::future::pending().await + // ProcessExited { status, platform } + }, } } Some(Ok(Some(msg))) = OptionFuture::from(handle.server_stdout.as_mut().map(|f| f.next_line())) => { @@ -360,6 +363,8 @@ impl AppRunner { id ); + tracing::info!("Opening debugger: {url}"); + tokio::process::Command::new("code") .arg("--open-url") .arg(url) From 39aeb9ee4a6196c35f5f85b95dffa8aa77e28e6e Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Thu, 15 May 2025 14:17:25 +0200 Subject: [PATCH 3/9] update debugger --- packages/cli/src/build/builder.rs | 19 ++++++++++++++++ packages/cli/src/serve/mod.rs | 2 +- packages/cli/src/serve/output.rs | 15 ++++++++----- packages/cli/src/serve/runner.rs | 37 ++++++++++--------------------- 4 files changed, 42 insertions(+), 31 deletions(-) diff --git a/packages/cli/src/build/builder.rs b/packages/cli/src/build/builder.rs index 83c7a669a6..1f4752af13 100644 --- a/packages/cli/src/build/builder.rs +++ b/packages/cli/src/build/builder.rs @@ -1343,4 +1343,23 @@ We checked the folder: {} pub(crate) fn can_receive_hotreloads(&self) -> bool { matches!(&self.stage, BuildStage::Success | BuildStage::Failed) } + + pub(crate) async fn open_debugger(&mut self) { + let Some(Some(pid)) = self.child.as_mut().map(|f| f.id()) else { + tracing::warn!("No process to attach debugger to"); + return; + }; + + let url = format!( + "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", + pid + ); + + tracing::info!("Opening debugger: {url}"); + + _ = tokio::process::Command::new("code") + .arg("--open-url") + .arg(url) + .spawn(); + } } diff --git a/packages/cli/src/serve/mod.rs b/packages/cli/src/serve/mod.rs index 062584c65c..dc0155ac67 100644 --- a/packages/cli/src/serve/mod.rs +++ b/packages/cli/src/serve/mod.rs @@ -203,7 +203,7 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) -> } ServeUpdate::OpenDebugger { id } => { - builder.open_debugger().await; + builder.open_debugger(id).await; } ServeUpdate::Exit { error } => { diff --git a/packages/cli/src/serve/output.rs b/packages/cli/src/serve/output.rs index 7e130e60a6..8ab2c56b98 100644 --- a/packages/cli/src/serve/output.rs +++ b/packages/cli/src/serve/output.rs @@ -1,6 +1,6 @@ use crate::{ serve::{ansi_buffer::AnsiStringLine, ServeUpdate, WebServer}, - BuildStage, BuilderUpdate, Platform, TraceContent, TraceMsg, TraceSrc, + BuildId, BuildStage, BuilderUpdate, Platform, TraceContent, TraceMsg, TraceSrc, }; use crossterm::{ cursor::{Hide, Show}, @@ -245,10 +245,15 @@ impl Output { tracing::info!("Tracing is now {}", if self.trace { "on" } else { "off" }); } KeyCode::Char('d') => { - // if key.modifiers.contains(KeyModifiers::SHIFT) { - tracing::info!("Opening debugger"); - return Ok(Some(ServeUpdate::OpenDebugger)); - // } + if key.modifiers.contains(KeyModifiers::SHIFT) { + return Ok(Some(ServeUpdate::OpenDebugger { + id: BuildId::SERVER, + })); + } else { + return Ok(Some(ServeUpdate::OpenDebugger { + id: BuildId::CLIENT, + })); + } } KeyCode::Char('c') => { diff --git a/packages/cli/src/serve/runner.rs b/packages/cli/src/serve/runner.rs index 180482b65c..f2992459a5 100644 --- a/packages/cli/src/serve/runner.rs +++ b/packages/cli/src/serve/runner.rs @@ -969,31 +969,18 @@ impl AppServer { } // todo: add a way to open the server's debugger too - pub(crate) async fn open_debugger(&self) { - let Some(handle) = self.running.as_ref() else { - return; - }; - - let Some(app) = handle.app_child.as_ref() else { - return; - }; - - let Some(id) = app.id() else { - return; - }; - - let url = format!( - "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", - id - ); - - tracing::info!("Opening debugger: {url}"); - - tokio::process::Command::new("code") - .arg("--open-url") - .arg(url) - .spawn() - .unwrap(); + pub(crate) async fn open_debugger(&mut self, build: BuildId) { + match build { + BuildId::CLIENT => { + self.client.open_debugger().await; + } + BuildId::SERVER => { + if let Some(server) = self.server.as_mut() { + server.open_debugger().await; + } + } + _ => {} + } } } From 8f50eaa5279de8e47ff202a55a081e97f87b58a6 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Thu, 15 May 2025 16:30:33 +0200 Subject: [PATCH 4/9] add uri handler to remote launch the debugger --- packages/extension/.gitignore | 1 + packages/extension/src/main.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/packages/extension/.gitignore b/packages/extension/.gitignore index 548955b60f..7a61312978 100644 --- a/packages/extension/.gitignore +++ b/packages/extension/.gitignore @@ -11,3 +11,4 @@ tsconfig.lsif.json *.lsif *.db *.vsix +pkg/ diff --git a/packages/extension/src/main.ts b/packages/extension/src/main.ts index 03bf55b830..b782456e1f 100644 --- a/packages/extension/src/main.ts +++ b/packages/extension/src/main.ts @@ -22,6 +22,9 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand('extension.formatRsxDocument', formatRsxDocument), vscode.workspace.onWillSaveTextDocument(fmtDocumentOnSave) ); + + context.subscriptions.push(vscode.window.registerUriHandler(new UriLaunchServer())); + } function translate(component: boolean) { @@ -171,3 +174,15 @@ function fmtDocument(document: vscode.TextDocument) { vscode.window.showWarningMessage(`Errors occurred while formatting. Make sure you have the most recent Dioxus-CLI installed! \n${error}`); } } + +class UriLaunchServer implements vscode.UriHandler { + handleUri(uri: vscode.Uri): vscode.ProviderResult { + console.log("URI Handler: ", uri); + if (uri.path === '/debugger') { + let query = decodeURIComponent(uri.query); + let params = new URLSearchParams(query); + let route = params.get('uri'); + vscode.commands.executeCommand('vscode.js-debug.debugLink', route); + } + } +} From 246e2b8cfabedb85a9a5c9c80396d06d71a28d73 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Thu, 15 May 2025 18:25:40 +0200 Subject: [PATCH 5/9] attach --- packages/cli/src/build/builder.rs | 48 ++++++++++++++++++++++++------- packages/cli/src/serve/mod.rs | 2 +- packages/cli/src/serve/runner.rs | 6 ++-- packages/extension/package.json | 2 +- packages/extension/src/main.ts | 4 +-- 5 files changed, 44 insertions(+), 18 deletions(-) diff --git a/packages/cli/src/build/builder.rs b/packages/cli/src/build/builder.rs index 1f4752af13..bc40ba4fe4 100644 --- a/packages/cli/src/build/builder.rs +++ b/packages/cli/src/build/builder.rs @@ -1,6 +1,6 @@ use crate::{ - BuildArtifacts, BuildRequest, BuildStage, BuilderUpdate, Platform, ProgressRx, ProgressTx, - Result, StructuredOutput, + serve::WebServer, BuildArtifacts, BuildRequest, BuildStage, BuilderUpdate, Platform, + ProgressRx, ProgressTx, Result, StructuredOutput, }; use anyhow::Context; use dioxus_cli_opt::process_file_to; @@ -94,6 +94,7 @@ pub(crate) struct AppBuilder { /// The debugger for the app - must be enabled with the `d` key pub(crate) app_debugger: Option, + pub(crate) pid: Option, } impl AppBuilder { @@ -160,6 +161,7 @@ impl AppBuilder { artifacts: None, patch_cache: None, app_debugger: None, + pid: None, }) } @@ -792,6 +794,7 @@ impl AppBuilder { .arg("simctl") .arg("launch") .arg("--console") + // .arg("--terminate-running-process") .arg("booted") .arg(self.build.bundle_identifier()) .envs(ios_envs) @@ -1344,16 +1347,39 @@ We checked the folder: {} matches!(&self.stage, BuildStage::Success | BuildStage::Failed) } - pub(crate) async fn open_debugger(&mut self) { - let Some(Some(pid)) = self.child.as_mut().map(|f| f.id()) else { - tracing::warn!("No process to attach debugger to"); - return; - }; + pub(crate) async fn open_debugger(&mut self, server: &WebServer) { + let url = match self.build.platform { + Platform::Web => { + // code --open-url "vscode://DioxusLabs.dioxus/debugger?uri=http://127.0.0.1:8080" + let address = server.devserver_address(); + let base_path = self.build.config.web.app.base_path.clone(); + let https = self.build.config.web.https.enabled.unwrap_or_default(); + let protocol = if https { "https" } else { "http" }; + let base_path = match base_path.as_deref() { + Some(base_path) => format!("/{}", base_path.trim_matches('/')), + None => "".to_owned(), + }; + format!("vscode://DioxusLabs.dioxus/debugger?uri={protocol}://{address}{base_path}") + } + Platform::Ios => return, + Platform::Android => return, - let url = format!( - "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", - pid - ); + Platform::MacOS + | Platform::Windows + | Platform::Linux + | Platform::Server + | Platform::Liveview => { + let Some(Some(pid)) = self.child.as_mut().map(|f| f.id()) else { + tracing::warn!("No process to attach debugger to"); + return; + }; + + format!( + "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", + pid + ) + } + }; tracing::info!("Opening debugger: {url}"); diff --git a/packages/cli/src/serve/mod.rs b/packages/cli/src/serve/mod.rs index 63945a9273..bba623f5a0 100644 --- a/packages/cli/src/serve/mod.rs +++ b/packages/cli/src/serve/mod.rs @@ -203,7 +203,7 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) -> } ServeUpdate::OpenDebugger { id } => { - builder.open_debugger(id).await; + builder.open_debugger(&devserver, id).await; } ServeUpdate::Exit { error } => { diff --git a/packages/cli/src/serve/runner.rs b/packages/cli/src/serve/runner.rs index 36fd737093..5d5f4d7755 100644 --- a/packages/cli/src/serve/runner.rs +++ b/packages/cli/src/serve/runner.rs @@ -972,14 +972,14 @@ impl AppServer { } // todo: add a way to open the server's debugger too - pub(crate) async fn open_debugger(&mut self, build: BuildId) { + pub(crate) async fn open_debugger(&mut self, dev: &WebServer, build: BuildId) { match build { BuildId::CLIENT => { - self.client.open_debugger().await; + self.client.open_debugger(dev).await; } BuildId::SERVER => { if let Some(server) = self.server.as_mut() { - server.open_debugger().await; + server.open_debugger(dev).await; } } _ => {} diff --git a/packages/extension/package.json b/packages/extension/package.json index 0918a69073..7d066a5c81 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -2,7 +2,7 @@ "name": "dioxus", "displayName": "Dioxus", "description": "Useful tools for working with Dioxus", - "version": "0.6.0", + "version": "0.7.0", "publisher": "DioxusLabs", "private": true, "license": "MIT", diff --git a/packages/extension/src/main.ts b/packages/extension/src/main.ts index b782456e1f..99005f3e86 100644 --- a/packages/extension/src/main.ts +++ b/packages/extension/src/main.ts @@ -177,12 +177,12 @@ function fmtDocument(document: vscode.TextDocument) { class UriLaunchServer implements vscode.UriHandler { handleUri(uri: vscode.Uri): vscode.ProviderResult { - console.log("URI Handler: ", uri); if (uri.path === '/debugger') { let query = decodeURIComponent(uri.query); let params = new URLSearchParams(query); let route = params.get('uri'); - vscode.commands.executeCommand('vscode.js-debug.debugLink', route); + vscode.window.showInformationMessage(`Opening Chrome debugger: ${route}`); + vscode.commands.executeCommand('extension.js-debug.debugLink', route); } } } From 910db31e6acaba5ae35b3e1695d3cfb19bd6a0a7 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Thu, 15 May 2025 18:45:56 +0200 Subject: [PATCH 6/9] dont panic --- packages/cli/src/build/builder.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/build/builder.rs b/packages/cli/src/build/builder.rs index bc40ba4fe4..15bfbc77e4 100644 --- a/packages/cli/src/build/builder.rs +++ b/packages/cli/src/build/builder.rs @@ -7,6 +7,7 @@ use dioxus_cli_opt::process_file_to; use futures_util::{future::OptionFuture, pin_mut, FutureExt}; use std::{ env, + process::ExitStatus, time::{Duration, Instant, SystemTime}, }; use std::{ @@ -191,10 +192,15 @@ impl AppBuilder { Some(status) = OptionFuture::from(self.child.as_mut().map(|f| f.wait())) => { // Panicking here is on purpose. If the task crashes due to a JoinError (a panic), // we want to propagate that panic up to the serve controller. - let status = status.unwrap(); self.child = None; + match status { + Ok(status) => ProcessExited { status }, + Err(err) => { + tracing::error!("Failed to wait for child process: {err}"); + ProcessExited { status: ExitStatus::default() } - ProcessExited { status } + } + } } }; From 9a90a0d0002028e32b18ef0468bf72361256fcaa Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Fri, 16 May 2025 15:29:34 +0200 Subject: [PATCH 7/9] fixed it - hung processes are not errors --- packages/cli/src/build/builder.rs | 9 +++------ packages/cli/src/build/context.rs | 6 ++++++ packages/cli/src/serve/mod.rs | 5 +++++ packages/cli/src/serve/runner.rs | 4 ++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/build/builder.rs b/packages/cli/src/build/builder.rs index 15bfbc77e4..86e4867ea7 100644 --- a/packages/cli/src/build/builder.rs +++ b/packages/cli/src/build/builder.rs @@ -7,7 +7,6 @@ use dioxus_cli_opt::process_file_to; use futures_util::{future::OptionFuture, pin_mut, FutureExt}; use std::{ env, - process::ExitStatus, time::{Duration, Instant, SystemTime}, }; use std::{ @@ -195,11 +194,7 @@ impl AppBuilder { self.child = None; match status { Ok(status) => ProcessExited { status }, - Err(err) => { - tracing::error!("Failed to wait for child process: {err}"); - ProcessExited { status: ExitStatus::default() } - - } + Err(err) => ProcessWaitFailed { err } } } }; @@ -275,6 +270,7 @@ impl AppBuilder { StdoutReceived { .. } => {} StderrReceived { .. } => {} ProcessExited { .. } => {} + ProcessWaitFailed { .. } => {} } update @@ -414,6 +410,7 @@ impl AppBuilder { BuilderUpdate::StdoutReceived { .. } => {} BuilderUpdate::StderrReceived { .. } => {} BuilderUpdate::ProcessExited { .. } => {} + BuilderUpdate::ProcessWaitFailed { .. } => {} } } } diff --git a/packages/cli/src/build/context.rs b/packages/cli/src/build/context.rs index 33eec6f9f6..8ec8292157 100644 --- a/packages/cli/src/build/context.rs +++ b/packages/cli/src/build/context.rs @@ -65,6 +65,12 @@ pub enum BuilderUpdate { ProcessExited { status: ExitStatus, }, + + /// Waiting for the process failed. This might be because it's hung or being debugged. + /// This is not the same as the process exiting, so it should just be logged but not treated as an error. + ProcessWaitFailed { + err: std::io::Error, + }, } impl BuildContext { diff --git a/packages/cli/src/serve/mod.rs b/packages/cli/src/serve/mod.rs index bba623f5a0..7240791352 100644 --- a/packages/cli/src/serve/mod.rs +++ b/packages/cli/src/serve/mod.rs @@ -173,6 +173,11 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) -> tracing::error!("Application [{platform}] exited with error: {status}"); } } + BuilderUpdate::ProcessWaitFailed { err } => { + tracing::warn!( + "Failed to wait for process - maybe it's hung or beng debugged?: {err}" + ); + } } } diff --git a/packages/cli/src/serve/runner.rs b/packages/cli/src/serve/runner.rs index 5d5f4d7755..82bd00c272 100644 --- a/packages/cli/src/serve/runner.rs +++ b/packages/cli/src/serve/runner.rs @@ -534,7 +534,7 @@ impl AppServer { // Always open the server first after the client has been built if let Some(server) = self.server.as_mut() { tracing::debug!("Opening server build"); - server.soft_kill().await; + // server.soft_kill().await; server .open( devserver_ip, @@ -548,7 +548,7 @@ impl AppServer { } // Start the new app before we kill the old one to give it a little bit of time - self.client.soft_kill().await; + // self.client.soft_kill().await; self.client .open( devserver_ip, From a668f5c4205228ac7176ff3bec2255bcd32b8399 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sun, 18 May 2025 11:30:38 +0200 Subject: [PATCH 8/9] wip: android debugger --- packages/cli/src/build/builder.rs | 231 +++++++++++++++++++++++++----- packages/cli/src/build/request.rs | 6 + packages/cli/src/cli/run.rs | 1 + packages/cli/src/serve/output.rs | 17 ++- packages/cli/src/serve/server.rs | 7 +- packages/devtools/src/lib.rs | 5 +- 6 files changed, 215 insertions(+), 52 deletions(-) diff --git a/packages/cli/src/build/builder.rs b/packages/cli/src/build/builder.rs index 86e4867ea7..6a8e000569 100644 --- a/packages/cli/src/build/builder.rs +++ b/packages/cli/src/build/builder.rs @@ -5,8 +5,10 @@ use crate::{ use anyhow::Context; use dioxus_cli_opt::process_file_to; use futures_util::{future::OptionFuture, pin_mut, FutureExt}; +use itertools::Itertools; use std::{ env, + pin::Pin, time::{Duration, Instant, SystemTime}, }; use std::{ @@ -16,7 +18,7 @@ use std::{ }; use subsecond_types::JumpTable; use tokio::{ - io::{AsyncBufReadExt, BufReader, Lines}, + io::{AsyncBufRead, AsyncBufReadExt, BufReader, Lines}, process::{Child, ChildStderr, ChildStdout, Command}, task::JoinHandle, }; @@ -73,8 +75,8 @@ pub(crate) struct AppBuilder { // stdio for the app so we can read its stdout/stderr // we don't map stdin today (todo) but most apps don't need it - pub stdout: Option>>, - pub stderr: Option>>, + pub stdout: Option>>>, + pub stderr: Option>>>, /// The executables but with some extra entropy in their name so we can run two instances of the /// same app without causing collisions on the filesystem. @@ -93,7 +95,6 @@ pub(crate) struct AppBuilder { pub bundle_end: Option, /// The debugger for the app - must be enabled with the `d` key - pub(crate) app_debugger: Option, pub(crate) pid: Option, } @@ -160,7 +161,6 @@ impl AppBuilder { entropy_app_exe: None, artifacts: None, patch_cache: None, - app_debugger: None, pid: None, }) } @@ -189,12 +189,15 @@ impl AppBuilder { StderrReceived { msg } }, Some(status) = OptionFuture::from(self.child.as_mut().map(|f| f.wait())) => { - // Panicking here is on purpose. If the task crashes due to a JoinError (a panic), - // we want to propagate that panic up to the serve controller. - self.child = None; match status { - Ok(status) => ProcessExited { status }, - Err(err) => ProcessWaitFailed { err } + Ok(status) => { + self.child = None; + ProcessExited { status } + }, + Err(err) => { + let () = futures_util::future::pending().await; + ProcessWaitFailed { err } + } } } }; @@ -473,7 +476,7 @@ impl AppBuilder { } // We try to use stdin/stdout to communicate with the app - let running_process = match self.build.platform { + match self.build.platform { // Unfortunately web won't let us get a proc handle to it (to read its stdout/stderr) so instead // use use the websocket to communicate with it. I wish we could merge the concepts here, // like say, opening the socket as a subprocess, but alas, it's simpler to do that somewhere else. @@ -482,15 +485,12 @@ impl AppBuilder { if open_browser { self.open_web(open_address.unwrap_or(devserver_ip)); } - - None } - Platform::Ios => Some(self.open_ios_sim(envs).await?), + Platform::Ios => self.open_ios_sim(envs).await?, Platform::Android => { self.open_android_sim(false, devserver_ip, envs).await?; - None } // These are all just basically running the main exe, but with slightly different resource dir paths @@ -498,18 +498,9 @@ impl AppBuilder { | Platform::MacOS | Platform::Windows | Platform::Linux - | Platform::Liveview => Some(self.open_with_main_exe(envs)?), + | Platform::Liveview => self.open_with_main_exe(envs)?, }; - // If we have a running process, we need to attach to it and wait for its outputs - if let Some(mut child) = running_process { - let stdout = BufReader::new(child.stdout.take().unwrap()); - let stderr = BufReader::new(child.stderr.take().unwrap()); - self.stdout = Some(stdout.lines()); - self.stderr = Some(stderr.lines()); - self.child = Some(child); - } - self.builds_opened += 1; Ok(()) @@ -737,19 +728,27 @@ impl AppBuilder { /// paths right now, but they will when we start to enable things like swift integration. /// /// Server/liveview/desktop are all basically the same, though - fn open_with_main_exe(&mut self, envs: Vec<(&str, String)>) -> Result { + fn open_with_main_exe(&mut self, envs: Vec<(&str, String)>) -> Result<()> { let main_exe = self.app_exe(); tracing::debug!("Opening app with main exe: {main_exe:?}"); - let child = Command::new(main_exe) + let mut child = Command::new(main_exe) .envs(envs) .stderr(Stdio::piped()) .stdout(Stdio::piped()) .kill_on_drop(true) .spawn()?; - Ok(child) + let stdout = BufReader::new(child.stdout.take().unwrap()); + let stderr = BufReader::new(child.stderr.take().unwrap()); + let stdout: Pin> = Box::pin(stdout); + let stderr: Pin> = Box::pin(stderr); + self.stdout = Some(stdout.lines()); + self.stderr = Some(stderr.lines()); + self.child = Some(child); + + Ok(()) } /// Open the web app by opening the browser to the given address. @@ -774,7 +773,7 @@ impl AppBuilder { /// /// TODO(jon): we should probably check if there's a simulator running before trying to install, /// and open the simulator if we have to. - async fn open_ios_sim(&mut self, envs: Vec<(&str, String)>) -> Result { + async fn open_ios_sim(&mut self, envs: Vec<(&str, String)>) -> Result<()> { tracing::debug!("Installing app to simulator {:?}", self.build.root_dir()); let res = Command::new("xcrun") @@ -793,20 +792,51 @@ impl AppBuilder { .iter() .map(|(k, v)| (format!("SIMCTL_CHILD_{k}"), v.clone())); - let child = Command::new("xcrun") + let stdout_file = tempfile::tempfile()?; + let stderr_file = tempfile::tempfile()?; + + let mut child = Command::new("xcrun") .arg("simctl") .arg("launch") - .arg("--console") - // .arg("--terminate-running-process") .arg("booted") .arg(self.build.bundle_identifier()) + .arg(format!("--stdout={}", 123)) + .arg(format!("--stderr={}", 123)) .envs(ios_envs) .stderr(Stdio::piped()) .stdout(Stdio::piped()) .kill_on_drop(true) - .spawn()?; + .output() + .await?; + + let pstdout = String::from_utf8_lossy(&child.stdout); + let pstderr = String::from_utf8_lossy(&child.stderr); - Ok(child) + if child.status.success() { + self.pid = pstdout + .trim() + .split_ascii_whitespace() + .last() + .unwrap() + .parse() + .ok(); + tracing::debug!("Launched app with pid: {:?}", self.pid); + } + + let stdout_io = tokio::fs::File::from(stdout_file); + let stderr_io = tokio::fs::File::from(stderr_file); + + // Create BufReaders + let stdout_reader = BufReader::new(stdout_io); + let stderr_reader = BufReader::new(stderr_io); + let stdout_reader: Pin> = Box::pin(stdout_reader); + let stderr_reader: Pin> = Box::pin(stderr_reader); + + // Store the line streams for later polling + self.stdout = Some(stdout_reader.lines()); + self.stderr = Some(stderr_reader.lines()); + + Ok(()) } /// We have this whole thing figured out, but we don't actually use it yet. @@ -1350,10 +1380,122 @@ We checked the folder: {} matches!(&self.stage, BuildStage::Success | BuildStage::Failed) } - pub(crate) async fn open_debugger(&mut self, server: &WebServer) { + pub(crate) async fn open_debugger(&mut self, server: &WebServer) -> Result<()> { let url = match self.build.platform { + // https://stackoverflow.com/questions/53733781/how-do-i-use-lldb-to-debug-c-code-on-android-on-command-line/64997332#64997332 + // https://android.googlesource.com/platform/development/+/refs/heads/main/scripts/gdbclient.py + // run lldbserver on the device and then connect + // + // # TODO: https://code.visualstudio.com/api/references/vscode-api#debug and + // # https://code.visualstudio.com/api/extension-guides/debugger-extension and + // # https://github.com/vadimcn/vscode-lldb/blob/6b775c439992b6615e92f4938ee4e211f1b060cf/extension/pickProcess.ts#L6 + // + // res = { + // "name": "(lldbclient.py) Attach {} (port: {})".format(binary_name.split("/")[-1], port), + // "type": "lldb", + // "request": "custom", + // "relativePathBase": root, + // "sourceMap": { "/b/f/w" : root, '': root, '.': root }, + // "initCommands": ['settings append target.exec-search-paths {}'.format(' '.join(solib_search_path))], + // "targetCreateCommands": ["target create {}".format(binary_name), + // "target modules search-paths add / {}/".format(sysroot)], + // "processCreateCommands": ["gdb-remote {}".format(str(port))] + // } + // + // https://github.com/vadimcn/codelldb/issues/213 + // + // lots of pain to figure this out: + // + // (lldb) image add target/dx/tw6/debug/android/app/app/src/main/jniLibs/arm64-v8a/libdioxusmain.so + // (lldb) settings append target.exec-search-paths target/dx/tw6/debug/android/app/app/src/main/jniLibs/arm64-v8a/libdioxusmain.so + // (lldb) process handle SIGSEGV --pass true --stop false --notify true (otherwise the java threads cause crash) + // + Platform::Android => { + // adb push ./sdk/ndk/29.0.13113456/toolchains/llvm/prebuilt/darwin-x86_64/lib/clang/20/lib/linux/aarch64/lldb-server /tmp + // adb shell "/tmp/lldb-server --server --listen ..." + // "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'connect','port': {}}}", + // format!( + // "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" + // ) + let tools = &self.build.workspace.android_tools()?; + + // get the pid of the app + let pid = Command::new(&tools.adb) + .arg("shell") + .arg("pidof") + .arg(self.build.bundle_identifier()) + .output() + .await + .ok() + .and_then(|output| String::from_utf8(output.stdout).ok()) + .and_then(|s| s.trim().parse::().ok()) + .unwrap(); + + // copy the lldb-server to the device + let lldb_server = tools + .android_tools_dir() + .parent() + .unwrap() + .join("lib") + .join("clang") + .join("20") + .join("lib") + .join("linux") + .join("aarch64") + .join("lldb-server"); + tracing::info!("Copying lldb-server to device: {lldb_server:?}"); + + let res = Command::new(&tools.adb) + .arg("push") + .arg(lldb_server) + .arg("/tmp/lldb-server") + .output() + .await; + + // Forward requests on 10086 to the device + let res = Command::new(&tools.adb) + .arg("forward") + .arg("tcp:10086") + .arg("tcp:10086") + .output() + .await; + + // start the server. when the debug session ends, it dies automatically + Command::new(&tools.adb) + .arg("shell") + .arg(r#"cd /tmp && ./lldb-server g :10086"#) + .kill_on_drop(false) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + let program_path = self.build.main_exe(); + format!( + r#"vscode://vadimcn.vscode-lldb/launch/config?{{ + 'request':'attach', + 'pid': '{pid}', + 'processCreateCommands': [ + 'gdb-remote 10086', + 'target create {program_path}', + 'platform select remote-android', + 'image add {program_path}', + 'settings append target.exec-search-paths {program_path}', + 'process handle SIGSEGV --pass true --stop false --notify true', + 'process attach --pid {pid}', + ] + }}"#, + program_path = program_path.display(), + ) + .lines() + .map(|line| line.trim()) + .join(" ") + } + Platform::Web => { // code --open-url "vscode://DioxusLabs.dioxus/debugger?uri=http://127.0.0.1:8080" + // todo - debugger could open to the *current* page afaik we don't have a way to have that info let address = server.devserver_address(); let base_path = self.build.config.web.app.base_path.clone(); let https = self.build.config.web.https.enabled.unwrap_or_default(); @@ -1364,8 +1506,17 @@ We checked the folder: {} }; format!("vscode://DioxusLabs.dioxus/debugger?uri={protocol}://{address}{base_path}") } - Platform::Ios => return, - Platform::Android => return, + + Platform::Ios => { + let Some(pid) = self.pid else { + tracing::warn!("No process to attach debugger to"); + return Ok(()); + }; + + format!( + "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" + ) + } Platform::MacOS | Platform::Windows @@ -1374,7 +1525,7 @@ We checked the folder: {} | Platform::Liveview => { let Some(Some(pid)) = self.child.as_mut().map(|f| f.id()) else { tracing::warn!("No process to attach debugger to"); - return; + return Ok(()); }; format!( @@ -1384,11 +1535,13 @@ We checked the folder: {} } }; - tracing::info!("Opening debugger: {url}"); + tracing::info!("Opening debugger for [{}]: {url}", self.build.platform); _ = tokio::process::Command::new("code") .arg("--open-url") .arg(url) .spawn(); + + Ok(()) } } diff --git a/packages/cli/src/build/request.rs b/packages/cli/src/build/request.rs index 8ab7bfd622..382c32e3b2 100644 --- a/packages/cli/src/build/request.rs +++ b/packages/cli/src/build/request.rs @@ -1940,6 +1940,12 @@ impl BuildRequest { )); } + // for debuggability, we need to make sure android studio can properly understand our build + // https://stackoverflow.com/questions/68481401/debugging-a-prebuilt-shared-library-in-android-studio + if self.platform == Platform::Android { + cargo_args.push("-Clink-arg=-Wl,--build-id=sha1".to_string()); + } + // Our fancy hot-patching engine needs a lot of customization to work properly. // // These args are mostly intended to be passed when *fat* linking but are generally fine to diff --git a/packages/cli/src/cli/run.rs b/packages/cli/src/cli/run.rs index 1f969c4f55..f0df280db7 100644 --- a/packages/cli/src/cli/run.rs +++ b/packages/cli/src/cli/run.rs @@ -123,6 +123,7 @@ impl RunArgs { break; } + BuilderUpdate::ProcessWaitFailed { .. } => {} } } _ => {} diff --git a/packages/cli/src/serve/output.rs b/packages/cli/src/serve/output.rs index 8ab2c56b98..9d9075c276 100644 --- a/packages/cli/src/serve/output.rs +++ b/packages/cli/src/serve/output.rs @@ -244,16 +244,15 @@ impl Output { self.trace = !self.trace; tracing::info!("Tracing is now {}", if self.trace { "on" } else { "off" }); } + KeyCode::Char('D') => { + return Ok(Some(ServeUpdate::OpenDebugger { + id: BuildId::SERVER, + })); + } KeyCode::Char('d') => { - if key.modifiers.contains(KeyModifiers::SHIFT) { - return Ok(Some(ServeUpdate::OpenDebugger { - id: BuildId::SERVER, - })); - } else { - return Ok(Some(ServeUpdate::OpenDebugger { - id: BuildId::CLIENT, - })); - } + return Ok(Some(ServeUpdate::OpenDebugger { + id: BuildId::CLIENT, + })); } KeyCode::Char('c') => { diff --git a/packages/cli/src/serve/server.rs b/packages/cli/src/serve/server.rs index 114ee9d605..325b52398b 100644 --- a/packages/cli/src/serve/server.rs +++ b/packages/cli/src/serve/server.rs @@ -69,6 +69,7 @@ pub(crate) struct ConnectedWsClient { socket: WebSocket, build_id: Option, aslr_reference: Option, + pid: Option, } impl WebServer { @@ -261,6 +262,7 @@ impl WebServer { BuilderUpdate::StdoutReceived { .. } => {} BuilderUpdate::StderrReceived { .. } => {} BuilderUpdate::ProcessExited { .. } => {} + BuilderUpdate::ProcessWaitFailed { .. } => {} } } @@ -495,6 +497,7 @@ fn build_devserver_router( struct ConnectionQuery { aslr_reference: Option, build_id: Option, + pid: Option, } // Setup websocket endpoint - and pass in the extension layer immediately after @@ -506,7 +509,7 @@ fn build_devserver_router( get( |ws: WebSocketUpgrade, ext: Extension>, query: Query| async move { tracing::debug!("New devtool websocket connection: {:?}", query); - ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: query.aslr_reference, build_id: query.build_id }) }) + ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: query.aslr_reference, build_id: query.build_id, pid: query.pid }) }) }, ), ) @@ -515,7 +518,7 @@ fn build_devserver_router( "/build_status", get( |ws: WebSocketUpgrade, ext: Extension>| async move { - ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: None, build_id: None }) }) + ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: None, build_id: None, pid: None }) }) }, ), ) diff --git a/packages/devtools/src/lib.rs b/packages/devtools/src/lib.rs index 077ed6c588..8e0a22682c 100644 --- a/packages/devtools/src/lib.rs +++ b/packages/devtools/src/lib.rs @@ -79,9 +79,10 @@ pub fn connect_subsecond() { pub fn connect_at(endpoint: String, mut callback: impl FnMut(DevserverMsg) + Send + 'static) { std::thread::spawn(move || { let uri = format!( - "{endpoint}?aslr_reference={}&build_id={}", + "{endpoint}?aslr_reference={}&build_id={}&pid={}", subsecond::__aslr_reference(), - dioxus_cli_config::build_id() + dioxus_cli_config::build_id(), + std::process::id() ); let (mut websocket, _req) = match tungstenite::connect(uri) { From db6deca1793f22f27a2f9d0d7cf35e6cfb0d7f16 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sun, 18 May 2025 12:02:46 +0200 Subject: [PATCH 9/9] clean it up a bit --- packages/cli/src/build/builder.rs | 117 +++++++++++++++--------------- packages/cli/src/serve/runner.rs | 4 +- packages/cli/src/serve/server.rs | 6 +- 3 files changed, 65 insertions(+), 62 deletions(-) diff --git a/packages/cli/src/build/builder.rs b/packages/cli/src/build/builder.rs index 6a8e000569..7e90fcaa2c 100644 --- a/packages/cli/src/build/builder.rs +++ b/packages/cli/src/build/builder.rs @@ -19,7 +19,7 @@ use std::{ use subsecond_types::JumpTable; use tokio::{ io::{AsyncBufRead, AsyncBufReadExt, BufReader, Lines}, - process::{Child, ChildStderr, ChildStdout, Command}, + process::{Child, Command}, task::JoinHandle, }; @@ -795,7 +795,7 @@ impl AppBuilder { let stdout_file = tempfile::tempfile()?; let stderr_file = tempfile::tempfile()?; - let mut child = Command::new("xcrun") + let child = Command::new("xcrun") .arg("simctl") .arg("launch") .arg("booted") @@ -810,7 +810,6 @@ impl AppBuilder { .await?; let pstdout = String::from_utf8_lossy(&child.stdout); - let pstderr = String::from_utf8_lossy(&child.stderr); if child.status.success() { self.pid = pstdout @@ -1382,6 +1381,47 @@ We checked the folder: {} pub(crate) async fn open_debugger(&mut self, server: &WebServer) -> Result<()> { let url = match self.build.platform { + Platform::MacOS + | Platform::Windows + | Platform::Linux + | Platform::Server + | Platform::Liveview => { + let Some(Some(pid)) = self.child.as_mut().map(|f| f.id()) else { + tracing::warn!("No process to attach debugger to"); + return Ok(()); + }; + + format!( + "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", + pid + ) + } + + Platform::Web => { + // code --open-url "vscode://DioxusLabs.dioxus/debugger?uri=http://127.0.0.1:8080" + // todo - debugger could open to the *current* page afaik we don't have a way to have that info + let address = server.devserver_address(); + let base_path = self.build.config.web.app.base_path.clone(); + let https = self.build.config.web.https.enabled.unwrap_or_default(); + let protocol = if https { "https" } else { "http" }; + let base_path = match base_path.as_deref() { + Some(base_path) => format!("/{}", base_path.trim_matches('/')), + None => "".to_owned(), + }; + format!("vscode://DioxusLabs.dioxus/debugger?uri={protocol}://{address}{base_path}") + } + + Platform::Ios => { + let Some(pid) = self.pid else { + tracing::warn!("No process to attach debugger to"); + return Ok(()); + }; + + format!( + "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" + ) + } + // https://stackoverflow.com/questions/53733781/how-do-i-use-lldb-to-debug-c-code-on-android-on-command-line/64997332#64997332 // https://android.googlesource.com/platform/development/+/refs/heads/main/scripts/gdbclient.py // run lldbserver on the device and then connect @@ -1443,9 +1483,10 @@ We checked the folder: {} .join("linux") .join("aarch64") .join("lldb-server"); + tracing::info!("Copying lldb-server to device: {lldb_server:?}"); - let res = Command::new(&tools.adb) + _ = Command::new(&tools.adb) .arg("push") .arg(lldb_server) .arg("/tmp/lldb-server") @@ -1453,85 +1494,47 @@ We checked the folder: {} .await; // Forward requests on 10086 to the device - let res = Command::new(&tools.adb) + _ = Command::new(&tools.adb) .arg("forward") .arg("tcp:10086") .arg("tcp:10086") .output() .await; - // start the server. when the debug session ends, it dies automatically - Command::new(&tools.adb) + // start the server - running it multiple times will make the subsequent ones fail (which is fine) + _ = Command::new(&tools.adb) .arg("shell") - .arg(r#"cd /tmp && ./lldb-server g :10086"#) + .arg(r#"./lldb-server platform --server --listen '*:10086'"#) .kill_on_drop(false) .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn() - .unwrap(); + .spawn(); let program_path = self.build.main_exe(); format!( r#"vscode://vadimcn.vscode-lldb/launch/config?{{ + 'name':'Attach to Android', + 'type':'lldb', 'request':'attach', 'pid': '{pid}', 'processCreateCommands': [ - 'gdb-remote 10086', - 'target create {program_path}', 'platform select remote-android', - 'image add {program_path}', + 'platform connect connect://localhost:10086', + 'settings set target.inherit-env false', + 'settings set target.inline-breakpoint-strategy always', + 'settings set target.process.thread.step-avoid-regexp \"JavaBridge|JDWP|Binder|ReferenceQueueDaemon\"', + 'process handle SIGSEGV --pass true --stop false --notify true"', 'settings append target.exec-search-paths {program_path}', - 'process handle SIGSEGV --pass true --stop false --notify true', - 'process attach --pid {pid}', + 'attach --pid {pid}', + 'continue' ] }}"#, program_path = program_path.display(), ) .lines() .map(|line| line.trim()) - .join(" ") - } - - Platform::Web => { - // code --open-url "vscode://DioxusLabs.dioxus/debugger?uri=http://127.0.0.1:8080" - // todo - debugger could open to the *current* page afaik we don't have a way to have that info - let address = server.devserver_address(); - let base_path = self.build.config.web.app.base_path.clone(); - let https = self.build.config.web.https.enabled.unwrap_or_default(); - let protocol = if https { "https" } else { "http" }; - let base_path = match base_path.as_deref() { - Some(base_path) => format!("/{}", base_path.trim_matches('/')), - None => "".to_owned(), - }; - format!("vscode://DioxusLabs.dioxus/debugger?uri={protocol}://{address}{base_path}") - } - - Platform::Ios => { - let Some(pid) = self.pid else { - tracing::warn!("No process to attach debugger to"); - return Ok(()); - }; - - format!( - "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{pid}}}" - ) - } - - Platform::MacOS - | Platform::Windows - | Platform::Linux - | Platform::Server - | Platform::Liveview => { - let Some(Some(pid)) = self.child.as_mut().map(|f| f.id()) else { - tracing::warn!("No process to attach debugger to"); - return Ok(()); - }; - - format!( - "vscode://vadimcn.vscode-lldb/launch/config?{{'request':'attach','pid':{}}}", - pid - ) + .join("") } }; diff --git a/packages/cli/src/serve/runner.rs b/packages/cli/src/serve/runner.rs index 82bd00c272..5dfe630f4b 100644 --- a/packages/cli/src/serve/runner.rs +++ b/packages/cli/src/serve/runner.rs @@ -975,11 +975,11 @@ impl AppServer { pub(crate) async fn open_debugger(&mut self, dev: &WebServer, build: BuildId) { match build { BuildId::CLIENT => { - self.client.open_debugger(dev).await; + _ = self.client.open_debugger(dev).await; } BuildId::SERVER => { if let Some(server) = self.server.as_mut() { - server.open_debugger(dev).await; + _ = server.open_debugger(dev).await; } } _ => {} diff --git a/packages/cli/src/serve/server.rs b/packages/cli/src/serve/server.rs index 325b52398b..d26ea5a431 100644 --- a/packages/cli/src/serve/server.rs +++ b/packages/cli/src/serve/server.rs @@ -69,7 +69,7 @@ pub(crate) struct ConnectedWsClient { socket: WebSocket, build_id: Option, aslr_reference: Option, - pid: Option, + _pid: Option, } impl WebServer { @@ -509,7 +509,7 @@ fn build_devserver_router( get( |ws: WebSocketUpgrade, ext: Extension>, query: Query| async move { tracing::debug!("New devtool websocket connection: {:?}", query); - ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: query.aslr_reference, build_id: query.build_id, pid: query.pid }) }) + ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: query.aslr_reference, build_id: query.build_id, _pid: query.pid }) }) }, ), ) @@ -518,7 +518,7 @@ fn build_devserver_router( "/build_status", get( |ws: WebSocketUpgrade, ext: Extension>| async move { - ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: None, build_id: None, pid: None }) }) + ws.on_upgrade(move |socket| async move { _ = ext.0.unbounded_send(ConnectedWsClient { socket, aslr_reference: None, build_id: None, _pid: None }) }) }, ), )