mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Show sleeping proc queue as threads in VSC
This commit is contained in:
parent
1da4eb3246
commit
1fc5056b40
4 changed files with 107 additions and 3 deletions
|
|
@ -113,6 +113,28 @@ pub struct ErrorResponseBody {
|
|||
// ----------------------------------------------------------------------------
|
||||
// Events
|
||||
|
||||
/// The event indicates that the execution of the debuggee has continued.
|
||||
///
|
||||
/// Please note: a debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. ‘launch’ or ‘continue’.
|
||||
///
|
||||
/// It is only necessary to send a ‘continued’ event if there was no previous request that implied this.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ContinuedEvent {
|
||||
/**
|
||||
* The thread which was continued.
|
||||
*/
|
||||
pub threadId: i64,
|
||||
|
||||
/**
|
||||
* If 'allThreadsContinued' is true, a debug adapter can announce that all threads have continued.
|
||||
*/
|
||||
pub allThreadsContinued: Option<bool>,
|
||||
}
|
||||
|
||||
impl Event for ContinuedEvent {
|
||||
const EVENT: &'static str = "continued";
|
||||
}
|
||||
|
||||
/// The event indicates that the debuggee has exited and returns its exit code.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ExitedEvent {
|
||||
|
|
@ -141,6 +163,30 @@ impl Event for TerminatedEvent {
|
|||
const EVENT: &'static str = "terminated";
|
||||
}
|
||||
|
||||
/// The event indicates that a thread has started or exited.
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ThreadEvent {
|
||||
/**
|
||||
* The reason for the event.
|
||||
* Values: 'started', 'exited', etc.
|
||||
*/
|
||||
pub reason: String,
|
||||
|
||||
/**
|
||||
* The identifier of the thread.
|
||||
*/
|
||||
pub threadId: i64,
|
||||
}
|
||||
|
||||
impl ThreadEvent {
|
||||
pub const REASON_STARTED: &'static str = "started";
|
||||
pub const REASON_EXITED: &'static str = "exited";
|
||||
}
|
||||
|
||||
impl Event for ThreadEvent {
|
||||
const EVENT: &'static str = "thread";
|
||||
}
|
||||
|
||||
/// The event indicates that the target has produced some output.
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
pub struct OutputEvent {
|
||||
|
|
|
|||
|
|
@ -480,7 +480,11 @@ handle_extools! {
|
|||
|
||||
on CallStack(&mut self, stack) {
|
||||
let mut map = self.threads.lock().unwrap();
|
||||
map.entry(0).or_default().call_stack = stack.0;
|
||||
map.clear();
|
||||
map.entry(0).or_default().call_stack = stack.current;
|
||||
for (i, list) in stack.suspended.into_iter().enumerate() {
|
||||
map.entry((i + 1) as i64).or_default().call_stack = list;
|
||||
}
|
||||
}
|
||||
|
||||
on DisassembledProc(&mut self, disasm) {
|
||||
|
|
|
|||
|
|
@ -436,7 +436,10 @@ impl Response for BreakpointHit {
|
|||
|
||||
// #define MESSAGE_CALL_STACK "call stack" //Content is a vector of proc paths
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct CallStack(pub Vec<StackFrame>);
|
||||
pub struct CallStack {
|
||||
pub current: Vec<StackFrame>,
|
||||
pub suspended: Vec<Vec<StackFrame>>,
|
||||
}
|
||||
|
||||
impl Response for CallStack {
|
||||
const TYPE: &'static str = "call stack";
|
||||
|
|
|
|||
|
|
@ -274,6 +274,36 @@ impl Debugger {
|
|||
fn issue_event<E: Event>(&mut self, event: E) {
|
||||
self.seq.issue_event(event);
|
||||
}
|
||||
|
||||
fn notify_continue(&mut self) {
|
||||
// Called when a Step occurs so we can tell VSC that actually you can't
|
||||
// do that on a per-thread basis in DM.
|
||||
self.cull_thread_list();
|
||||
self.issue_event(dap_types::ContinuedEvent {
|
||||
threadId: 0,
|
||||
allThreadsContinued: Some(true),
|
||||
});
|
||||
}
|
||||
|
||||
fn cull_thread_list(&mut self) {
|
||||
// Cull threads other than the main thread so that VSC goes back to
|
||||
// acting like the application is single-threaded, rather than showing
|
||||
// the last-known sleeping stacks every time.
|
||||
|
||||
// An alternative would be to send these in real-time when sleeping
|
||||
// threads enter or exit existence.
|
||||
|
||||
let keys: Vec<_> = {
|
||||
guard!(let Ok(extools) = self.extools.get() else { return });
|
||||
extools.get_all_threads().keys().cloned().filter(|&k| k != 0).collect()
|
||||
};
|
||||
for k in keys {
|
||||
self.issue_event(dap_types::ThreadEvent {
|
||||
reason: dap_types::ThreadEvent::REASON_EXITED.to_owned(),
|
||||
threadId: k,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const EXCEPTION_FILTER_RUNTIMES: &str = "runtimes";
|
||||
|
|
@ -373,8 +403,25 @@ handle_request! {
|
|||
}
|
||||
|
||||
on Threads(&mut self, ()) {
|
||||
let mut threads = Vec::new();
|
||||
|
||||
let extools = self.extools.get()?;
|
||||
for (&k, v) in extools.get_all_threads().iter() {
|
||||
threads.push(Thread {
|
||||
id: k,
|
||||
name: v.call_stack.last().unwrap().proc.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
if threads.is_empty() {
|
||||
threads.push(Thread {
|
||||
id: 0,
|
||||
name: "Main".to_owned(),
|
||||
});
|
||||
}
|
||||
|
||||
ThreadsResponse {
|
||||
threads: vec![Thread { id: 0, name: "Main".to_owned() }]
|
||||
threads,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -757,6 +804,7 @@ handle_request! {
|
|||
}
|
||||
|
||||
on Continue(&mut self, _params) {
|
||||
self.cull_thread_list();
|
||||
let extools = self.extools.get()?;
|
||||
extools.continue_execution();
|
||||
ContinueResponse {
|
||||
|
|
@ -765,16 +813,19 @@ handle_request! {
|
|||
}
|
||||
|
||||
on StepIn(&mut self, params) {
|
||||
self.notify_continue();
|
||||
let extools = self.extools.get()?;
|
||||
extools.step_in(params.threadId);
|
||||
}
|
||||
|
||||
on Next(&mut self, params) {
|
||||
self.notify_continue();
|
||||
let extools = self.extools.get()?;
|
||||
extools.step_over(params.threadId);
|
||||
}
|
||||
|
||||
on StepOut(&mut self, params) {
|
||||
self.notify_continue();
|
||||
let extools = self.extools.get()?;
|
||||
extools.step_out(params.threadId);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue