Unverified Commit 675b9615 authored by Danny Tuppeny's avatar Danny Tuppeny Committed by GitHub

Unpause and remove breakpoints when detaching from Flutter process with DAP (#101695)

parent b0864737
...@@ -205,6 +205,9 @@ class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments ...@@ -205,6 +205,9 @@ class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments
/// quickly and therefore may leave orphaned processes. /// quickly and therefore may leave orphaned processes.
@override @override
Future<void> disconnectImpl() async { Future<void> disconnectImpl() async {
if (isAttach) {
await preventBreakingAndResume();
}
terminatePids(ProcessSignal.sigkill); terminatePids(ProcessSignal.sigkill);
} }
...@@ -379,6 +382,9 @@ class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments ...@@ -379,6 +382,9 @@ class FlutterDebugAdapter extends DartDebugAdapter<FlutterLaunchRequestArguments
/// Called by [terminateRequest] to request that we gracefully shut down the app being run (or in the case of an attach, disconnect). /// Called by [terminateRequest] to request that we gracefully shut down the app being run (or in the case of an attach, disconnect).
@override @override
Future<void> terminateImpl() async { Future<void> terminateImpl() async {
if (isAttach) {
await preventBreakingAndResume();
}
terminatePids(ProcessSignal.sigterm); terminatePids(ProcessSignal.sigterm);
await _process?.exitCode; await _process?.exitCode;
} }
......
...@@ -380,13 +380,35 @@ void main() { ...@@ -380,13 +380,35 @@ void main() {
stoppedFuture, stoppedFuture,
dap.client.setBreakpoint(breakpointFilePath, breakpointLine), dap.client.setBreakpoint(breakpointFilePath, breakpointLine),
], eagerError: true); ], eagerError: true);
final int threadId = (await stoppedFuture).threadId!; });
testWithoutContext('resumes and removes breakpoints on detach', () async {
final Uri vmServiceUri = await testProcess.vmServiceUri;
// Launch the app and wait for it to print "topLevelFunction".
await Future.wait(<Future<void>>[
dap.client.stdoutOutput.firstWhere((String output) => output.startsWith('topLevelFunction')),
dap.client.start(
launch: () => dap.client.attach(
cwd: project.dir.path,
toolArgs: <String>['-d', 'flutter-tester'],
vmServiceUri: vmServiceUri.toString(),
),
),
], eagerError: true);
// Remove the breakpoint and resume. // Set a breakpoint and expect to hit it.
await dap.client.clearBreakpoints(breakpointFilePath); final Future<StoppedEventBody> stoppedFuture = dap.client.stoppedEvents.firstWhere((StoppedEventBody e) => e.reason == 'breakpoint');
await dap.client.continue_(threadId); await Future.wait(<Future<void>>[
stoppedFuture,
dap.client.setBreakpoint(breakpointFilePath, breakpointLine),
], eagerError: true);
// Detach.
await dap.client.terminate(); await dap.client.terminate();
// Ensure we get additional output (confirming the process resumed).
await testProcess.output.first;
}); });
}); });
} }
......
...@@ -63,6 +63,11 @@ class SimpleFlutterRunner { ...@@ -63,6 +63,11 @@ class SimpleFlutterRunner {
unawaited(process.exitCode.then(_handleExitCode)); unawaited(process.exitCode.then(_handleExitCode));
} }
final StreamController<String> _output = StreamController<String>.broadcast();
/// A broadcast stream of any non-JSON output from the process.
Stream<String> get output => _output.stream;
void _handleExitCode(int code) { void _handleExitCode(int code) {
if (!_vmServiceUriCompleter.isCompleted) { if (!_vmServiceUriCompleter.isCompleted) {
_vmServiceUriCompleter.completeError('Flutter process ended without producing a VM Service URI'); _vmServiceUriCompleter.completeError('Flutter process ended without producing a VM Service URI');
...@@ -91,8 +96,9 @@ class SimpleFlutterRunner { ...@@ -91,8 +96,9 @@ class SimpleFlutterRunner {
} }
} }
} on FormatException { } on FormatException {
// `flutter run` writes a lot of text to stdout so just ignore anything // `flutter run` writes a lot of text to stdout that isn't daemon messages
// that's not valid JSON. // (not valid JSON), so just pass that one for tests that may want it.
_output.add(outputLine);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment