| 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 |