@@ -90,6 +90,7 @@ interface DebuggerState {
90
90
currentGoroutine : DebugGoroutine ;
91
91
Running : boolean ;
92
92
Threads : DebugThread [ ] ;
93
+ NextInProgress : boolean ;
93
94
}
94
95
95
96
export interface PackageBuildInfo {
@@ -857,6 +858,7 @@ export class GoDebugSession extends LoggingDebugSession {
857
858
private breakpoints : Map < string , DebugBreakpoint [ ] > ;
858
859
// Editing breakpoints requires halting delve, skip sending Stop Event to VS Code in such cases
859
860
private skipStopEventOnce : boolean ;
861
+ private overrideStopReason : string ;
860
862
private debugState : DebuggerState ;
861
863
private delve : Delve ;
862
864
private localPathSeparator : string ;
@@ -877,13 +879,16 @@ export class GoDebugSession extends LoggingDebugSession {
877
879
878
880
private continueEpoch = 0 ;
879
881
private continueRequestRunning = false ;
882
+ private nextEpoch = 0 ;
883
+ private nextRequestRunning = false ;
880
884
public constructor (
881
885
debuggerLinesStartAt1 : boolean ,
882
886
isServer : boolean = false ,
883
887
readonly fileSystem = fs ) {
884
888
super ( '' , debuggerLinesStartAt1 , isServer ) ;
885
889
this . variableHandles = new Handles < DebugVariable > ( ) ;
886
890
this . skipStopEventOnce = false ;
891
+ this . overrideStopReason = '' ;
887
892
this . stopOnEntry = false ;
888
893
this . debugState = null ;
889
894
this . delve = null ;
@@ -1303,11 +1308,25 @@ export class GoDebugSession extends LoggingDebugSession {
1303
1308
log ( 'Debuggee is not running. Setting breakpoints without halting.' ) ;
1304
1309
await this . setBreakPoints ( response , args ) ;
1305
1310
} else {
1311
+ // Skip stop event if a continue request is running.
1306
1312
this . skipStopEventOnce = this . continueRequestRunning ;
1313
+ const haltedDuringNext = this . nextRequestRunning ;
1314
+ if ( haltedDuringNext ) {
1315
+ this . overrideStopReason = 'next cancelled' ;
1316
+ }
1317
+
1307
1318
log ( `Halting before setting breakpoints. SkipStopEventOnce is ${ this . skipStopEventOnce } .` ) ;
1308
1319
this . delve . callPromise ( 'Command' , [ { name : 'halt' } ] ) . then (
1309
1320
( ) => {
1310
1321
return this . setBreakPoints ( response , args ) . then ( ( ) => {
1322
+ // We do not want to continue if it was running a next request, since the
1323
+ // request was automatically cancelled.
1324
+ if ( haltedDuringNext ) {
1325
+ // Send an output event containing a warning that next was cancelled.
1326
+ const warning = `Setting breakpoints during 'next', 'step in' or 'step out' halted delve and cancelled the next request` ;
1327
+ this . sendEvent ( new OutputEvent ( warning , 'stderr' ) ) ;
1328
+ return ;
1329
+ }
1311
1330
return this . continue ( true ) . then ( null , ( err ) => {
1312
1331
this . logDelveError ( err , 'Failed to continue delve after halting it to set breakpoints' ) ;
1313
1332
} ) ;
@@ -1687,8 +1706,16 @@ export class GoDebugSession extends LoggingDebugSession {
1687
1706
}
1688
1707
1689
1708
protected nextRequest ( response : DebugProtocol . NextResponse ) : void {
1709
+ this . nextEpoch ++ ;
1710
+ const closureEpoch = this . nextEpoch ;
1711
+ this . nextRequestRunning = true ;
1712
+
1690
1713
log ( 'NextRequest' ) ;
1691
1714
this . delve . call < DebuggerState | CommandOut > ( 'Command' , [ { name : 'next' } ] , ( err , out ) => {
1715
+ if ( closureEpoch === this . continueEpoch ) {
1716
+ this . nextRequestRunning = false ;
1717
+ }
1718
+
1692
1719
if ( err ) {
1693
1720
this . logDelveError ( err , 'Failed to next' ) ;
1694
1721
}
@@ -1702,8 +1729,16 @@ export class GoDebugSession extends LoggingDebugSession {
1702
1729
}
1703
1730
1704
1731
protected stepInRequest ( response : DebugProtocol . StepInResponse ) : void {
1732
+ this . nextEpoch ++ ;
1733
+ const closureEpoch = this . nextEpoch ;
1734
+ this . nextRequestRunning = true ;
1735
+
1705
1736
log ( 'StepInRequest' ) ;
1706
1737
this . delve . call < DebuggerState | CommandOut > ( 'Command' , [ { name : 'step' } ] , ( err , out ) => {
1738
+ if ( closureEpoch === this . continueEpoch ) {
1739
+ this . nextRequestRunning = false ;
1740
+ }
1741
+
1707
1742
if ( err ) {
1708
1743
this . logDelveError ( err , 'Failed to step in' ) ;
1709
1744
}
@@ -1717,8 +1752,16 @@ export class GoDebugSession extends LoggingDebugSession {
1717
1752
}
1718
1753
1719
1754
protected stepOutRequest ( response : DebugProtocol . StepOutResponse ) : void {
1755
+ this . nextEpoch ++ ;
1756
+ const closureEpoch = this . nextEpoch ;
1757
+ this . nextRequestRunning = true ;
1758
+
1720
1759
log ( 'StepOutRequest' ) ;
1721
1760
this . delve . call < DebuggerState | CommandOut > ( 'Command' , [ { name : 'stepOut' } ] , ( err , out ) => {
1761
+ if ( closureEpoch === this . continueEpoch ) {
1762
+ this . nextRequestRunning = false ;
1763
+ }
1764
+
1722
1765
if ( err ) {
1723
1766
this . logDelveError ( err , 'Failed to step out' ) ;
1724
1767
}
@@ -2352,6 +2395,11 @@ export class GoDebugSession extends LoggingDebugSession {
2352
2395
return ;
2353
2396
}
2354
2397
2398
+ if ( this . overrideStopReason ?. length > 0 ) {
2399
+ reason = this . overrideStopReason ;
2400
+ this . overrideStopReason = '' ;
2401
+ }
2402
+
2355
2403
const stoppedEvent = new StoppedEvent ( reason , this . debugState . currentGoroutine . id ) ;
2356
2404
( < any > stoppedEvent . body ) . allThreadsStopped = true ;
2357
2405
this . sendEvent ( stoppedEvent ) ;
@@ -2375,7 +2423,7 @@ export class GoDebugSession extends LoggingDebugSession {
2375
2423
} catch ( error ) {
2376
2424
this . logDelveError ( error , 'Failed to get state' ) ;
2377
2425
// Fall back to the internal tracking.
2378
- return this . continueRequestRunning ;
2426
+ return this . continueRequestRunning || this . nextRequestRunning ;
2379
2427
}
2380
2428
}
2381
2429
0 commit comments