From 643e4d6717241678d3378011dab37f35edf2c177 Mon Sep 17 00:00:00 2001 From: xiphon Date: Wed, 14 Nov 2018 18:13:50 +0000 Subject: [PATCH 1/6] debug: fixed 'ThreadsRequest' handling when debugState is null --- src/debugAdapter/goDebug.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts index 042d5a3f1..5c3ef9ec5 100644 --- a/src/debugAdapter/goDebug.ts +++ b/src/debugAdapter/goDebug.ts @@ -759,7 +759,7 @@ class GoDebugSession extends LoggingDebugSession { } log('ThreadsRequest'); this.delve.call('ListGoroutines', [], (err, out) => { - if (this.debugState.exited) { + if (this.debugState && this.debugState.exited) { // If the program exits very quickly, the initial threadsRequest will complete after it has exited. // A TerminatedEvent has already been sent. Ignore the err returned in this case. response.body = { threads: [] }; From f7085dd2f834e057d5d886f81ce4c202381f23cb Mon Sep 17 00:00:00 2001 From: xiphon Date: Wed, 14 Nov 2018 18:14:37 +0000 Subject: [PATCH 2/6] debug: update threads state on 'ThreadsRequest' --- src/debugAdapter/goDebug.ts | 39 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts index 5c3ef9ec5..20677c3f0 100644 --- a/src/debugAdapter/goDebug.ts +++ b/src/debugAdapter/goDebug.ts @@ -751,6 +751,26 @@ class GoDebugSession extends LoggingDebugSession { }); } + private updateThreads(goroutines: DebugGoroutine[]): void { + // Assume we need to stop all the threads we saw before... + let needsToBeStopped = new Set(); + this.threads.forEach(id => needsToBeStopped.add(id)); + for (let goroutine of goroutines) { + // ...but delete from list of threads to stop if we still see it + needsToBeStopped.delete(goroutine.id); + if (!this.threads.has(goroutine.id)) { + // Send started event if it's new + this.sendEvent(new ThreadEvent('started', goroutine.id)); + } + this.threads.add(goroutine.id); + } + // Send existed event if it's no longer there + needsToBeStopped.forEach(id => { + this.sendEvent(new ThreadEvent('exited', id)); + this.threads.delete(id); + }); + } + protected threadsRequest(response: DebugProtocol.ThreadsResponse): void { if (this.continueRequestRunning) { // Thread request to delve is syncronous and will block if a previous async continue request didn't return @@ -772,6 +792,7 @@ class GoDebugSession extends LoggingDebugSession { } const goroutines = this.delve.isApiV1 ? out : (out).Goroutines; log('goroutines', goroutines); + this.updateThreads(goroutines); let threads = goroutines.map(goroutine => new Thread( goroutine.id, @@ -1055,23 +1076,7 @@ class GoDebugSession extends LoggingDebugSession { logError('Failed to get threads - ' + err.toString()); } const goroutines = this.delve.isApiV1 ? out : (out).Goroutines; - // Assume we need to stop all the threads we saw before... - let needsToBeStopped = new Set(); - this.threads.forEach(id => needsToBeStopped.add(id)); - for (let goroutine of goroutines) { - // ...but delete from list of threads to stop if we still see it - needsToBeStopped.delete(goroutine.id); - if (!this.threads.has(goroutine.id)) { - // Send started event if it's new - this.sendEvent(new ThreadEvent('started', goroutine.id)); - } - this.threads.add(goroutine.id); - } - // Send existed event if it's no longer there - needsToBeStopped.forEach(id => { - this.sendEvent(new ThreadEvent('exited', id)); - this.threads.delete(id); - }); + this.updateThreads(goroutines); let stoppedEvent = new StoppedEvent(reason, this.debugState.currentGoroutine.id); (stoppedEvent.body).allThreadsStopped = true; From 3648a2eb6952a396353f2be61180954d1bf0cb5d Mon Sep 17 00:00:00 2001 From: xiphon Date: Wed, 14 Nov 2018 18:14:56 +0000 Subject: [PATCH 3/6] debug: return dummy thread on 'ThreadsRequest' while running --- src/debugAdapter/goDebug.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts index 20677c3f0..7aa5e4e5c 100644 --- a/src/debugAdapter/goDebug.ts +++ b/src/debugAdapter/goDebug.ts @@ -774,7 +774,7 @@ class GoDebugSession extends LoggingDebugSession { protected threadsRequest(response: DebugProtocol.ThreadsResponse): void { if (this.continueRequestRunning) { // Thread request to delve is syncronous and will block if a previous async continue request didn't return - response.body = { threads: [] }; + response.body = { threads: [new Thread(1, 'Dummy')] }; return this.sendResponse(response); } log('ThreadsRequest'); From e56e19cb8bbd0e17ef190ada3b26fc39f62ef47a Mon Sep 17 00:00:00 2001 From: xiphon Date: Wed, 14 Nov 2018 18:15:20 +0000 Subject: [PATCH 4/6] debug: use any active goroutine when debugState.currentGoroutine is null --- src/debugAdapter/goDebug.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts index 7aa5e4e5c..55bc81db2 100644 --- a/src/debugAdapter/goDebug.ts +++ b/src/debugAdapter/goDebug.ts @@ -1077,6 +1077,9 @@ class GoDebugSession extends LoggingDebugSession { } const goroutines = this.delve.isApiV1 ? out : (out).Goroutines; this.updateThreads(goroutines); + if (!this.debugState.currentGoroutine && goroutines.length > 0) { + this.debugState.currentGoroutine = goroutines[0]; + } let stoppedEvent = new StoppedEvent(reason, this.debugState.currentGoroutine.id); (stoppedEvent.body).allThreadsStopped = true; From c15ed9d36664d68b6d7251857f517f58978b8ffb Mon Sep 17 00:00:00 2001 From: xiphon Date: Wed, 14 Nov 2018 18:15:40 +0000 Subject: [PATCH 5/6] debug: update debugState and threads on 'PauseRequest' --- src/debugAdapter/goDebug.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts index 55bc81db2..babee5737 100644 --- a/src/debugAdapter/goDebug.ts +++ b/src/debugAdapter/goDebug.ts @@ -1165,9 +1165,11 @@ class GoDebugSession extends LoggingDebugSession { } const state = this.delve.isApiV1 ? out : (out).State; log('pause state', state); - this.sendResponse(response); - log('PauseResponse'); + this.debugState = state; + this.handleReenterDebug('pause'); }); + this.sendResponse(response); + log('PauseResponse'); } protected evaluateRequest(response: DebugProtocol.EvaluateResponse, args: DebugProtocol.EvaluateArguments): void { From fc0784062a855e7658703287ce6d4de25afcff0c Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Sun, 27 Jan 2019 22:52:38 -0800 Subject: [PATCH 6/6] Rename for clarity --- src/debugAdapter/goDebug.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/debugAdapter/goDebug.ts b/src/debugAdapter/goDebug.ts index 39c1a39be..7dec79902 100644 --- a/src/debugAdapter/goDebug.ts +++ b/src/debugAdapter/goDebug.ts @@ -545,7 +545,7 @@ class GoDebugSession extends LoggingDebugSession { private _variableHandles: Handles; private breakpoints: Map; private skipStopEventOnce: boolean; // Editing breakpoints requires halting delve, skip sending Stop Event to VS Code in such cases - private threads: Set; + private goroutines: Set; private debugState: DebuggerState; private delve: Delve; private localPathSeparator: string; @@ -560,7 +560,7 @@ class GoDebugSession extends LoggingDebugSession { super('', debuggerLinesStartAt1, isServer); this._variableHandles = new Handles(); this.skipStopEventOnce = false; - this.threads = new Set(); + this.goroutines = new Set(); this.debugState = null; this.delve = null; this.breakpoints = new Map(); @@ -706,26 +706,26 @@ class GoDebugSession extends LoggingDebugSession { return pathToConvert.replace(this.delve.remotePath, this.delve.program).split(this.remotePathSeparator).join(this.localPathSeparator); } - private updateThreads(goroutines: DebugGoroutine[]): void { + private updateGoroutinesList(goroutines: DebugGoroutine[]): void { // Assume we need to stop all the threads we saw before... let needsToBeStopped = new Set(); - this.threads.forEach(id => needsToBeStopped.add(id)); + this.goroutines.forEach(id => needsToBeStopped.add(id)); for (let goroutine of goroutines) { // ...but delete from list of threads to stop if we still see it needsToBeStopped.delete(goroutine.id); - if (!this.threads.has(goroutine.id)) { + if (!this.goroutines.has(goroutine.id)) { // Send started event if it's new this.sendEvent(new ThreadEvent('started', goroutine.id)); } - this.threads.add(goroutine.id); + this.goroutines.add(goroutine.id); } // Send existed event if it's no longer there needsToBeStopped.forEach(id => { this.sendEvent(new ThreadEvent('exited', id)); - this.threads.delete(id); + this.goroutines.delete(id); }); } - + private setBreakPoints(response: DebugProtocol.SetBreakpointsResponse, args: DebugProtocol.SetBreakpointsArguments): Thenable { let file = normalizePath(args.source.path); if (!this.breakpoints.get(file)) { @@ -823,7 +823,7 @@ class GoDebugSession extends LoggingDebugSession { } const goroutines = this.delve.isApiV1 ? out : (out).Goroutines; log('goroutines', goroutines); - this.updateThreads(goroutines); + this.updateGoroutinesList(goroutines); let threads = goroutines.map(goroutine => new Thread( goroutine.id, @@ -1139,7 +1139,7 @@ class GoDebugSession extends LoggingDebugSession { logError('Failed to get threads - ' + err.toString()); } const goroutines = this.delve.isApiV1 ? out : (out).Goroutines; - this.updateThreads(goroutines); + this.updateGoroutinesList(goroutines); if (!this.debugState.currentGoroutine && goroutines.length > 0) { this.debugState.currentGoroutine = goroutines[0]; }