Skip to content

Commit 379e208

Browse files
Clement Skaucommit-bot@chromium.org
authored andcommitted
[Test] Fix lazy-async nested stepping consistency, tests.
The debugger async function handling has been moved to allow handling of stepping_fp_ and async_stepping_fp_. Previously the presence of an async function would take precedence over the *stepping_fp while stepping, resulting in nested asyncs to incorrectly re-trigger the insertion of synthetic breakpoints. This fix revealed three tests that were still testing for unintentional inconsistencies between causal and lazy async. Note that there are still tests that branch on `useCausalAsyncStacks` though these all test for known differences - namely that lazy async cannot traverse unawaited future calls. Cq-Include-Trybots: luci.dart.try:app-kernel-linux-debug-x64-try,vm-kernel-linux-debug-x64-try Change-Id: I5f74db18086a90828024dbb461759869531d478f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164781 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Clement Skau <cskau@google.com>
1 parent 3af9638 commit 379e208

File tree

4 files changed

+42
-52
lines changed

4 files changed

+42
-52
lines changed

runtime/observatory/tests/service/async_next_regession_18877_test.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ var tests = <IsolateTest>[
3838
hasStoppedAtBreakpoint,
3939
stoppedAtLine(LINE_A),
4040
stepOver, // foo()
41+
stoppedAtLine(LINE_A),
4142
asyncNext,
4243
hasStoppedAtBreakpoint,
4344
stoppedAtLine(LINE_B),
4445
stepOver, // foo()
46+
stoppedAtLine(LINE_B),
4547
asyncNext,
4648
hasStoppedAtBreakpoint,
4749
stoppedAtLine(LINE_C),

runtime/observatory/tests/service/pause_on_unhandled_async_exceptions2_test.dart

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,13 @@ var tests = <IsolateTest>[
4444
var stack = await isolate.getStack();
4545
expect(stack['asyncCausalFrames'], isNotNull);
4646
var asyncStack = stack['asyncCausalFrames'];
47-
if (useCausalAsyncStacks) {
48-
expect(asyncStack.length, greaterThanOrEqualTo(4));
49-
expect(asyncStack[0].toString(), contains('doThrow'));
50-
expect(asyncStack[1].toString(), contains('asyncThrower'));
51-
expect(asyncStack[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
52-
expect(asyncStack[3].toString(), contains('testeeMain'));
53-
expect(await asyncStack[3].location.toUserString(),
54-
contains('.dart:$LINE_A'));
55-
} else {
56-
expect(asyncStack.length, greaterThanOrEqualTo(2));
57-
expect(asyncStack[0].toString(), contains('doThrow'));
58-
expect(asyncStack[1].toString(), contains('asyncThrower'));
59-
// There was no await'er for "doThrow()".
60-
}
47+
expect(asyncStack.length, greaterThanOrEqualTo(4));
48+
expect(asyncStack[0].toString(), contains('doThrow'));
49+
expect(asyncStack[1].toString(), contains('asyncThrower'));
50+
expect(asyncStack[2].kind, equals(M.FrameKind.asyncSuspensionMarker));
51+
expect(asyncStack[3].toString(), contains('testeeMain'));
52+
expect(
53+
await asyncStack[3].location.toUserString(), contains('.dart:$LINE_A'));
6154
}
6255
];
6356

runtime/observatory/tests/service/positive_token_pos_test.dart

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,8 @@ var tests = <IsolateTest>[
3030
// See issue #27128.
3131
var frame = stack['frames'][0];
3232
expect(frame.function.qualifiedName, equals('helper.async_op'));
33-
if (useCausalAsyncStacks) {
34-
expect(await frame.location.getLine(), equals(14));
35-
expect(await frame.location.getColumn(), equals(1));
36-
} else {
37-
expect(await frame.location.getLine(), equals(12));
38-
expect(await frame.location.getColumn(), equals(7));
39-
}
33+
expect(await frame.location.getLine(), equals(14));
34+
expect(await frame.location.getColumn(), equals(1));
4035

4136
frame = stack['frames'][1];
4237
expect(frame.function.name, equals('testMain'));

runtime/vm/debugger.cc

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4470,37 +4470,6 @@ ErrorPtr Debugger::PauseStepping() {
44704470
ActivationFrame* frame = TopDartFrame();
44714471
ASSERT(frame != NULL);
44724472

4473-
// Since lazy async stacks doesn't use the _asyncStackTraceHelper runtime
4474-
// entry, we need to manually set a synthetic breakpoint for async_op before
4475-
// we enter it.
4476-
if (FLAG_lazy_async_stacks) {
4477-
// async and async* functions always contain synthetic async_ops.
4478-
if ((frame->function().IsAsyncFunction() ||
4479-
frame->function().IsAsyncGenerator())) {
4480-
ASSERT(!frame->GetSavedCurrentContext().IsNull());
4481-
ASSERT(frame->GetSavedCurrentContext().num_variables() >
4482-
Context::kAsyncCompleterIndex);
4483-
4484-
const Object& jump_var = Object::Handle(
4485-
frame->GetSavedCurrentContext().At(Context::kAsyncCompleterIndex));
4486-
4487-
// Only set breakpoint when entering async_op the first time.
4488-
// :async_completer_var should be uninitialised at this point:
4489-
if (jump_var.IsNull()) {
4490-
const Function& async_op =
4491-
Function::Handle(frame->function().GetGeneratedClosure());
4492-
if (!async_op.IsNull()) {
4493-
SetBreakpointAtAsyncOp(async_op);
4494-
// After setting the breakpoint we stop stepping and continue the
4495-
// debugger until the next breakpoint, to step over all the
4496-
// synthetic code.
4497-
Continue();
4498-
return Error::null();
4499-
}
4500-
}
4501-
}
4502-
}
4503-
45044473
if (FLAG_async_debugger) {
45054474
if ((async_stepping_fp_ != 0) && (top_frame_awaiter_ != Object::null())) {
45064475
// Check if the user has single stepped out of an async function with
@@ -4539,6 +4508,37 @@ ErrorPtr Debugger::PauseStepping() {
45394508
}
45404509
}
45414510

4511+
// Since lazy async stacks doesn't use the _asyncStackTraceHelper runtime
4512+
// entry, we need to manually set a synthetic breakpoint for async_op before
4513+
// we enter it.
4514+
if (FLAG_lazy_async_stacks) {
4515+
// async and async* functions always contain synthetic async_ops.
4516+
if ((frame->function().IsAsyncFunction() ||
4517+
frame->function().IsAsyncGenerator())) {
4518+
ASSERT(!frame->GetSavedCurrentContext().IsNull());
4519+
ASSERT(frame->GetSavedCurrentContext().num_variables() >
4520+
Context::kAsyncCompleterIndex);
4521+
4522+
const Object& async_completer = Object::Handle(
4523+
frame->GetSavedCurrentContext().At(Context::kAsyncCompleterIndex));
4524+
4525+
// Only set breakpoint when entering async_op the first time.
4526+
// :async_completer_var should be uninitialised at this point:
4527+
if (async_completer.IsNull()) {
4528+
const Function& async_op =
4529+
Function::Handle(frame->function().GetGeneratedClosure());
4530+
if (!async_op.IsNull()) {
4531+
SetBreakpointAtAsyncOp(async_op);
4532+
// After setting the breakpoint we stop stepping and continue the
4533+
// debugger until the next breakpoint, to step over all the
4534+
// synthetic code.
4535+
Continue();
4536+
return Error::null();
4537+
}
4538+
}
4539+
}
4540+
}
4541+
45424542
if (!frame->IsDebuggable()) {
45434543
return Error::null();
45444544
}

0 commit comments

Comments
 (0)