Skip to content

Commit 8fd02d8

Browse files
committed
Fixed passing of events. Now it properly shows two stack traces in subprocesses
Still some polishing is needed since it is not very stable
1 parent 96a1909 commit 8fd02d8

2 files changed

Lines changed: 166 additions & 19 deletions

File tree

src/mibase.ts

Lines changed: 102 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ export class MI2DebugSession extends DebugSession {
4646
public miDebugger: MI2;
4747
protected commandServer: net.Server;
4848
protected serverPath: string;
49+
protected sessionPid: string | undefined = undefined;
4950
protected threadGroupPids = new Map<string, string>();
50-
protected threadToPid = new Map<number, string>();
51+
public threadToPid = new Map<number, string>();
52+
protected mi2Inferiors = new Array();
5153
protected inferiorServers = new Array();
5254

5355
public constructor(debuggerLinesStartAt1: boolean, isServer: boolean = false) {
@@ -144,30 +146,72 @@ export class MI2DebugSession extends DebugSession {
144146
}
145147

146148
protected handleBreakpoint(info: MINode) {
149+
let threadId = info.record("thread-id");
150+
151+
this.miDebugger.log("stdout", `Got theadid ${threadId}`);
152+
153+
let threadPid = this.threadToPid.get(parseInt(info.record("thread-id"), 10));
154+
147155
const event = new StoppedEvent("breakpoint", parseInt(info.record("thread-id")));
148156
(event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info.record("stopped-threads") === "all";
149-
this.sendEvent(event);
157+
158+
this.miDebugger.log("stdout", `Handling breakpoint for threadPid == this.sessionPid (${threadPid} == ${this.sessionPid})`)
159+
160+
if (threadPid == this.sessionPid) {
161+
this.sendEvent(event);
162+
} else {
163+
this.mi2Inferiors.forEach(inferior => {
164+
if (threadPid == inferior.sessionPid) inferior.sendEvent(event)
165+
});
166+
}
150167
}
151168

152169
protected handleBreak(info?: MINode) {
170+
let threadPid = this.threadToPid.get(parseInt(info.record("thread-id"), 10));
171+
153172
const event = new StoppedEvent("step", info ? parseInt(info.record("thread-id")) : 1);
154173
(event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info ? info.record("stopped-threads") === "all" : true;
155-
this.sendEvent(event);
174+
175+
if (threadPid == this.sessionPid) {
176+
this.sendEvent(event);
177+
} else {
178+
this.mi2Inferiors.forEach(inferior => {
179+
if (threadPid == inferior.sessionPid) inferior.sendEvent(event)
180+
});
181+
}
156182
}
157183

158184
protected handlePause(info: MINode) {
185+
let threadPid = this.threadToPid.get(parseInt(info.record("thread-id"), 10));
186+
159187
const event = new StoppedEvent("user request", parseInt(info.record("thread-id")));
160188
(event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info.record("stopped-threads") === "all";
161-
this.sendEvent(event);
189+
190+
if (threadPid == this.sessionPid) {
191+
this.sendEvent(event);
192+
} else {
193+
this.mi2Inferiors.forEach(inferior => {
194+
if (threadPid == inferior.sessionPid) inferior.sendEvent(event)
195+
});
196+
}
162197
}
163198

164199
protected stopEvent(info: MINode) {
165200
if (!this.started)
166201
this.crashed = true;
167202
if (!this.quit) {
203+
let threadPid = this.threadToPid.get(parseInt(info.record("thread-id"), 10));
204+
168205
const event = new StoppedEvent("exception", parseInt(info.record("thread-id")));
169206
(event as DebugProtocol.StoppedEvent).body.allThreadsStopped = info.record("stopped-threads") === "all";
170-
this.sendEvent(event);
207+
208+
if (threadPid == this.sessionPid) {
209+
this.sendEvent(event);
210+
} else {
211+
this.mi2Inferiors.forEach(inferior => {
212+
if (threadPid == inferior.sessionPid) inferior.sendEvent(event)
213+
});
214+
}
171215
}
172216
}
173217

@@ -177,15 +221,28 @@ export class MI2DebugSession extends DebugSession {
177221
let threadPid = this.threadGroupPids.get(info.record("group-id"));
178222
this.threadToPid.set(threadId, threadPid);
179223

180-
this.sendEvent(new ThreadEvent("started", threadId));
224+
if (threadPid == this.sessionPid) {
225+
this.sendEvent(new ThreadEvent("started", threadId));
226+
} else {
227+
this.mi2Inferiors.forEach(inferior => {
228+
if (threadPid == inferior.sessionPid) inferior.sendEvent(new ThreadEvent("started", threadId));
229+
});
230+
}
181231
}
182232

183233
protected threadExitedEvent(info: MINode) {
184234
let threadId = parseInt(info.record("id"), 10);
185235

236+
let threadPid = this.threadGroupPids.get(info.record("group-id"));
186237
this.threadToPid.delete(info.record("group-id"));
187238

188-
this.sendEvent(new ThreadEvent("exited", threadId));
239+
if (threadPid == this.sessionPid) {
240+
this.sendEvent(new ThreadEvent("exited", threadId));
241+
} else {
242+
this.mi2Inferiors.forEach(inferior => {
243+
if (threadPid == inferior.sessionPid) inferior.sendEvent(new ThreadEvent("exited", threadId));
244+
});
245+
}
189246
}
190247

191248
private openInferiorDebugServer(superiorServer: MI2DebugSession) {
@@ -205,6 +262,8 @@ export class MI2DebugSession extends DebugSession {
205262
const session = new MI2InferiorSession(superiorServer);
206263
session.setRunAsServer(true);
207264
session.start(socket, socket);
265+
266+
this.mi2Inferiors.push(session);
208267
}).listen(port);
209268

210269
this.inferiorServers.push(server);
@@ -213,7 +272,12 @@ export class MI2DebugSession extends DebugSession {
213272
}
214273

215274
protected threadGroupStartedEvent(info: MINode) {
216-
let pid = parseInt(info.record("pid"), 10);
275+
let pid = info.record("pid");
276+
277+
if (typeof this.sessionPid === "undefined") {
278+
this.miDebugger.log("stdout", `Updated this.sessionPid to ${pid}`)
279+
this.sessionPid = pid;
280+
}
217281

218282
this.miDebugger.log("stdout", "threadGroupStartedEvent")
219283
this.miDebugger.log("stdout", pid.toString())
@@ -240,6 +304,17 @@ export class MI2DebugSession extends DebugSession {
240304
}
241305

242306
protected threadGroupExitedEvent(info: MINode) {
307+
let pid = this.threadGroupPids.get(info.record("id"));
308+
309+
if (pid == this.sessionPid) {
310+
this.miDebugger.log("stdout", "this.sesionPid = undefind");
311+
// Session has no thread group anymore. Next started thread group will be debugged by this session
312+
this.sessionPid = undefined;
313+
}
314+
315+
this.miDebugger.log("stdout", "threadGroupExitedEvent");
316+
this.miDebugger.log("stdout", pid);
317+
243318
this.threadGroupPids.delete(info.record("id"));
244319
}
245320

@@ -350,6 +425,8 @@ export class MI2DebugSession extends DebugSession {
350425
}
351426

352427
public override threadsRequest(response: DebugProtocol.ThreadsResponse): void {
428+
this.miDebugger.log("stdout", `Received superior thread request for ${this.sessionPid}`);
429+
353430
if (!this.miDebugger) {
354431
this.sendResponse(response);
355432
return;
@@ -361,10 +438,11 @@ export class MI2DebugSession extends DebugSession {
361438
for (const thread of threads) {
362439
const threadName = thread.name || thread.targetId || "<unnamed>";
363440

364-
if (this.threadGroupPids.size > 1) {
365-
let pid = this.threadToPid.get(thread.id);
366-
response.body.threads.push(new Thread(thread.id, `(${pid}) ${thread.id}:${threadName}`));
367-
} else {
441+
let pid = this.threadToPid.get(thread.id);
442+
443+
this.miDebugger.log("stdout", `pid == this.sessionPid (${pid} == ${this.sessionPid})`)
444+
445+
if (pid == this.sessionPid) {
368446
response.body.threads.push(new Thread(thread.id, `${thread.id}:${threadName}`));
369447
}
370448
}
@@ -386,7 +464,9 @@ export class MI2DebugSession extends DebugSession {
386464
return [frameId & 0xffff, frameId >> 16];
387465
}
388466

389-
public override stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments): void {
467+
public inferiorStackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments,
468+
cb_good: (res: DebugProtocol.StackTraceResponse) => any,
469+
cb_bad: (res: DebugProtocol.StackTraceResponse, codeOrMessage: number, err: string) => any) {
390470
this.miDebugger.getStack(args.startFrame, args.levels, args.threadId).then(stack => {
391471
const ret: StackFrame[] = [];
392472
stack.forEach(element => {
@@ -414,12 +494,19 @@ export class MI2DebugSession extends DebugSession {
414494
response.body = {
415495
stackFrames: ret
416496
};
417-
this.sendResponse(response);
497+
cb_good(response);
418498
}, err => {
419-
this.sendErrorResponse(response, 12, `Failed to get Stack Trace: ${err.toString()}`);
499+
cb_bad(response, 12, `Failed to get Stack Trace: ${err.toString()}`);
420500
});
421501
}
422502

503+
public override stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments): void {
504+
this.inferiorStackTraceRequest(response, args,
505+
(r: DebugProtocol.StackTraceResponse) => this.sendResponse(r),
506+
(r: DebugProtocol.StackTraceResponse, c: number, e: string) => this.sendErrorResponse(r, c, e)
507+
)
508+
}
509+
423510
public override configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse, args: DebugProtocol.ConfigurationDoneArguments): void {
424511
const promises: Thenable<any>[] = [];
425512
let entryPoint: string | undefined = undefined;

src/miinferior.ts

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { MI2DebugSession } from './mibase';
22
import { DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, OutputEvent, Thread, StackFrame, Scope, Source, Handles } from 'vscode-debugadapter';
33
import { DebugProtocol } from 'vscode-debugprotocol';
4+
import { MIError } from './backend/backend';
5+
import { setFlagsFromString } from 'v8';
46

57
export interface AttachRequestArguments extends DebugProtocol.AttachRequestArguments {
6-
parentSession: MI2DebugSession | DebugSession
8+
parentSession: MI2DebugSession | DebugSession,
9+
target: string
710
}
811

912
export class MI2InferiorSession extends DebugSession {
1013
superiorSession: MI2DebugSession;
14+
sessionPid: string | undefined;
1115

1216
constructor(superiorSession: MI2DebugSession) {
1317
super(false, true);
@@ -16,6 +20,7 @@ export class MI2InferiorSession extends DebugSession {
1620
}
1721

1822
protected override initializeRequest(response: DebugProtocol.InitializeResponse, args: DebugProtocol.InitializeRequestArguments): void {
23+
this.superiorSession.miDebugger.log("stdout", `intiialize request via inferior ${this.sessionPid}`);
1924
// Same capabilities as GDBDebugSession
2025
response.body.supportsGotoTargetsRequest = true;
2126
response.body.supportsHitConditionalBreakpoints = true;
@@ -30,86 +35,141 @@ export class MI2InferiorSession extends DebugSession {
3035
}
3136

3237
protected override attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments): void {
38+
this.superiorSession.miDebugger.log("stdout", `attach request via inferior ${this.sessionPid}`);
3339
// Attached to server
3440
const pargs = JSON.stringify(args);
3541

42+
this.sessionPid = args.target;
43+
3644
this.superiorSession.miDebugger.log("stdout", "Received attach request!");
37-
this.superiorSession.miDebugger.log("stdout", pargs);
45+
this.superiorSession.miDebugger.log("stdout", this.sessionPid);
3846
}
3947

4048
protected override disconnectRequest(response: DebugProtocol.DisconnectResponse, args: DebugProtocol.DisconnectArguments): void {
49+
this.superiorSession.miDebugger.log("stdout", `disconnect request via inferior ${this.sessionPid}`);
4150
this.superiorSession.disconnectRequest(response, args);
4251
}
4352

4453
protected override async setVariableRequest(response: DebugProtocol.SetVariableResponse, args: DebugProtocol.SetVariableArguments): Promise<void> {
54+
this.superiorSession.miDebugger.log("stdout", `set variables request via inferior ${this.sessionPid}`);
4555
this.superiorSession.setVariableRequest(response, args);
4656
}
4757

4858
protected override setFunctionBreakPointsRequest(response: DebugProtocol.SetFunctionBreakpointsResponse, args: DebugProtocol.SetFunctionBreakpointsArguments): void {
59+
this.superiorSession.miDebugger.log("stdout", `set function breakpoints request via inferior ${this.sessionPid}`);
4960
this.superiorSession.setFunctionBreakPointsRequest(response, args);
5061
}
5162

5263
protected override setBreakPointsRequest(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): void {
64+
this.superiorSession.miDebugger.log("stdout", `set breakpoints request via inferior ${this.sessionPid}`);
5365
this.superiorSession.setBreakPointsRequest(response, args);
5466
}
5567

5668
protected override threadsRequest(response: DebugProtocol.ThreadsResponse): void {
57-
this.superiorSession.threadsRequest(response);
69+
this.superiorSession.miDebugger.log("stdout", `Received inferior thread request for ${this.sessionPid}`);
70+
71+
if (!this.superiorSession.miDebugger) {
72+
this.sendResponse(response);
73+
return;
74+
}
75+
this.superiorSession.miDebugger.getThreads().then(threads => {
76+
response.body = {
77+
threads: []
78+
};
79+
for (const thread of threads) {
80+
const threadName = thread.name || thread.targetId || "<unnamed>";
81+
82+
83+
let pid = this.superiorSession.threadToPid.get(thread.id);
84+
85+
86+
if (pid == this.sessionPid) {
87+
this.superiorSession.miDebugger.log("stdout", `Found thead via inferior ${threadName}`)
88+
this.superiorSession.miDebugger.log("stdout", `pid == this.sessionPid (${pid} == ${this.sessionPid})`)
89+
response.body.threads.push(new Thread(thread.id, `${thread.id}:${threadName}`));
90+
}
91+
}
92+
this.sendResponse(response);
93+
}).catch((error: MIError) => {
94+
if (error.message === 'Selected thread is running.') {
95+
this.sendResponse(response);
96+
return;
97+
}
98+
this.sendErrorResponse(response, 17, `Could not get threads: ${error}`);
99+
});
58100
}
59101

60102
protected override stackTraceRequest(response: DebugProtocol.StackTraceResponse, args: DebugProtocol.StackTraceArguments): void {
61-
this.superiorSession.stackTraceRequest(response, args);
103+
this.superiorSession.miDebugger.log("stdout", `Stack trace request via inferior ${this.sessionPid}`);
104+
this.superiorSession.inferiorStackTraceRequest(response, args,
105+
(r: DebugProtocol.StackTraceResponse) => this.sendResponse(r),
106+
(r: DebugProtocol.StackTraceResponse, c: number, e: string) => this.sendErrorResponse(r, c, e)
107+
)
108+
this.superiorSession.miDebugger.log("stdout", `Stack trace request via inferior ${this.sessionPid} completed`);
62109
}
63110

64111
protected override configurationDoneRequest(response: DebugProtocol.ConfigurationDoneResponse, args: DebugProtocol.ConfigurationDoneArguments): void {
112+
this.superiorSession.miDebugger.log("stdout", `configuration done request via inferior ${this.sessionPid}`);
65113
this.superiorSession.configurationDoneRequest(response, args);
66114
}
67115

68116
protected override scopesRequest(response: DebugProtocol.ScopesResponse, args: DebugProtocol.ScopesArguments): void {
117+
this.superiorSession.miDebugger.log("stdout", `scopes request via inferior ${this.sessionPid}`);
69118
this.superiorSession.scopesRequest(response, args);
70119
}
71120

72121
protected override async variablesRequest(response: DebugProtocol.VariablesResponse, args: DebugProtocol.VariablesArguments): Promise<void> {
122+
this.superiorSession.miDebugger.log("stdout", `variables request via inferior ${this.sessionPid}`);
73123
this.superiorSession.variablesRequest(response, args);
74124
}
75125

76126
protected override pauseRequest(response: DebugProtocol.PauseResponse, args: DebugProtocol.PauseArguments): void {
127+
this.superiorSession.miDebugger.log("stdout", `pause request via inferior ${this.sessionPid}`);
77128
this.superiorSession.pauseRequest(response, args);
78129
}
79130

80131
protected override reverseContinueRequest(response: DebugProtocol.ReverseContinueResponse, args: DebugProtocol.ReverseContinueArguments): void {
132+
this.superiorSession.miDebugger.log("stdout", `reverse continue request via inferior ${this.sessionPid}`);
81133
this.superiorSession.reverseContinueRequest(response, args);
82134
}
83135

84136
protected override continueRequest(response: DebugProtocol.ContinueResponse, args: DebugProtocol.ContinueArguments): void {
137+
this.superiorSession.miDebugger.log("stdout", `continue request via inferior ${this.sessionPid}`);
85138
this.superiorSession.continueRequest(response, args);
86139
}
87140

88141
protected override stepBackRequest(response: DebugProtocol.StepBackResponse, args: DebugProtocol.StepBackArguments): void {
142+
this.superiorSession.miDebugger.log("stdout", `step back request via inferior ${this.sessionPid}`);
89143
this.superiorSession.stepBackRequest(response, args);
90144
}
91145

92146
protected override stepInRequest(response: DebugProtocol.StepInResponse, args: DebugProtocol.StepInArguments): void {
147+
this.superiorSession.miDebugger.log("stdout", `step in request via inferior ${this.sessionPid}`);
93148
this.superiorSession.stepInRequest(response, args);
94149
}
95150

96151
protected override stepOutRequest(response: DebugProtocol.StepOutResponse, args: DebugProtocol.StepOutArguments): void {
152+
this.superiorSession.miDebugger.log("stdout", `step out request via inferior ${this.sessionPid}`);
97153
this.superiorSession.stepOutRequest(response, args);
98154
}
99155

100156
protected override nextRequest(response: DebugProtocol.NextResponse, args: DebugProtocol.NextArguments): void {
157+
this.superiorSession.miDebugger.log("stdout", `next request via inferior ${this.sessionPid}`);
101158
this.superiorSession.nextRequest(response, args);
102159
}
103160

104161
protected override evaluateRequest(response: DebugProtocol.EvaluateResponse, args: DebugProtocol.EvaluateArguments): void {
162+
this.superiorSession.miDebugger.log("stdout", `evaluate request via inferior ${this.sessionPid}`);
105163
this.superiorSession.evaluateRequest(response, args);
106164
}
107165

108166
protected override gotoTargetsRequest(response: DebugProtocol.GotoTargetsResponse, args: DebugProtocol.GotoTargetsArguments): void {
167+
this.superiorSession.miDebugger.log("stdout", `goto targets request via inferior ${this.sessionPid}`);
109168
this.superiorSession.gotoTargetsRequest(response, args);
110169
}
111170

112171
protected override gotoRequest(response: DebugProtocol.GotoResponse, args: DebugProtocol.GotoArguments): void {
172+
this.superiorSession.miDebugger.log("stdout", `goto request via inferior ${this.sessionPid}`);
113173
this.superiorSession.gotoRequest(response, args);
114174
}
115175
}

0 commit comments

Comments
 (0)