Flutter Engine
The Flutter Engine
stacktrace.cc
Go to the documentation of this file.
1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "lib/stacktrace.h"
7#include "vm/debugger.h"
8#include "vm/exceptions.h"
9#include "vm/native_entry.h"
10#include "vm/object_store.h"
11#include "vm/runtime_entry.h"
12#include "vm/stack_frame.h"
13#include "vm/stack_trace.h"
14
15namespace dart {
16
17DECLARE_FLAG(bool, show_invisible_frames);
18
19static constexpr intptr_t kDefaultStackAllocation = 8;
20
21static StackTracePtr CreateStackTraceObject(
22 Zone* zone,
23 const GrowableObjectArray& code_list,
24 const GrowableArray<uword>& pc_offset_list) {
25 const auto& code_array =
26 Array::Handle(zone, Array::MakeFixedLength(code_list));
27 const auto& pc_offset_array = TypedData::Handle(
28 zone, TypedData::New(kUintPtrCid, pc_offset_list.length()));
29 {
30 NoSafepointScope no_safepoint;
31 memmove(pc_offset_array.DataAddr(0), pc_offset_list.data(),
32 pc_offset_list.length() * kWordSize);
33 }
34 return StackTrace::New(code_array, pc_offset_array);
35}
36
37// Gets current stack trace for `thread`.
38static StackTracePtr CurrentStackTrace(Thread* thread,
39 intptr_t skip_frames = 1) {
40 Zone* zone = thread->zone();
41
42 const auto& code_array = GrowableObjectArray::ZoneHandle(
45
46 // Collect the frames.
47 StackTraceUtils::CollectFrames(thread, skip_frames,
48 [&](const StackTraceUtils::Frame& frame) {
49 code_array.Add(frame.code);
50 pc_offset_array.Add(frame.pc_offset);
51 });
52
53 return CreateStackTraceObject(zone, code_array, pc_offset_array);
54}
55
57 Thread* thread = Thread::Current();
58 return CurrentStackTrace(thread, 0);
59}
60
61DEFINE_NATIVE_ENTRY(StackTrace_current, 0, 0) {
62 return CurrentStackTrace(thread);
63}
64
65static void AppendFrames(const GrowableObjectArray& code_list,
66 GrowableArray<uword>* pc_offset_list,
67 int skip_frames) {
68 Thread* thread = Thread::Current();
69 Zone* zone = thread->zone();
72 StackFrame* frame = frames.NextFrame();
73 ASSERT(frame != nullptr); // We expect to find a dart invocation frame.
74 Code& code = Code::Handle(zone);
75 for (; frame != nullptr; frame = frames.NextFrame()) {
76 if (!frame->IsDartFrame()) {
77 continue;
78 }
79 if (skip_frames > 0) {
80 skip_frames--;
81 continue;
82 }
83
84 code = frame->LookupDartCode();
85 const intptr_t pc_offset = frame->pc() - code.PayloadStart();
86 code_list.Add(code);
87 pc_offset_list->Add(pc_offset);
88 }
89}
90
91// Creates a StackTrace object from the current stack.
92//
93// Skips the first skip_frames Dart frames.
94const StackTrace& GetCurrentStackTrace(int skip_frames) {
95 Zone* zone = Thread::Current()->zone();
96 const GrowableObjectArray& code_list =
98 GrowableArray<uword> pc_offset_list;
99 AppendFrames(code_list, &pc_offset_list, skip_frames);
100
101 const StackTrace& stacktrace = StackTrace::Handle(
102 zone, CreateStackTraceObject(zone, code_list, pc_offset_list));
103 return stacktrace;
104}
105
106bool HasStack() {
107 Thread* thread = Thread::Current();
110 StackFrame* frame = frames.NextFrame();
111 return frame != nullptr;
112}
113
114} // namespace dart
static ArrayPtr MakeFixedLength(const GrowableObjectArray &growable_array, bool unique=false)
Definition: object.cc:24935
void Add(const T &value)
intptr_t length() const
void Add(const Object &value, Heap::Space space=Heap::kNew) const
Definition: object.cc:24991
static GrowableObjectArrayPtr New(Heap::Space space=Heap::kNew)
Definition: object.h:11144
static Object & Handle()
Definition: object.h:407
static Object & ZoneHandle()
Definition: object.h:419
StackFrame * NextFrame()
Definition: stack_frame.cc:549
static void CollectFrames(Thread *thread, int skip_frames, const std::function< void(const Frame &)> &handle_frame, bool *has_async_catch_error=nullptr)
Definition: stack_trace.cc:745
static StackTracePtr New(const Array &code_array, const TypedData &pc_offset_array, Heap::Space space=Heap::kNew)
Definition: object.cc:26069
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
static TypedDataPtr New(intptr_t class_id, intptr_t len, Heap::Space space=Heap::kNew)
Definition: object.cc:25587
#define ASSERT(E)
double frame
Definition: examples.cpp:31
Definition: dart_vm.cc:33
StackTracePtr GetStackTraceForException()
Definition: stacktrace.cc:56
static void AppendFrames(const GrowableObjectArray &code_list, GrowableArray< uword > *pc_offset_list, int skip_frames)
Definition: stacktrace.cc:65
static constexpr intptr_t kDefaultStackAllocation
Definition: stacktrace.cc:19
static StackTracePtr CurrentStackTrace(Thread *thread, intptr_t skip_frames=1)
Definition: stacktrace.cc:38
bool HasStack()
Definition: stacktrace.cc:106
DEFINE_NATIVE_ENTRY(List_allocate, 0, 2)
Definition: array.cc:13
constexpr intptr_t kWordSize
Definition: globals.h:509
const StackTrace & GetCurrentStackTrace(int skip_frames)
Definition: stacktrace.cc:94
static StackTracePtr CreateStackTraceObject(Zone *zone, const GrowableObjectArray &code_list, const GrowableArray< uword > &pc_offset_list)
Definition: stacktrace.cc:21
DECLARE_FLAG(bool, show_invisible_frames)