Chromium Code Reviews| Index: runtime/vm/stack_trace.cc |
| diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ee7ba3be339b7e20caa20efe9f915c8de41ce3bf |
| --- /dev/null |
| +++ b/runtime/vm/stack_trace.cc |
| @@ -0,0 +1,113 @@ |
| +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
|
siva
2017/01/26 19:26:23
2017
Cutch
2017/01/31 23:45:31
Done.
|
| +// 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. |
| + |
| +#include "vm/stack_frame.h" |
| +#include "vm/stack_trace.h" |
| + |
| +namespace dart { |
| + |
| +// Count the number of frames that are on the stack. |
| +intptr_t StackTraceUtils::CountFrames(int skip_frames, |
| + const Function& async_function, |
| + bool count_invisible_frames) { |
| + intptr_t frame_count = 0; |
| + StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| + StackFrame* frame = frames.NextFrame(); |
| + ASSERT(frame != NULL); // We expect to find a dart invocation frame. |
| + Code& code = Code::Handle(); |
| + Function& function = Function::Handle(); |
| + const bool async_function_is_null = async_function.IsNull(); |
| + while (frame != NULL) { |
| + if (frame->IsDartFrame()) { |
| + if (skip_frames > 0) { |
| + skip_frames--; |
| + } else { |
| + code = frame->LookupDartCode(); |
| + function = code.function(); |
| + if (function.is_visible() || count_invisible_frames) { |
| + frame_count++; |
| + } |
| + if (!async_function_is_null && |
| + (async_function.raw() == function.parent_function())) { |
| + // We have hit the sentinel, stop. |
| + break; |
|
siva
2017/01/26 19:26:23
can this be a return here, that is
return frame_co
Cutch
2017/01/31 23:45:31
Done.
|
| + } |
| + } |
| + } |
| + frame = frames.NextFrame(); |
| + } |
| + // We hit the sentinel. |
| + ASSERT(async_function_is_null || |
| + (async_function.raw() == function.parent_function())); |
| + return frame_count; |
| +} |
| + |
| + |
| +intptr_t StackTraceUtils::CollectFrames(const Array& code_array, |
| + const Array& pc_offset_array, |
| + intptr_t array_offset, |
| + intptr_t count, |
| + int skip_frames, |
| + bool collect_invisible_frames) { |
| + StackFrameIterator frames(StackFrameIterator::kDontValidateFrames); |
| + StackFrame* frame = frames.NextFrame(); |
| + ASSERT(frame != NULL); // We expect to find a dart invocation frame. |
| + Function& function = Function::Handle(); |
| + Code& code = Code::Handle(); |
| + Smi& offset = Smi::Handle(); |
|
siva
2017/01/26 19:26:23
I am assuming these functions are going to be call
Cutch
2017/01/31 23:45:31
Done.
|
| + intptr_t collected_frames_count = 0; |
| + while ((frame != NULL) && (count > 0)) { |
| + if (frame->IsDartFrame()) { |
| + if (skip_frames > 0) { |
| + skip_frames--; |
| + } else { |
| + code = frame->LookupDartCode(); |
| + function = code.function(); |
| + if (function.is_visible() || collect_invisible_frames) { |
| + offset = Smi::New(frame->pc() - code.PayloadStart()); |
| + code_array.SetAt(array_offset, code); |
| + pc_offset_array.SetAt(array_offset, offset); |
| + array_offset++; |
| + collected_frames_count++; |
| + count--; |
|
siva
2017/01/26 19:26:23
Why decrement an input parameter 'count' here, why
Cutch
2017/01/31 23:45:31
Done.
|
| + } |
| + } |
| + } |
| + frame = frames.NextFrame(); |
| + } |
| + return collected_frames_count; |
| +} |
| + |
| + |
| +intptr_t StackTraceUtils::ExtractAsyncStackTraceInfo( |
| + Thread* thread, |
| + Function* async_function, |
| + Array* async_code_array, |
| + Array* async_pc_offset_array) { |
| + if (thread->async_stack_trace() == StackTrace::null()) { |
| + return 0; |
| + } |
| + const StackTrace& async_stack_trace = |
| + StackTrace::Handle(thread->async_stack_trace()); |
| + const intptr_t async_stack_trace_length = async_stack_trace.Length(); |
| + // At least two entries (0: gap marker, 1: async function). |
| + ASSERT(async_stack_trace_length >= 2); |
| + // Validate the structure of this stack trace. |
| + *async_code_array = async_stack_trace.code_array(); |
| + ASSERT(!async_code_array->IsNull()); |
| + *async_pc_offset_array = async_stack_trace.pc_offset_array(); |
| + ASSERT(!async_pc_offset_array->IsNull()); |
| + // We start with the asynchronous gap marker. |
| + ASSERT(async_code_array->At(0) != Code::null()); |
| + ASSERT(async_code_array->At(0) == |
| + StubCode::AsynchronousGapMarker_entry()->code()); |
| + const Code& code = Code::Handle(Code::RawCast(async_code_array->At(1))); |
| + *async_function = code.function(); |
| + ASSERT(!async_function->IsNull()); |
| + ASSERT(async_function->IsAsyncFunction() || |
| + async_function->IsAsyncGenerator()); |
| + return async_stack_trace_length; |
| +} |
| + |
| +} // namespace dart |