Unpause and remove breakpoints when detaching from Flutter process with DAP (#101695)
This commit is contained in:
parent
b086473769
commit
675b961573
@ -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
|
|||||||
/// 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() {
|
|||||||
stoppedFuture,
|
stoppedFuture,
|
||||||
dap.client.setBreakpoint(breakpointFilePath, breakpointLine),
|
dap.client.setBreakpoint(breakpointFilePath, breakpointLine),
|
||||||
], eagerError: true);
|
], eagerError: true);
|
||||||
final int threadId = (await stoppedFuture).threadId!;
|
});
|
||||||
|
|
||||||
// Remove the breakpoint and resume.
|
testWithoutContext('resumes and removes breakpoints on detach', () async {
|
||||||
await dap.client.clearBreakpoints(breakpointFilePath);
|
final Uri vmServiceUri = await testProcess.vmServiceUri;
|
||||||
await dap.client.continue_(threadId);
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Set a breakpoint and expect to hit it.
|
||||||
|
final Future<StoppedEventBody> stoppedFuture = dap.client.stoppedEvents.firstWhere((StoppedEventBody e) => e.reason == 'breakpoint');
|
||||||
|
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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user