@@ -56,6 +56,16 @@ class IsolateManager {
56
56
/// [debugExternalPackageLibraries] in one step.
57
57
bool debugExternalPackageLibraries = true ;
58
58
59
+ /// Whether to automatically resume new isolates after configuring them.
60
+ ///
61
+ /// This setting is almost always `true` because isolates are paused only so
62
+ /// we can configure them (send breakpoints, pause-on-exceptions,
63
+ /// setLibraryDebuggables) without races. It is set to `false` during the
64
+ /// initial connection of an `attachRequest` to allow paused isolates to
65
+ /// remain paused. In this case, it will be automatically re-set to `true` the
66
+ /// first time the user resumes.
67
+ bool autoResumeStartingIsolates = true ;
68
+
59
69
/// The root of the Dart SDK containing the VM running the debug adapter.
60
70
late final String sdkRoot;
61
71
@@ -138,13 +148,7 @@ class IsolateManager {
138
148
ThreadInfo ? getThread (int threadId) => _threadsByThreadId[threadId];
139
149
140
150
/// Handles Isolate and Debug events.
141
- ///
142
- /// If [resumeIfStarting] is `true` , PauseStart/PausePostStart events will be
143
- /// automatically resumed from.
144
- Future <void > handleEvent (
145
- vm.Event event, {
146
- bool resumeIfStarting = true ,
147
- }) async {
151
+ Future <void > handleEvent (vm.Event event) async {
148
152
final isolateId = event.isolate? .id! ;
149
153
150
154
final eventKind = event.kind;
@@ -163,7 +167,7 @@ class IsolateManager {
163
167
if (eventKind == vm.EventKind .kIsolateExit) {
164
168
_handleExit (event);
165
169
} else if (eventKind? .startsWith ('Pause' ) ?? false ) {
166
- await _handlePause (event, resumeIfStarting : resumeIfStarting );
170
+ await _handlePause (event);
167
171
} else if (eventKind == vm.EventKind .kResume) {
168
172
_handleResumed (event);
169
173
}
@@ -236,6 +240,11 @@ class IsolateManager {
236
240
/// [vm.StepOption.kOver] , a [StepOption.kOverAsyncSuspension] step will be
237
241
/// sent instead.
238
242
Future <void > resumeThread (int threadId, [String ? resumeType]) async {
243
+ // The first time a user resumes a thread is our signal that the app is now
244
+ // "running" and future isolates can be auto-resumed. This only affects
245
+ // attach, as it's already `true` for launch requests.
246
+ autoResumeStartingIsolates = true ;
247
+
239
248
final thread = _threadsByThreadId[threadId];
240
249
if (thread == null ) {
241
250
throw DebugAdapterException ('Thread $threadId was not found' );
@@ -408,21 +417,18 @@ class IsolateManager {
408
417
///
409
418
/// For [vm.EventKind.kPausePostRequest] which occurs after a restart, the
410
419
/// isolate will be re-configured (pause-exception behaviour, debuggable
411
- /// libraries, breakpoints) and then (if [resumeIfStarting ] is `true` )
412
- /// resumed.
420
+ /// libraries, breakpoints) and then (if [autoResumeStartingIsolates ] is
421
+ /// `true` ) resumed.
413
422
///
414
- /// For [vm.EventKind.kPauseStart] and [resumeIfStarting ] is `true` , the
415
- /// isolate will be resumed.
423
+ /// For [vm.EventKind.kPauseStart] and [autoResumeStartingIsolates ] is `true` ,
424
+ /// the isolate will be resumed.
416
425
///
417
426
/// For breakpoints with conditions that are not met and for logpoints, the
418
427
/// isolate will be automatically resumed.
419
428
///
420
429
/// For all other pause types, the isolate will remain paused and a
421
430
/// corresponding "Stopped" event sent to the editor.
422
- Future <void > _handlePause (
423
- vm.Event event, {
424
- bool resumeIfStarting = true ,
425
- }) async {
431
+ Future <void > _handlePause (vm.Event event) async {
426
432
final eventKind = event.kind;
427
433
final isolate = event.isolate! ;
428
434
final thread = _threadsByIsolateId[isolate.id! ];
@@ -439,7 +445,7 @@ class IsolateManager {
439
445
// after a hot restart.
440
446
if (eventKind == vm.EventKind .kPausePostRequest) {
441
447
await _configureIsolate (thread);
442
- if (resumeIfStarting ) {
448
+ if (autoResumeStartingIsolates ) {
443
449
await resumeThread (thread.threadId);
444
450
}
445
451
} else if (eventKind == vm.EventKind .kPauseStart) {
@@ -449,7 +455,7 @@ class IsolateManager {
449
455
thread.startupHandled = true ;
450
456
// If requested, automatically resume. Otherwise send a Stopped event to
451
457
// inform the client UI the thread is paused.
452
- if (resumeIfStarting ) {
458
+ if (autoResumeStartingIsolates ) {
453
459
await resumeThread (thread.threadId);
454
460
} else {
455
461
sendStoppedOnEntryEvent (thread.threadId);
0 commit comments