debugger: Fix phantom JavaScript frames (#32469)
JavaScript debugger is using a phantom stack frame to delineate await
points; that frame reuses a frame ID of 0, which collides with other
frames returned from that adapter.
934075df8c/src/adapter/stackTrace.ts (L287)
The bug has since been fixed in
https://github.com/microsoft/vscode-js-debug/issues/2234, but we'll need
to wait for a new release of node debugger for that to make a
difference. Until then..
Release Notes:
- Fixed a bug with JavaScript debugging which led to stack trace list
containing excessive amount of `await` entries.
---------
Co-authored-by: Conrad Irwin <conrad@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
parent
71d5c57119
commit
295db79c47
1 changed files with 16 additions and 14 deletions
|
@ -13,7 +13,7 @@ use super::dap_command::{
|
||||||
};
|
};
|
||||||
use super::dap_store::DapStore;
|
use super::dap_store::DapStore;
|
||||||
use anyhow::{Context as _, Result, anyhow};
|
use anyhow::{Context as _, Result, anyhow};
|
||||||
use collections::{HashMap, HashSet, IndexMap, IndexSet};
|
use collections::{HashMap, HashSet, IndexMap};
|
||||||
use dap::adapters::{DebugAdapterBinary, DebugAdapterName};
|
use dap::adapters::{DebugAdapterBinary, DebugAdapterName};
|
||||||
use dap::messages::Response;
|
use dap::messages::Response;
|
||||||
use dap::requests::{Request, RunInTerminal, StartDebugging};
|
use dap::requests::{Request, RunInTerminal, StartDebugging};
|
||||||
|
@ -25,7 +25,7 @@ use dap::{
|
||||||
};
|
};
|
||||||
use dap::{
|
use dap::{
|
||||||
ExceptionBreakpointsFilter, ExceptionFilterOptions, OutputEvent, OutputEventCategory,
|
ExceptionBreakpointsFilter, ExceptionFilterOptions, OutputEvent, OutputEventCategory,
|
||||||
RunInTerminalRequestArguments, StartDebuggingRequestArguments,
|
RunInTerminalRequestArguments, StackFramePresentationHint, StartDebuggingRequestArguments,
|
||||||
};
|
};
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
use futures::channel::{mpsc, oneshot};
|
use futures::channel::{mpsc, oneshot};
|
||||||
|
@ -106,7 +106,7 @@ impl ThreadStatus {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
dap: dap::Thread,
|
dap: dap::Thread,
|
||||||
stack_frame_ids: IndexSet<StackFrameId>,
|
stack_frames: Vec<StackFrame>,
|
||||||
_has_stopped: bool,
|
_has_stopped: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ impl From<dap::Thread> for Thread {
|
||||||
fn from(dap: dap::Thread) -> Self {
|
fn from(dap: dap::Thread) -> Self {
|
||||||
Self {
|
Self {
|
||||||
dap,
|
dap,
|
||||||
stack_frame_ids: Default::default(),
|
stack_frames: Default::default(),
|
||||||
_has_stopped: false,
|
_has_stopped: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1948,8 +1948,8 @@ impl Session {
|
||||||
let stack_frames = stack_frames.log_err()?;
|
let stack_frames = stack_frames.log_err()?;
|
||||||
|
|
||||||
let entry = this.threads.entry(thread_id).and_modify(|thread| {
|
let entry = this.threads.entry(thread_id).and_modify(|thread| {
|
||||||
thread.stack_frame_ids =
|
thread.stack_frames =
|
||||||
stack_frames.iter().map(|frame| frame.id).collect();
|
stack_frames.iter().cloned().map(StackFrame::from).collect();
|
||||||
});
|
});
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
matches!(entry, indexmap::map::Entry::Occupied(_)),
|
matches!(entry, indexmap::map::Entry::Occupied(_)),
|
||||||
|
@ -1959,6 +1959,15 @@ impl Session {
|
||||||
this.stack_frames.extend(
|
this.stack_frames.extend(
|
||||||
stack_frames
|
stack_frames
|
||||||
.iter()
|
.iter()
|
||||||
|
.filter(|frame| {
|
||||||
|
// Workaround for JavaScript debug adapter sending out "fake" stack frames for delineating await points. This is fine,
|
||||||
|
// except that they always use an id of 0 for it, which collides with other (valid) stack frames.
|
||||||
|
!(frame.id == 0
|
||||||
|
&& frame.line == 0
|
||||||
|
&& frame.column == 0
|
||||||
|
&& frame.presentation_hint
|
||||||
|
== Some(StackFramePresentationHint::Label))
|
||||||
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|frame| (frame.id, StackFrame::from(frame))),
|
.map(|frame| (frame.id, StackFrame::from(frame))),
|
||||||
);
|
);
|
||||||
|
@ -1976,14 +1985,7 @@ impl Session {
|
||||||
|
|
||||||
self.threads
|
self.threads
|
||||||
.get(&thread_id)
|
.get(&thread_id)
|
||||||
.map(|thread| {
|
.map(|thread| thread.stack_frames.clone())
|
||||||
thread
|
|
||||||
.stack_frame_ids
|
|
||||||
.iter()
|
|
||||||
.filter_map(|id| self.stack_frames.get(id))
|
|
||||||
.cloned()
|
|
||||||
.collect()
|
|
||||||
})
|
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue