The main contribution of this CL is unification of disparate
handling of various functions like `Future.timeout`,
`Future.wait`, `_SuspendState.createAsyncCallbacks` and
`_SuspendState._createAsyncStarCallback` into a single
`@pragma('vm:awaiter-link')` which allows Dart developers
to specify where awaiter unwinder should look for the next
awaiter.
For example this allows unwinding to succeed for the code like this:
Future<int> outer(Future<int> inner) {
@pragma('vm:awaiter-link')
final completer = Completer<int>();
inner.then((v) => completer.complete(v));
return completer.future;
}
This refactoring also ensures that we preserve information
(including Function & Code objects) required for awaiter
unwinding across all modes (JIT, AOT and AOT with DWARF stack
traces). This guarantees users will get the same information
no matter which mode they are running in. Previously
we have been disabling awaiter_stacks tests in some AOT
modes - which led to regressions in the quality of produced
stacks.
This CL also cleans up relationship between debugger and awaiter
stack returned by StackTrace.current - which makes stack trace
displayed by debugger (used for stepping out and determinining
whether exception is caught or not) and `StackTrace.current`
consistent.
Finally we make one user visible change to the stack trace:
awaiter stack will no always include intermediate listeners
created through `Future.then`. Previously we would sometimes
include these listeners at the tail of the stack trace,
which was inconsistent.
Ultimately this means that code like this:
Future<int> inner() async {
await null; // asynchronous gap
print(StackTrace.current); // (*)
return 0;
}
Future<int> outer() async {
int process(int v) {
return v + 1;
}
return await inner().then(process);
}
void main() async {
await outer();
}
Produces stack trace like this:
inner
<asynchronous suspension>
outer.process
<asynchronous suspension>
outer
<asynchronous suspension>
main
<asynchronous suspension>
And when stepping out of `inner` execution will stop at `outer.process`
first and the next step out will bring execution to `outer` next.
Fixes https://github.com/dart-lang/sdk/issues/52797
Fixes https://github.com/dart-lang/sdk/issues/52203
Issue https://github.com/dart-lang/sdk/issues/47985
TEST=ci
Bug: b/279929839
CoreLibraryReviewExempt: CL just adds @pragma to facilitate unwinding
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-dwarf-linux-product-x64-try
Change-Id: If377d5329d6a11c86effb9369dc603a7ae616fe7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311680
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
The name is more accurately reflects what this stack trace
contains: despite what causal implies it does *not* actually
reflect the stack which initiated the async operation. Instead
it contains the chain of listeners which will run when
the async operation completes - its awaiters.
TEST=ci
Change-Id: Ie7309c9b1c39246e0fd4c14f7b9c515bcdfbbe10
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311384
Reviewed-by: Derek Xu <derekx@google.com>
We no longer rewrite suspendable function into closures nested
inside the original function, so the whole synthetic async breakpoint
machinery is not needed.
Refactor `Breakpoint` class to make one-shot and per-closure
separate properties of breakpoint, which allows creating
one-shot-per-closure breakpoints.
TEST=existing service tests
Change-Id: I208afe13f36efa40f5746e44867bd24684cf5f03
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310601
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Reviewed-by: Derek Xu <derekx@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
v11.7.0 has to be skipped because it was retracted.
Change-Id: Ia51a1b0ec261e671d2007a03c5089ff590e1313e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308723
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
This reverts commit 6c3c34560e.
Reason for revert: We will put the proto bindings in a separate package to prevent introducing new transitive dependencies into package:flutter.
Original change's description:
> [VM/Service] Add code for working with Perfetto protos to package:vm_service
>
> TEST=get_perfetto_vm_timeline_rpc_test and
> get_perfetto_cpu_samples_rpc_test
>
> Change-Id: I23a30629f1d7a8cd7e2c9daad2d02fae4decb338
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/302421
> Reviewed-by: Ben Konyi <bkonyi@google.com>
> Commit-Queue: Derek Xu <derekx@google.com>
Change-Id: I3bd9ce8a09e131271f76fe46ca92288f888d6147
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307968
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
In Flutter hot reload, the flutter_tools are calling the `getIsolate`
to read the pause state of the isolate, which returns a full list of
libraries loaded in the isolate. The size of the return object grow
linearly to the number of Dart files, which can take ~500ms to transfer
for a large app.
This change adds a new method to only read what is needed.
TEST=pkg/vm_service/test/get_isolate_pause_event_rpc_test.dart
Change-Id: If19910cb3ff5d5057932551ac738afd3c3136fac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305362
Reviewed-by: Ben Konyi <bkonyi@google.com>
Auto-Submit: Chingjun Lau <chingjun@google.com>
Commit-Queue: Derek Xu <derekx@google.com>
This field was supposed[1] to replace Stack.asyncCausalFrames but IDEs
and other service protocol users never adopted it.
The mechanism for collecting awaiterFrames and asyncCausalFrames
was originally considerably different, but we have since unified
both[2] after we switched to lazy async stack traces[3].
Today the only differences between the two are:
- asyncCausalFrames represens async gaps explicitly, while
awaiterFrames does not;
- when asynchronous function is running its synchronous part
before the first suspension awaiterFrames will still represent
the corresponding frame as an asynchronous activation, while
asyncCausalFrames will treat the same frame as regular frame.
Consequently having this field does not add any value.
This CL removes it from the response and updates all tests to
test against asyncCausalFrames.
[1]: https://codereview.chromium.org/2692803006/
[2]: https://dart-review.googlesource.com/c/sdk/+/167561
[3]: https://github.com/dart-lang/sdk/issues/37668
Tested: pkg/vm_service, service, service_2
Bug: https://github.com/dart-lang/sdk/issues/51763
Change-Id: If2b035a8840047423b8ed8ce3b5d81155e9f38d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301062
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
TEST=Checked that Observatory's timeline view was still able to load CPU
samples correctly, and ensured that samples retrived using
getPerfettoCpuSamples were the same as the ones shown in Observatory.
Change-Id: I9b58cd32bc9a1c08848718f25f10db9fa6d4d241
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/297760
Commit-Queue: Derek Xu <derekx@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
TEST=Loaded the response from a getPerfettoVMTimeline request in the
Perfetto trace viewer and made sure everything looked correct.
Change-Id: I8d4bc35fb36601701976c28653db92b2161e4724
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/288066
Commit-Queue: Derek Xu <derekx@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
TEST=Manually verified that the modified CLI options worked as expected, CI
Change-Id: Ibaa308e5c9c3b96c939e2007ee2eaaca30eae280
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/288063
Reviewed-by: Ben Konyi <bkonyi@google.com>
Change-Id: Icf489686d790be195e37db37727782227d2f3704
TEST=Version bump autogenerated by scripts
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/294600
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: William Hesse <whesse@google.com>
The changes the MatchingCache to always create a new CacheExpression.
When the expression is cached the first CacheExpression is used
(the current behavior) but when the expression is not cached, each
individual CacheExpression is used. This ensures the file offsets match
the source location for the uncached expression.
In the updated VM test this shows up as the is-tests using all for
lines in the switch case and not just the first two.
In response to https://github.com/dart-lang/sdk/issues/51812
Change-Id: I2d7bdb54e11f212cd809899a50d827284c4f6657
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292082
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Also adds a new "label" property to @Instance
TEST=pkg/vm_service/test/get_object_rpc_test.dart
Change-Id: I746d56909a55e0158896e1034665147c469109bb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290920
Reviewed-by: Derek Xu <derekx@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This is a reland of commit 1be893c507
Patchset 2 fixes the failure that was in
pkg/dds/test/dap/integration/debug_variables_test.
TEST=CI
Original change's description:
> [VM/Service] Start indexing positional record fields at 1
>
> TEST=CI
>
> Fixes: https://github.com/dart-lang/sdk/issues/51451
> Change-Id: I0e00e0ffb35aeb40affbbd5544542723bafc747c
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/284722
> Reviewed-by: Ben Konyi <bkonyi@google.com>
> Commit-Queue: Derek Xu <derekx@google.com>
Change-Id: I4cdee610646b3389d7d02ee6d905a66ae6e0329d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/284862
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Derek Xu <derekx@google.com>