Skip to content

Commit 37bf4af

Browse files
author
Anna Gringauze
authored
Fix getStack race conditions on isolate start (#1704)
1 parent 6b93e27 commit 37bf4af

File tree

3 files changed

+13
-3
lines changed

3 files changed

+13
-3
lines changed

dwds/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
evaluation using a compiler in all scenarios.
66
- Fix a bug where evaluation would fail with more than one parameter in
77
the scope.
8-
- Remove showing uncaptured values from the stack during evaluation.
8+
- Remove showing un-captured values from the stack during evaluation.
99
- Refactor code to break most circular dependencies between files.
1010
- Migrate `package:dwds` to null safety.
11+
- Make `ChromeProxyService.getStack` wait for the debugger to perform initial
12+
resume operation. This avoids race conditions on isolate start.
1113

1214
**Breaking changes**
1315
- Remove no longer used `ExpressionCompilerService.handler`.

dwds/lib/src/debugging/debugger.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class Debugger extends Domain {
150150

151151
/// Returns the current Dart stack for the paused debugger.
152152
///
153-
/// Returns null if the debugger is not paused.
153+
/// Throws RPCError if the debugger is not paused.
154154
///
155155
/// The returned stack will contain up to [limit] frames if provided.
156156
Future<Stack> getStack({int? limit}) async {

dwds/lib/src/services/chrome_proxy_service.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class ChromeProxyService implements VmServiceInterface {
4646
Future<void> get isInitialized => _initializedCompleter.future;
4747
Completer<void> _initializedCompleter = Completer<void>();
4848

49+
/// Signals when isolate starts.
50+
Future<void> get isStarted => _startedCompleter.future;
51+
Completer<void> _startedCompleter = Completer<void>();
52+
4953
/// Signals when expression compiler is ready to evaluate.
5054
Future<void> get isCompilerInitialized => _compilerCompleter.future;
5155
Completer<void> _compilerCompleter = Completer<void>();
@@ -252,6 +256,7 @@ class ChromeProxyService implements VmServiceInterface {
252256

253257
unawaited(appConnection.onStart.then((_) async {
254258
await debugger.resumeFromStart();
259+
_startedCompleter.complete();
255260
}));
256261

257262
final isolateRef = inspector.isolateRef;
@@ -301,6 +306,7 @@ class ChromeProxyService implements VmServiceInterface {
301306
final isolateRef = inspector.isolateRef;
302307

303308
_initializedCompleter = Completer<void>();
309+
_startedCompleter = Completer<void>();
304310
_compilerCompleter = Completer<void>();
305311
_streamNotify(
306312
'Isolate',
@@ -573,12 +579,13 @@ ${globalLoadStrategy.loadModuleSnippet}("dart_sdk").developer.invokeExtension(
573579

574580
/// Returns the current stack.
575581
///
576-
/// Returns null if the corresponding isolate is not paused.
582+
/// Throws RPCError the corresponding isolate is not paused.
577583
///
578584
/// The returned stack will contain up to [limit] frames if provided.
579585
@override
580586
Future<Stack> getStack(String isolateId, {int? limit}) async {
581587
await isInitialized;
588+
await isStarted;
582589
_checkIsolate('getStack', isolateId);
583590
return (await debuggerFuture).getStack(limit: limit);
584591
}
@@ -718,6 +725,7 @@ ${globalLoadStrategy.loadModuleSnippet}("dart_sdk").developer.invokeExtension(
718725
if (inspector.appConnection.isStarted) {
719726
return captureElapsedTime(() async {
720727
await isInitialized;
728+
await isStarted;
721729
_checkIsolate('resume', isolateId);
722730
return await (await debuggerFuture)
723731
.resume(step: step, frameIndex: frameIndex);

0 commit comments

Comments
 (0)