32 print_stacktrace_at_throw,
34 "Prints a stack trace everytime a throw occurs.");
63 intptr_t dropped_frames_;
74 intptr_t null_slot =
start - 2;
88 intptr_t
prev = (
i - 1);
109 if (!
frame->IsDartFrame()) {
133 if (
frame ==
nullptr)
return false;
134 handler_pc_set_ =
false;
136 bool is_catch_all =
false;
138 bool is_optimized =
false;
142 while (!
frame->IsEntryFrame()) {
143 if (
frame->IsDartFrame()) {
144 if (
frame->FindExceptionHandler(thread_, &temp_handler_pc,
147 if (!handler_pc_set_) {
148 handler_pc_set_ =
true;
154 StubCode::AsyncExceptionHandler().EntryPoint())) {
158 catch_entry_moves_cache_->
Lookup(pc_);
159 if (cached_catch_entry_moves !=
nullptr) {
160 cached_catch_entry_moves_ = *cached_catch_entry_moves;
162 if (cached_catch_entry_moves_.
IsEmpty()) {
163#if defined(DART_PRECOMPILED_RUNTIME)
165 ReadCompressedCatchEntryMoves();
166#elif defined(DART_PRECOMPILER)
168 if (FLAG_precompiled_mode) {
169 ReadCompressedCatchEntryMoves();
175 ASSERT(!FLAG_precompiled_mode);
190 if (!handler_pc_set_) {
197 return handler_pc_set_;
208 if (cached_catch_entry_moves_.
IsEmpty()) {
209 catch_entry_moves_cache_->
Insert(
212 catch_entry_moves_ = &cached_catch_entry_moves_.
moves();
225 for (
int j = 0; j < moves.
count(); j++) {
230 if (
pool ==
nullptr) {
289 for (
int j = 0; j < moves.
count(); j++) {
291 *TaggedSlotAt(
fp, move.
dest_slot()) = dst_values[j]->ptr();
312#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
313 void ReadCompressedCatchEntryMoves() {
318 catch_entry_moves_ = reader.ReadMovesForPcOffset(pc_offset);
322#if !defined(DART_PRECOMPILED_RUNTIME)
327 nullptr,
true,
false );
333 delete deopt_context;
343 template <
typename T>
344 static T* SlotAt(
uword fp,
int stack_slot) {
345 const intptr_t frame_slot =
347 return reinterpret_cast<T*
>(
fp + frame_slot *
kWordSize);
351 return SlotAt<ObjectPtr>(
fp, stack_slot);
354 typedef ReadStream::Raw<
sizeof(intptr_t), intptr_t> Reader;
357 bool handler_pc_set_;
360 const CatchEntryMoves* catch_entry_moves_ =
nullptr;
362 CatchEntryMovesRefPtr cached_catch_entry_moves_;
372#if !defined(DART_PRECOMPILED_RUNTIME)
375 Writer::Write(
stream, src_);
376 Writer::Write(
stream, dest_and_kind_);
380#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
464 while (
stream.PendingBytes() > 0) {
465 const intptr_t stream_position =
stream.Position();
469 const intptr_t
length = prefix_length + suffix_length;
471 for (intptr_t j = 0; j < prefix_length; j++) {
478 &inner_stream, stream_position,
length);
479 THR_Print(
" [code+0x%08" Px "]: (% " Pd " moves)\n", target_pc_offset,
481 for (intptr_t
i = 0;
i < moves->
count();
i++) {
490 intptr_t pc_offset) {
495 intptr_t position = 0;
499 return ReadCompressedCatchEntryMovesSuffix(&
stream, position,
length);
508 while (
stream->PendingBytes() > 0) {
509 const intptr_t stream_position =
stream->Position();
514 if (pc_offset == target_pc_offset) {
515 *position = stream_position;
516 *
length = prefix_length + suffix_length;
521 for (intptr_t j = 0; j < prefix_length; j++) {
529CatchEntryMoves* CatchEntryMovesMapReader::ReadCompressedCatchEntryMovesSuffix(
533 using Reader = ReadStream::Raw<
sizeof(intptr_t), intptr_t>;
537 intptr_t remaining_length =
length;
539 intptr_t moves_offset = 0;
540 while (remaining_length > 0) {
546 const intptr_t to_read = remaining_length - suffix_length;
548 for (
int j = 0; j < to_read; j++) {
550 moves->At(moves_offset + to_read - j - 1) =
553 remaining_length -= to_read;
554 moves_offset += to_read;
570 while (!
frame->IsEntryFrame()) {
575 *handler_pc =
frame->pc();
576 *handler_sp =
frame->sp();
577 *handler_fp =
frame->fp();
590 if (
frame->fp() >= frame_pointer) {
593 if (
frame->IsMarkedForLazyDeopt()) {
594 frame->UnmarkForLazyDeopt();
613 uword program_counter,
616 const Object& exception_object,
617 const Object& stacktrace_object) {
618 bool clear_deopt =
false;
620 program_counter, frame_pointer, &clear_deopt);
624 uword run_exception_pc = StubCode::RunExceptionHandler().EntryPoint();
626 frame_pointer, clear_deopt);
632 uword program_counter,
635 bool clear_deopt_at_target) {
637 const uword fp_for_clearing =
638 (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer);
641#if defined(USING_SIMULATOR)
651 frame_pointer, thread);
661 stack_pointer - current_sp);
665#if defined(USING_SAFE_STACK)
666 const uword saved_ssp = thread->saved_safestack_limit();
667 OSThread::SetCurrentSafestackPointer(saved_ssp);
670#if defined(USING_SHADOW_CALL_STACK)
674#if defined(USING_THREAD_SANITIZER)
676 auto tsan_utils = thread->tsan_utils();
677 tsan_utils->exception_pc = program_counter;
678 tsan_utils->exception_sp = stack_pointer;
679 tsan_utils->exception_fp = frame_pointer;
680 longjmp(*(tsan_utils->setjmp_buffer), 1);
689 reinterpret_cast<ExcpHandler
>(StubCode::JumpToFrame().EntryPoint());
694 func(program_counter, stack_pointer, frame_pointer, thread);
708 const auto& error_class =
709 Class::Handle(zone, isolate_group->object_store()->error_class());
714 if (test_class.
ptr() == error_class.ptr()) {
715 return error_class.LookupInstanceFieldAllowPrivate(
716 Symbols::_stackTrace());
720 test_class =
type.type_class();
733 const Instance& existing_stacktrace,
734 const bool is_rethrow,
735 const bool bypass_debugger) {
744 if (!bypass_debugger) {
748 if (incoming_exception.
ptr() != object_store->out_of_memory() &&
749 incoming_exception.
ptr() != object_store->stack_overflow()) {
754 bool use_preallocated_stacktrace =
false;
759 args.SetAt(0, Symbols::OptimizedOut());
760 args.SetAt(1, line_col);
761 args.SetAt(2, line_col);
764 }
else if (existing_stacktrace.
IsNull() &&
765 (exception.
ptr() == object_store->out_of_memory() ||
766 exception.
ptr() == object_store->stack_overflow())) {
767 use_preallocated_stacktrace =
true;
772 bool handler_exists = finder.
Find();
778 if (use_preallocated_stacktrace) {
779 if (handler_pc == 0) {
781 ASSERT(incoming_exception.
ptr() == object_store->out_of_memory());
791 (existing_stacktrace.
ptr() == stacktrace.
ptr()));
793 if (handler_needs_stacktrace && existing_stacktrace.
IsNull()) {
797 if (!existing_stacktrace.
IsNull()) {
798 stacktrace = existing_stacktrace.
ptr();
802 const Field& stacktrace_field =
804 if (!stacktrace_field.
IsNull() &&
806 exception.
SetField(stacktrace_field, stacktrace);
812 const Field& stacktrace_field =
814 if (!stacktrace_field.
IsNull() || handler_needs_stacktrace) {
820 if (!stacktrace_field.
IsNull() &&
822 exception.
SetField(stacktrace_field, stacktrace);
833 if (FLAG_print_stacktrace_at_throw) {
837 if (handler_exists) {
841 exception, stacktrace);
852 zone, exception.
ptr() == object_store->out_of_memory()
854 ->preallocated_unhandled_exception()
858 unhandled_exception, stacktrace);
871#if defined(DART_PRECOMPILED_RUNTIME)
911 zone,
script.IsNull() ? Symbols::OptimizedOut().ptr() :
script.url());
913 intptr_t column = -1;
915 script.GetTokenLocation(location, &
line, &column);
929 pieces.
Add(Symbols::TypeQuote());
931 pieces.
Add(Symbols::QuoteIsNotASubtypeOf());
933 pieces.
Add(Symbols::TypeQuote());
936 if (dst_name.
Length() > 0) {
937 if (dst_name.
ptr() == Symbols::InTypeCast().ptr()) {
938 pieces.
Add(dst_name);
940 pieces.
Add(Symbols::SpaceOfSpace());
942 pieces.
Add(dst_name);
955 const String& formatted_uris =
957 if (formatted_uris.
Length() > 0) {
958 pieces.
Add(Symbols::SpaceWhereNewLine());
959 pieces.
Add(formatted_uris);
964 args.SetAt(3, error_msg);
968 if (FLAG_print_stacktrace_at_throw) {
969 THR_Print(
"'%s': Failed type check: line %" Pd " pos %" Pd ": ",
989 bool bypass_debugger ) {
1011 if (
error.IsUnhandledException()) {
1022 uword handler_pc = 0;
1023 uword handler_sp = 0;
1024 uword handler_fp = 0;
1037 if (
error.IsUnhandledException()) {
1043 uword handler_pc = 0;
1044 uword handler_sp = 0;
1045 uword handler_fp = 0;
1068 auto isolate_group = thread->isolate_group();
1070 thread->zone(), isolate_group->object_store()->out_of_memory());
1076 auto isolate_group = thread->isolate_group();
1078 thread->zone(), isolate_group->object_store()->stack_overflow());
1079 Throw(thread, stack_overflow);
1095 const Integer& argument_value,
1096 intptr_t expected_from,
1097 intptr_t expected_to) {
1099 args.SetAt(0, argument_value);
1145 constructor_name = &Symbols::DotRange();
1159 constructor_name = &Symbols::DotValue();
1167 class_name = &Symbols::IntegerDivisionByZeroException();
1172 constructor_name = &Symbols::DotWithType();
1184 class_name = &Symbols::IsolateSpawnException();
1189 constructor_name = &Symbols::DotCreate();
1194 constructor_name = &Symbols::DotCreate();
1197#if defined(DART_PRECOMPILED_RUNTIME)
1201 class_name = &Symbols::AbstractClassInstantiationError();
1202 constructor_name = &Symbols::DotCreate();
1207 class_name = &Symbols::_CyclicInitializationError();
1216 constructor_name = &Symbols::DotFieldADI();
1221 constructor_name = &Symbols::DotFieldNI();
1226 *constructor_name, arguments);
1234 args.SetAt(0, error_str);
static float prev(float f)
#define ASAN_UNPOISON(ptr, len)
#define ASSERT_EQUAL(expected, actual)
#define RELEASE_ASSERT(cond)
StringPtr UserVisibleName() const
static StringPtr PrintURIs(URIs *uris)
bool IsDynamicType() const
virtual void EnumerateURIs(URIs *uris) const
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
static ArrayPtr MakeFixedLength(const GrowableObjectArray &growable_array, bool unique=false)
intptr_t dest_slot() const
intptr_t src_hi_slot() const
const char * ToCString() const
void WriteTo(BaseWriteStream *stream)
intptr_t src_slot() const
SourceKind source_kind() const
static CatchEntryMove ReadFrom(ReadStream *stream)
intptr_t src_lo_slot() const
CatchEntryMoves * ReadMovesForPcOffset(intptr_t pc_offset)
const CatchEntryMoves & moves()
static void Free(const CatchEntryMoves *moves)
static CatchEntryMoves * Allocate(intptr_t num_moves)
CatchEntryMove & At(intptr_t i)
TypePtr super_type() const
bool is_optimized() const
ObjectPoolPtr GetObjectPool() const
intptr_t num_variables() const
uword PayloadStart() const
static ObjectPtr InstanceCreate(const Library &library, const String &exception_name, const String &constructor_name, const Array &arguments)
void PauseException(const Instance &exc)
const CatchEntryMoves * ToCatchEntryMoves(intptr_t num_vars)
static DoublePtr New(double d, Heap::Space space=Heap::kNew)
void PrepareFrameForCatchEntry()
void ExecuteCatchEntryMoves(const CatchEntryMoves &moves)
void GetCatchEntryMovesFromDeopt(intptr_t num_vars, StackFrame *frame)
ExceptionHandlerFinder(Thread *thread)
static DART_NORETURN void ThrowStateError(const Instance &arg)
static DART_NORETURN void ThrowStackOverflow()
static DART_NORETURN void JumpToFrame(Thread *thread, uword program_counter, uword stack_pointer, uword frame_pointer, bool clear_deopt_at_target)
static DART_NORETURN void ThrowByType(ExceptionType type, const Array &arguments)
static DART_NORETURN void ThrowOOM()
static DART_NORETURN void ThrowRangeError(const char *argument_name, const Integer &argument_value, intptr_t expected_from, intptr_t expected_to)
static DART_NORETURN void ThrowUnsupportedError(const char *msg)
static InstancePtr NewInstance(const char *class_name)
static DART_NORETURN void ThrowLateFieldAssignedDuringInitialization(const String &name)
static DART_NORETURN void Throw(Thread *thread, const Instance &exception)
static DART_NORETURN void ThrowArgumentError(const Instance &arg)
static DART_NORETURN void PropagateToEntry(const Error &error)
static ScriptPtr GetCallerScript(DartFrameIterator *iterator)
@ kCyclicInitializationError
@ kAbstractClassInstantiation
@ kLateFieldNotInitialized
@ kLateFieldAssignedDuringInitialization
@ kIntegerDivisionByZeroException
static StackTracePtr CurrentStackTrace()
static DART_NORETURN void ThrowLateFieldNotInitialized(const String &name)
static DART_NORETURN void ThrowCompileTimeError(const LanguageError &error)
static ObjectPtr Create(ExceptionType type, const Array &arguments)
static UnhandledExceptionPtr CreateUnhandledException(Zone *zone, ExceptionType type, const char *msg)
static DART_NORETURN void ReThrow(Thread *thread, const Instance &exception, const Instance &stacktrace, bool bypass_debugger=false)
static void CreateAndThrowTypeError(TokenPosition location, const AbstractType &src_type, const AbstractType &dst_type, const String &dst_name)
static DART_NORETURN void ThrowWithStackTrace(Thread *thread, const Instance &exception, const Instance &stacktrace)
static DART_NORETURN void PropagateError(const Error &error)
void Insert(K key, V value)
static Float32x4Ptr New(float value0, float value1, float value2, float value3, Heap::Space space=Heap::kNew)
static Float64x2Ptr New(double value0, double value1, Heap::Space space=Heap::kNew)
void Add(const Object &value, Heap::Space space=Heap::kNew) const
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
ObjectPtr GetField(const Field &field) const
void SetField(const Field &field, const Object &value) const
static InstancePtr New(const Class &cls, Heap::Space space=Heap::kNew)
static Int32x4Ptr New(int32_t value0, int32_t value1, int32_t value2, int32_t value3, Heap::Space space=Heap::kNew)
static IntegerPtr New(const String &str, Heap::Space space=Heap::kNew)
ObjectStore * object_store() const
void set_deopt_context(DeoptContext *value)
static Isolate * Current()
IsolateObjectStore * isolate_object_store() const
Debugger * debugger() const
CatchEntryMovesCache * catch_entry_moves_cache()
static LibraryPtr CoreLibrary()
static LibraryPtr MirrorsLibrary()
static LibraryPtr IsolateLibrary()
ClassPtr LookupClass(const String &name) const
static LibraryPtr InternalLibrary()
DART_NORETURN void Jump(int value, const Error &error)
static uword GetCurrentStackPointer()
virtual const char * ToCString() const
void ClearPendingDeoptsBelow(uword fp, ClearReason reason)
uword RemapExceptionPCForDeopt(uword program_counter, uword frame_pointer, bool *clear_deopt)
void AddFrame(const Object &code, uword pc_offset) override
PreallocatedStackTraceBuilder(const Instance &stacktrace)
~PreallocatedStackTraceBuilder()
void JumpToFrame(uword pc, uword sp, uword fp, Thread *thread)
static Simulator * Current()
static SmiPtr New(intptr_t value)
@ kNoCrossThreadIteration
virtual bool IsDartFrame(bool validate=true) const
FunctionPtr LookupDartFunction() const
ThreadState * thread() const
static void Unwind(ThreadState *thread)
virtual void AddFrame(const Object &code, uword pc_offset)=0
virtual ~StackTraceBuilder()
void SetPcOffsetAtFrame(intptr_t frame_index, uword pc_offset) const
void SetCodeAtFrame(intptr_t frame_index, const Object &code) const
static constexpr int kPreallocatedStackdepth
uword PcOffsetAtFrame(intptr_t frame_index) const
ObjectPtr CodeAtFrame(intptr_t frame_index) const
static StringPtr ConcatAll(const Array &strings, Heap::Space space=Heap::kNew)
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
static const char * ToCString(Thread *thread, StringPtr ptr)
static const String & SingleQuote()
static StringPtr New(Thread *thread, const char *cstr)
static const String & Dot()
LongJumpScope * long_jump_base() const
void set_active_stacktrace(const Object &value)
static Thread * Current()
PendingDeopts & pending_deopts()
void set_resume_pc(uword value)
void SetUnwindErrorInProgress(bool value)
@ kExitThroughRuntimeCall
bool is_unwind_in_progress() const
uword top_exit_frame_info() const
ExecutionState execution_state() const
Isolate * isolate() const
IsolateGroup * isolate_group() const
void set_active_exception(const Object &value)
void * DataAddr(intptr_t byte_offset) const
InstancePtr exception() const
static UnhandledExceptionPtr New(const Instance &exception, const Instance &stacktrace, Heap::Space space=Heap::kNew)
InstancePtr stacktrace() const
static int SNPrint(char *str, size_t size, const char *format,...) PRINTF_ATTRIBUTE(3
static int64_t LowHighTo64Bits(uint32_t low, int32_t high)
char * PrintToString(const char *format,...) PRINTF_ATTRIBUTE(2
#define THR_Print(format,...)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
SK_API bool Read(SkStreamSeekable *src, SkDocumentPage *dstArray, int dstArrayCount, const SkDeserialProcs *=nullptr)
static constexpr intptr_t kWordSize
StackTracePtr GetStackTraceForException()
const char *const class_name
static void ClearLazyDeopts(Thread *thread, uword frame_pointer)
constexpr uword kUwordMax
FixedCache< intptr_t, CatchEntryMovesRefPtr, 16 > CatchEntryMovesCache
static void BuildStackTrace(StackTraceBuilder *builder)
static intptr_t SlotIndexToFrameIndex(intptr_t slot)
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
FrameLayout runtime_frame_layout
static void FindErrorHandler(uword *handler_pc, uword *handler_sp, uword *handler_fp)
static FieldPtr LookupStackTraceField(const Instance &instance)
static intptr_t SlotIndexToFpRelativeOffset(intptr_t slot)
constexpr intptr_t kWordSize
static DART_NORETURN void ThrowExceptionHelper(Thread *thread, const Instance &incoming_exception, const Instance &existing_stacktrace, const bool is_rethrow, const bool bypass_debugger)
static void JumpToExceptionHandler(Thread *thread, uword program_counter, uword stack_pointer, uword frame_pointer, const Object &exception_object, const Object &stacktrace_object)
DECLARE_FLAG(bool, show_invisible_frames)
#define NO_SANITIZE_SAFE_STACK
intptr_t FrameSlotForVariableIndex(intptr_t index) const
#define ARRAY_SIZE(array)