[vm/debugger] break on asyncfunction entry

In observatory, "Break <function name>" will add a breakpoint at the beginning of function. But it will reject if <function name> is an async function, as it is not debuggable.
Add checks for async function will allow breakpoint to set. Once async_op is compiled, breakpoint will be resolved correctly.

Bug: https://github.com/dart-lang/sdk/issues/28561
Change-Id: I37cf6a05c54b6a0062845926f4f3b85557dcc52a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107522
Commit-Queue: Zichang Guo <zichangguo@google.com>
Reviewed-by: Régis Crelier <regis@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Zichang Guo 2019-07-02 17:49:48 +00:00 committed by commit-bot@chromium.org
parent e0eeffaf9b
commit 45a9815aff
2 changed files with 50 additions and 1 deletions

View file

@ -0,0 +1,45 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:observatory/service_io.dart';
import 'package:unittest/unittest.dart';
import 'service_test_common.dart';
import 'test_helper.dart';
import 'dart:developer';
const int LINE_A = 13;
Future<String> testFunction() async {
await new Future.delayed(new Duration(milliseconds: 1));
return "Done";
}
testMain() async {
debugger();
var str = await testFunction();
print(str);
}
var tests = <IsolateTest>[
hasStoppedAtBreakpoint,
// Add breakpoint at the entry of async function
(Isolate isolate) async {
Library rootLib = await isolate.rootLibrary.load();
var function =
rootLib.functions.singleWhere((f) => f.name == 'testFunction');
var bpt = await isolate.addBreakpointAtEntry(function);
expect(bpt is Breakpoint, isTrue);
print(bpt);
},
resumeIsolate,
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_A),
resumeIsolate,
];
main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);

View file

@ -3554,7 +3554,11 @@ void Debugger::SyncBreakpointLocation(BreakpointLocation* loc) {
Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function,
bool single_shot) {
ASSERT(!target_function.IsNull());
if (!target_function.is_debuggable()) {
// AsyncFunction is marked not debuggable. When target_function is an async
// function, it is actually referring the inner async_op. Allow the
// breakpoint to be set, it will get resolved correctly when inner async_op
// gets compiled.
if (!target_function.is_debuggable() && !target_function.IsAsyncFunction()) {
return NULL;
}
const Script& script = Script::Handle(target_function.script());