OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 5 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 | 9 |
10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
158 AllocationContext AllocationContextTracker::GetContextSnapshot() { | 158 AllocationContext AllocationContextTracker::GetContextSnapshot() { |
159 AllocationContext ctx; | 159 AllocationContext ctx; |
160 | 160 |
161 if (ignore_scope_depth_) { | 161 if (ignore_scope_depth_) { |
162 ctx.backtrace.frames[0] = StackFrame::FromTraceEventName(kTracingOverhead); | 162 ctx.backtrace.frames[0] = StackFrame::FromTraceEventName(kTracingOverhead); |
163 ctx.type_name = kTracingOverhead; | 163 ctx.type_name = kTracingOverhead; |
164 ctx.backtrace.frame_count = 1; | 164 ctx.backtrace.frame_count = 1; |
165 return ctx; | 165 return ctx; |
166 } | 166 } |
167 | 167 |
168 // Ignore reentrancy during the call. | |
169 ignore_scope_depth_++; | |
170 | |
168 CaptureMode mode = static_cast<CaptureMode>( | 171 CaptureMode mode = static_cast<CaptureMode>( |
169 subtle::NoBarrier_Load(&capture_mode_)); | 172 subtle::NoBarrier_Load(&capture_mode_)); |
170 | 173 |
171 auto backtrace = std::begin(ctx.backtrace.frames); | 174 auto backtrace = std::begin(ctx.backtrace.frames); |
172 auto backtrace_end = std::end(ctx.backtrace.frames); | 175 auto backtrace_end = std::end(ctx.backtrace.frames); |
173 | 176 |
174 if (!thread_name_) { | 177 if (!thread_name_) { |
175 // Ignore the string allocation made by GetAndLeakThreadName to avoid | |
176 // reentrancy. | |
177 ignore_scope_depth_++; | |
178 thread_name_ = GetAndLeakThreadName(); | 178 thread_name_ = GetAndLeakThreadName(); |
179 ANNOTATE_LEAKING_OBJECT_PTR(thread_name_); | 179 ANNOTATE_LEAKING_OBJECT_PTR(thread_name_); |
180 DCHECK(thread_name_); | 180 DCHECK(thread_name_); |
181 ignore_scope_depth_--; | |
182 } | 181 } |
183 | 182 |
184 // Add the thread name as the first entry in pseudo stack. | 183 // Add the thread name as the first entry in pseudo stack. |
185 if (thread_name_) { | 184 if (thread_name_) { |
186 *backtrace++ = StackFrame::FromThreadName(thread_name_); | 185 *backtrace++ = StackFrame::FromThreadName(thread_name_); |
187 } | 186 } |
188 | 187 |
189 switch (mode) { | 188 switch (mode) { |
190 case CaptureMode::DISABLED: | 189 case CaptureMode::DISABLED: |
191 { | 190 { |
(...skipping 11 matching lines...) Expand all Loading... | |
203 } | 202 } |
204 case CaptureMode::NATIVE_STACK: | 203 case CaptureMode::NATIVE_STACK: |
205 { | 204 { |
206 // Backtrace contract requires us to return bottom frames, i.e. | 205 // Backtrace contract requires us to return bottom frames, i.e. |
207 // from main() and up. Stack unwinding produces top frames, i.e. | 206 // from main() and up. Stack unwinding produces top frames, i.e. |
208 // from this point and up until main(). We request many frames to | 207 // from this point and up until main(). We request many frames to |
209 // make sure we reach main(), and then copy bottom portion of them. | 208 // make sure we reach main(), and then copy bottom portion of them. |
210 const void* frames[128]; | 209 const void* frames[128]; |
211 static_assert(arraysize(frames) >= Backtrace::kMaxFrameCount, | 210 static_assert(arraysize(frames) >= Backtrace::kMaxFrameCount, |
212 "not requesting enough frames to fill Backtrace"); | 211 "not requesting enough frames to fill Backtrace"); |
213 #if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_NACL) | 212 #if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_NACL) |
Primiano Tucci (use gerrit)
2016/05/27 16:49:43
tip: maybe exclude OS_NACL in HAVE_TRACE_STACK_FRA
Dmitry Skiba
2016/05/27 18:50:09
OS_NACL is there because in NaCl mode stack_trace.
Primiano Tucci (use gerrit)
2016/05/31 16:13:06
Yeah but since we generally don't care about what
| |
214 size_t frame_count = debug::TraceStackFramePointers( | 213 size_t frame_count = debug::TraceStackFramePointers( |
215 frames, | 214 frames, |
216 arraysize(frames), | 215 arraysize(frames), |
217 1 /* exclude this function from the trace */ ); | 216 1 /* exclude this function from the trace */, |
217 &stack_info_); | |
218 #else | 218 #else |
219 size_t frame_count = 0; | 219 size_t frame_count = 0; |
220 NOTREACHED(); | 220 NOTREACHED(); |
221 #endif | 221 #endif |
222 | 222 |
223 // Copy frames backwards | 223 // Copy frames backwards |
224 size_t backtrace_capacity = backtrace_end - backtrace; | 224 size_t backtrace_capacity = backtrace_end - backtrace; |
225 size_t top_frame_index = (backtrace_capacity >= frame_count) ? | 225 size_t top_frame_index = (backtrace_capacity >= frame_count) ? |
226 0 : | 226 0 : |
227 frame_count - backtrace_capacity; | 227 frame_count - backtrace_capacity; |
228 for (size_t i = frame_count; i > top_frame_index;) { | 228 for (size_t i = frame_count; i > top_frame_index;) { |
229 const void* frame = frames[--i]; | 229 const void* frame = frames[--i]; |
230 *backtrace++ = StackFrame::FromProgramCounter(frame); | 230 *backtrace++ = StackFrame::FromProgramCounter(frame); |
231 } | 231 } |
232 break; | 232 break; |
233 } | 233 } |
234 } | 234 } |
235 | 235 |
236 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames); | 236 ctx.backtrace.frame_count = backtrace - std::begin(ctx.backtrace.frames); |
237 | 237 |
238 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension | 238 // TODO(ssid): Fix crbug.com/594803 to add file name as 3rd dimension |
239 // (component name) in the heap profiler and not piggy back on the type name. | 239 // (component name) in the heap profiler and not piggy back on the type name. |
240 ctx.type_name = task_contexts_.empty() ? nullptr : task_contexts_.back(); | 240 ctx.type_name = task_contexts_.empty() ? nullptr : task_contexts_.back(); |
241 | 241 |
242 ignore_scope_depth_--; | |
242 return ctx; | 243 return ctx; |
243 } | 244 } |
244 | 245 |
245 } // namespace trace_event | 246 } // namespace trace_event |
246 } // namespace base | 247 } // namespace base |
OLD | NEW |