OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "lib/stacktrace.h" | 5 #include "lib/stacktrace.h" |
6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
7 #include "vm/debugger.h" | 7 #include "vm/debugger.h" |
8 #include "vm/exceptions.h" | 8 #include "vm/exceptions.h" |
9 #include "vm/native_entry.h" | 9 #include "vm/native_entry.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 // Collect the frames. | 34 // Collect the frames. |
35 const intptr_t collected_frames_count = StackTraceUtils::CollectFrames( | 35 const intptr_t collected_frames_count = StackTraceUtils::CollectFrames( |
36 thread, code_array, pc_offset_array, 0, stack_trace_length, skip_frames); | 36 thread, code_array, pc_offset_array, 0, stack_trace_length, skip_frames); |
37 | 37 |
38 ASSERT(collected_frames_count == stack_trace_length); | 38 ASSERT(collected_frames_count == stack_trace_length); |
39 | 39 |
40 return StackTrace::New(code_array, pc_offset_array); | 40 return StackTrace::New(code_array, pc_offset_array); |
41 } | 41 } |
42 | 42 |
43 | |
44 static RawStackTrace* CurrentStackTrace( | 43 static RawStackTrace* CurrentStackTrace( |
45 Thread* thread, | 44 Thread* thread, |
46 bool for_async_function, | 45 bool for_async_function, |
47 intptr_t skip_frames = 1, | 46 intptr_t skip_frames = 1, |
48 bool causal_async_stacks = FLAG_causal_async_stacks) { | 47 bool causal_async_stacks = FLAG_causal_async_stacks) { |
49 if (!causal_async_stacks) { | 48 if (!causal_async_stacks) { |
50 // Return the synchronous stack trace. | 49 // Return the synchronous stack trace. |
51 return CurrentSyncStackTrace(thread, skip_frames); | 50 return CurrentSyncStackTrace(thread, skip_frames); |
52 } | 51 } |
53 | 52 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 thread, code_array, pc_offset_array, write_cursor, | 90 thread, code_array, pc_offset_array, write_cursor, |
92 synchronous_stack_trace_length, skip_frames); | 91 synchronous_stack_trace_length, skip_frames); |
93 | 92 |
94 write_cursor += collected_frames_count; | 93 write_cursor += collected_frames_count; |
95 | 94 |
96 ASSERT(write_cursor == capacity); | 95 ASSERT(write_cursor == capacity); |
97 | 96 |
98 return StackTrace::New(code_array, pc_offset_array, async_stack_trace); | 97 return StackTrace::New(code_array, pc_offset_array, async_stack_trace); |
99 } | 98 } |
100 | 99 |
101 | |
102 RawStackTrace* GetStackTraceForException() { | 100 RawStackTrace* GetStackTraceForException() { |
103 Thread* thread = Thread::Current(); | 101 Thread* thread = Thread::Current(); |
104 return CurrentStackTrace(thread, false, 0); | 102 return CurrentStackTrace(thread, false, 0); |
105 } | 103 } |
106 | 104 |
107 | |
108 DEFINE_NATIVE_ENTRY(StackTrace_current, 0) { | 105 DEFINE_NATIVE_ENTRY(StackTrace_current, 0) { |
109 return CurrentStackTrace(thread, false); | 106 return CurrentStackTrace(thread, false); |
110 } | 107 } |
111 | 108 |
112 | |
113 DEFINE_NATIVE_ENTRY(StackTrace_asyncStackTraceHelper, 1) { | 109 DEFINE_NATIVE_ENTRY(StackTrace_asyncStackTraceHelper, 1) { |
114 GET_NATIVE_ARGUMENT(Closure, async_op, arguments->NativeArgAt(0)); | 110 GET_NATIVE_ARGUMENT(Closure, async_op, arguments->NativeArgAt(0)); |
115 if (!async_op.IsNull()) { | 111 if (!async_op.IsNull()) { |
116 if (FLAG_support_debugger) { | 112 if (FLAG_support_debugger) { |
117 Debugger* debugger = isolate->debugger(); | 113 Debugger* debugger = isolate->debugger(); |
118 if (debugger != NULL) { | 114 if (debugger != NULL) { |
119 debugger->MaybeAsyncStepInto(async_op); | 115 debugger->MaybeAsyncStepInto(async_op); |
120 } | 116 } |
121 } | 117 } |
122 } | 118 } |
123 return CurrentStackTrace(thread, true); | 119 return CurrentStackTrace(thread, true); |
124 } | 120 } |
125 | 121 |
126 | |
127 DEFINE_NATIVE_ENTRY(StackTrace_clearAsyncThreadStackTrace, 0) { | 122 DEFINE_NATIVE_ENTRY(StackTrace_clearAsyncThreadStackTrace, 0) { |
128 thread->clear_async_stack_trace(); | 123 thread->clear_async_stack_trace(); |
129 return Object::null(); | 124 return Object::null(); |
130 } | 125 } |
131 | 126 |
132 | |
133 DEFINE_NATIVE_ENTRY(StackTrace_setAsyncThreadStackTrace, 1) { | 127 DEFINE_NATIVE_ENTRY(StackTrace_setAsyncThreadStackTrace, 1) { |
134 GET_NON_NULL_NATIVE_ARGUMENT(StackTrace, stack_trace, | 128 GET_NON_NULL_NATIVE_ARGUMENT(StackTrace, stack_trace, |
135 arguments->NativeArgAt(0)); | 129 arguments->NativeArgAt(0)); |
136 thread->set_async_stack_trace(stack_trace); | 130 thread->set_async_stack_trace(stack_trace); |
137 return Object::null(); | 131 return Object::null(); |
138 } | 132 } |
139 | 133 |
140 | |
141 static void AppendFrames(const GrowableObjectArray& code_list, | 134 static void AppendFrames(const GrowableObjectArray& code_list, |
142 const GrowableObjectArray& pc_offset_list, | 135 const GrowableObjectArray& pc_offset_list, |
143 int skip_frames) { | 136 int skip_frames) { |
144 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, | 137 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames, |
145 Thread::Current(), | 138 Thread::Current(), |
146 StackFrameIterator::kNoCrossThreadIteration); | 139 StackFrameIterator::kNoCrossThreadIteration); |
147 StackFrame* frame = frames.NextFrame(); | 140 StackFrame* frame = frames.NextFrame(); |
148 ASSERT(frame != NULL); // We expect to find a dart invocation frame. | 141 ASSERT(frame != NULL); // We expect to find a dart invocation frame. |
149 Code& code = Code::Handle(); | 142 Code& code = Code::Handle(); |
150 Smi& offset = Smi::Handle(); | 143 Smi& offset = Smi::Handle(); |
151 while (frame != NULL) { | 144 while (frame != NULL) { |
152 if (frame->IsDartFrame()) { | 145 if (frame->IsDartFrame()) { |
153 if (skip_frames > 0) { | 146 if (skip_frames > 0) { |
154 skip_frames--; | 147 skip_frames--; |
155 } else { | 148 } else { |
156 code = frame->LookupDartCode(); | 149 code = frame->LookupDartCode(); |
157 offset = Smi::New(frame->pc() - code.PayloadStart()); | 150 offset = Smi::New(frame->pc() - code.PayloadStart()); |
158 code_list.Add(code); | 151 code_list.Add(code); |
159 pc_offset_list.Add(offset); | 152 pc_offset_list.Add(offset); |
160 } | 153 } |
161 } | 154 } |
162 frame = frames.NextFrame(); | 155 frame = frames.NextFrame(); |
163 } | 156 } |
164 } | 157 } |
165 | 158 |
166 | |
167 // Creates a StackTrace object from the current stack. | 159 // Creates a StackTrace object from the current stack. |
168 // | 160 // |
169 // Skips the first skip_frames Dart frames. | 161 // Skips the first skip_frames Dart frames. |
170 const StackTrace& GetCurrentStackTrace(int skip_frames) { | 162 const StackTrace& GetCurrentStackTrace(int skip_frames) { |
171 const GrowableObjectArray& code_list = | 163 const GrowableObjectArray& code_list = |
172 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 164 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
173 const GrowableObjectArray& pc_offset_list = | 165 const GrowableObjectArray& pc_offset_list = |
174 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 166 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
175 AppendFrames(code_list, pc_offset_list, skip_frames); | 167 AppendFrames(code_list, pc_offset_list, skip_frames); |
176 const Array& code_array = Array::Handle(Array::MakeFixedLength(code_list)); | 168 const Array& code_array = Array::Handle(Array::MakeFixedLength(code_list)); |
177 const Array& pc_offset_array = | 169 const Array& pc_offset_array = |
178 Array::Handle(Array::MakeFixedLength(pc_offset_list)); | 170 Array::Handle(Array::MakeFixedLength(pc_offset_list)); |
179 const StackTrace& stacktrace = | 171 const StackTrace& stacktrace = |
180 StackTrace::Handle(StackTrace::New(code_array, pc_offset_array)); | 172 StackTrace::Handle(StackTrace::New(code_array, pc_offset_array)); |
181 return stacktrace; | 173 return stacktrace; |
182 } | 174 } |
183 | 175 |
184 } // namespace dart | 176 } // namespace dart |
OLD | NEW |