Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: runtime/vm/stack_trace.cc

Issue 2646443005: Track async causal stack traces (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/stack_trace.h ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2017, 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 "vm/stack_frame.h"
6 #include "vm/stack_trace.h"
7
8 namespace dart {
9
10 // Count the number of frames that are on the stack.
11 intptr_t StackTraceUtils::CountFrames(Thread* thread,
12 int skip_frames,
13 const Function& async_function,
14 bool count_invisible_frames) {
15 Zone* zone = thread->zone();
16 intptr_t frame_count = 0;
17 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
18 StackFrame* frame = frames.NextFrame();
19 ASSERT(frame != NULL); // We expect to find a dart invocation frame.
20 Code& code = Code::Handle(zone);
21 Function& function = Function::Handle(zone);
22 const bool async_function_is_null = async_function.IsNull();
23 while (frame != NULL) {
24 if (frame->IsDartFrame()) {
25 if (skip_frames > 0) {
26 skip_frames--;
27 } else {
28 code = frame->LookupDartCode();
29 function = code.function();
30 if (function.is_visible() || count_invisible_frames) {
31 frame_count++;
32 }
33 if (!async_function_is_null &&
34 (async_function.raw() == function.parent_function())) {
35 return frame_count;
36 }
37 }
38 }
39 frame = frames.NextFrame();
40 }
41 // We hit the sentinel.
42 ASSERT(async_function_is_null);
43 return frame_count;
44 }
45
46
47 intptr_t StackTraceUtils::CollectFrames(Thread* thread,
48 const Array& code_array,
49 const Array& pc_offset_array,
50 intptr_t array_offset,
51 intptr_t count,
52 int skip_frames,
53 bool collect_invisible_frames) {
54 Zone* zone = thread->zone();
55 StackFrameIterator frames(StackFrameIterator::kDontValidateFrames);
56 StackFrame* frame = frames.NextFrame();
57 ASSERT(frame != NULL); // We expect to find a dart invocation frame.
58 Function& function = Function::Handle(zone);
59 Code& code = Code::Handle(zone);
60 Smi& offset = Smi::Handle(zone);
61 intptr_t collected_frames_count = 0;
62 while ((frame != NULL) && (collected_frames_count < count)) {
63 if (frame->IsDartFrame()) {
64 if (skip_frames > 0) {
65 skip_frames--;
66 } else {
67 code = frame->LookupDartCode();
68 function = code.function();
69 if (function.is_visible() || collect_invisible_frames) {
70 offset = Smi::New(frame->pc() - code.PayloadStart());
71 code_array.SetAt(array_offset, code);
72 pc_offset_array.SetAt(array_offset, offset);
73 array_offset++;
74 collected_frames_count++;
75 }
76 }
77 }
78 frame = frames.NextFrame();
79 }
80 return collected_frames_count;
81 }
82
83
84 intptr_t StackTraceUtils::ExtractAsyncStackTraceInfo(
85 Thread* thread,
86 Function* async_function,
87 StackTrace* async_stack_trace_out,
88 Array* async_code_array,
89 Array* async_pc_offset_array) {
90 if (thread->async_stack_trace() == StackTrace::null()) {
91 return 0;
92 }
93 *async_stack_trace_out = thread->async_stack_trace();
94 ASSERT(!async_stack_trace_out->IsNull());
95 const StackTrace& async_stack_trace =
96 StackTrace::Handle(thread->async_stack_trace());
97 const intptr_t async_stack_trace_length = async_stack_trace.Length();
98 // At least two entries (0: gap marker, 1: async function).
99 ASSERT(async_stack_trace_length >= 2);
100 // Validate the structure of this stack trace.
101 *async_code_array = async_stack_trace.code_array();
102 ASSERT(!async_code_array->IsNull());
103 *async_pc_offset_array = async_stack_trace.pc_offset_array();
104 ASSERT(!async_pc_offset_array->IsNull());
105 // We start with the asynchronous gap marker.
106 ASSERT(async_code_array->At(0) != Code::null());
107 ASSERT(async_code_array->At(0) ==
108 StubCode::AsynchronousGapMarker_entry()->code());
109 const Code& code = Code::Handle(Code::RawCast(async_code_array->At(1)));
110 *async_function = code.function();
111 ASSERT(!async_function->IsNull());
112 ASSERT(async_function->IsAsyncFunction() ||
113 async_function->IsAsyncGenerator());
114 return async_stack_trace_length;
115 }
116
117 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/stack_trace.h ('k') | runtime/vm/stub_code.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698