mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 23:49:45 +00:00
df6fd34f75
This CL adds @pragma('vm:awaiter-link') in various places in Stream implementation to facilitate unwinding and expands async unwinding logic with more information about Stream internals. At the same time be more conservative when checking if an exception thrown from async method handled: failing to unwind the stack fully creates situations when we incorrectly report caught exceptions as uncaught, which frustrates users. To distinguish stream subscriptions with and without error handlers we add a state bit. Otherwise, it looks like all subscriptions have error handlers because if no error handler is installed we eagerly install error handler forwarding the error to `Zone.handleUncaughtError`. Fixes https://github.com/dart-lang/sdk/issues/53334 Fixes https://github.com/dart-lang/sdk/issues/54788 Fixes https://github.com/dart-lang/sdk/issues/47985 TEST=runtime/vm/dart/awaiter_stacks/stream_methods_test.dart,pkg/vm_service/test/pause_on_unhandled_async_exceptions6_test.dart,pkg/vm_service/test/pause_on_unhandled_async_exceptions7_test.dart CoreLibraryReviewExempt: No behavioral change. Async changes reviewed by lrhn@ Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-dwarf-linux-product-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try Change-Id: Ic51f926867092dd0adbe801b753f57c357c7ace2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/322720 Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Lasse Nielsen <lrn@google.com> Reviewed-by: Ben Konyi <bkonyi@google.com> Commit-Queue: Slava Egorov <vegorov@google.com>
72 lines
2.3 KiB
C++
72 lines
2.3 KiB
C++
// Copyright (c) 2017, 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.
|
|
|
|
#ifndef RUNTIME_VM_STACK_TRACE_H_
|
|
#define RUNTIME_VM_STACK_TRACE_H_
|
|
|
|
#include <functional>
|
|
|
|
#include "vm/allocation.h"
|
|
#include "vm/flag_list.h"
|
|
#include "vm/object.h"
|
|
#include "vm/symbols.h"
|
|
|
|
namespace dart {
|
|
|
|
class StackTraceUtils : public AllStatic {
|
|
public:
|
|
static constexpr uword kFutureListenerPcOffset = 1;
|
|
|
|
struct Frame {
|
|
// Corresponding on stack frame or |nullptr| if this is an awaiter frame
|
|
// or a gap.
|
|
StackFrame* frame;
|
|
|
|
// Code object corresponding to this frame.
|
|
const Code& code;
|
|
|
|
// Offset into the code object corresponding to this frame.
|
|
//
|
|
// Will be set to |kFutureListenerPcOffset| if this frame corresponds to
|
|
// future listener that is not yet executing.
|
|
uword pc_offset;
|
|
|
|
// Closure corresponding to the awaiter frame or |null| if this is
|
|
// a synchronous frame or a gap.
|
|
const Closure& closure;
|
|
};
|
|
|
|
// Returns |true| if this function is needed to correctly unwind through
|
|
// awaiter chains. This means AOT compiler should retain |Function| object,
|
|
// its signature and the corresponding |Code| object (so that we could
|
|
// perform the reverse lookup).
|
|
static bool IsNeededForAsyncAwareUnwinding(const Function& function);
|
|
|
|
// Returns |true| if the given class might serve as an awaiter-link when
|
|
// unwinding an awaiter chain.
|
|
//
|
|
// This is used to eagerly mark tear-offs of methods on this class
|
|
// as having an awaiter-link.
|
|
static bool IsPossibleAwaiterLink(const Class& cls);
|
|
|
|
/// Collects all frames on the current stack until an async/async* frame is
|
|
/// hit which has yielded before (i.e. is not in sync-async case).
|
|
///
|
|
/// From there on finds the closure of the async/async* frame and starts
|
|
/// traversing the listeners.
|
|
static void CollectFrames(
|
|
Thread* thread,
|
|
int skip_frames,
|
|
const std::function<void(const Frame&)>& handle_frame,
|
|
bool* has_async_catch_error = nullptr);
|
|
|
|
// If |closure| has an awaiter-link pointing to the |SuspendState|
|
|
// the return that object.
|
|
static bool GetSuspendState(const Closure& closure, Object* suspend_state);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_STACK_TRACE_H_
|