debugger support for dx (#3814)

* add vscode debugger for apps

* todo: need to disconnect when rebuilding

* update debugger

* add uri handler to remote launch the debugger

* attach

* dont panic

* fixed it - hung processes are not errors

* wip: android debugger

* clean it up a bit

* revert ios stdout/stderr

* wire up pid from ios

* use target family instead of target_arch

* fix android

* bring back softkill

* typo
This commit is contained in:
Jonathan Kelley authored and GitHub committed 2025-05-24 23:31:42 +01:00
1 parent eb15b42ab1
commit b2bd1f48d4
13 files changed
+305 -41

No files matched your search

+15 -2
View File
@@ -90,7 +90,11 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) ->
// Run the server in the background
// Waiting for updates here lets us tap into when clients are added/removed
ServeUpdate::NewConnection { id, aslr_reference } => {
ServeUpdate::NewConnection {
id,
aslr_reference,
pid,
} => {
devserver
.send_hotreload(builder.applied_hot_reload_changes(BuildId::CLIENT))
.await;
@@ -101,7 +105,7 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) ->
.await;
}
builder.client_connected(id, aslr_reference).await;
builder.client_connected(id, aslr_reference, pid).await;
}
// Received a message from the devtools server - currently we only use this for
@@ -173,6 +177,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 being debugged?: {err}"
);
}
}
}
@@ -202,6 +211,10 @@ pub(crate) async fn serve_all(args: ServeArgs, tracer: &mut TraceController) ->
)
}
ServeUpdate::OpenDebugger { id } => {
builder.open_debugger(&devserver, id).await;
}
ServeUpdate::Exit { error } => {
_ = builder.shutdown().await;
_ = devserver.shutdown().await;
+11 -1
View File
@@ -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 cargo_metadata::diagnostic::Diagnostic;
use crossterm::{
@@ -245,6 +245,16 @@ 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') => {
return Ok(Some(ServeUpdate::OpenDebugger {
id: BuildId::CLIENT,
}));
}
KeyCode::Char('c') => {
stdout()
+22
View File
@@ -692,6 +692,7 @@ impl AppServer {
&mut self,
build_id: BuildId,
aslr_reference: Option<u64>,
pid: Option<u32>,
) {
match build_id {
BuildId::CLIENT => {
@@ -701,6 +702,9 @@ impl AppServer {
if let Some(aslr_reference) = aslr_reference {
self.client.aslr_reference = Some(aslr_reference);
}
if let Some(pid) = pid {
self.client.pid = Some(pid);
}
}
}
BuildId::SERVER => {
@@ -970,6 +974,24 @@ impl AppServer {
server.compiled_crates as f64 / server.expected_crates as f64
}
pub(crate) async fn open_debugger(&mut self, dev: &WebServer, build: BuildId) {
if self.use_hotpatch_engine {
tracing::warn!("Debugging symbols might not work properly with hotpatching enabled. Consider disabling hotpatching for debugging.");
}
match build {
BuildId::CLIENT => {
_ = self.client.open_debugger(dev).await;
}
BuildId::SERVER => {
if let Some(server) = self.server.as_mut() {
_ = server.open_debugger(dev).await;
}
}
_ => {}
}
}
}
/// Bind a listener to any point and return it
+7 -3
View File
@@ -69,6 +69,7 @@ pub(crate) struct ConnectedWsClient {
socket: WebSocket,
build_id: Option<BuildId>,
aslr_reference: Option<u64>,
pid: Option<u32>,
}
impl WebServer {
@@ -146,12 +147,13 @@ impl WebServer {
new_hot_reload_socket = &mut new_hot_reload_socket => {
if let Some(new_socket) = new_hot_reload_socket {
let aslr_reference = new_socket.aslr_reference;
let pid = new_socket.pid;
let id = new_socket.build_id.unwrap_or(BuildId::CLIENT);
drop(new_message);
self.hot_reload_sockets.push(new_socket);
return ServeUpdate::NewConnection { aslr_reference, id };
return ServeUpdate::NewConnection { aslr_reference, id, pid };
} else {
panic!("Could not receive a socket - the devtools could not boot - the port is likely already in use");
}
@@ -261,6 +263,7 @@ impl WebServer {
BuilderUpdate::StdoutReceived { .. } => {}
BuilderUpdate::StderrReceived { .. } => {}
BuilderUpdate::ProcessExited { .. } => {}
BuilderUpdate::ProcessWaitFailed { .. } => {}
}
}
@@ -495,6 +498,7 @@ fn build_devserver_router(
struct ConnectionQuery {
aslr_reference: Option<u64>,
build_id: Option<BuildId>,
pid: Option<u32>,
}
// Setup websocket endpoint - and pass in the extension layer immediately after
@@ -506,7 +510,7 @@ fn build_devserver_router(
get(
|ws: WebSocketUpgrade, ext: Extension<UnboundedSender<ConnectedWsClient>>, query: Query<ConnectionQuery>| 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 +519,7 @@ fn build_devserver_router(
"/build_status",
get(
|ws: WebSocketUpgrade, ext: Extension<UnboundedSender<ConnectedWsClient>>| 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 }) })
},
),
)
+5
View File
@@ -10,6 +10,7 @@ pub(crate) enum ServeUpdate {
NewConnection {
id: BuildId,
aslr_reference: Option<u64>,
pid: Option<u32>,
},
WsMessage {
platform: Platform,
@@ -32,6 +33,10 @@ pub(crate) enum ServeUpdate {
ToggleShouldRebuild,
OpenDebugger {
id: BuildId,
},
Redraw,
TracingLog {