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

Side by Side Diff: base/debug/stack_trace.cc

Issue 2757123002: Cleaner fall-back stack capture for --enable-heap-profiling=native. (Closed)
Patch Set: Fix comments Created 3 years, 8 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 | « base/debug/stack_trace.h ('k') | base/debug/stack_trace_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/debug/stack_trace.h" 5 #include "base/debug/stack_trace.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <sstream> 10 #include <sstream>
(...skipping 17 matching lines...) Expand all
28 extern "C" void* __libc_stack_end; 28 extern "C" void* __libc_stack_end;
29 #endif 29 #endif
30 30
31 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 31 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
32 32
33 namespace base { 33 namespace base {
34 namespace debug { 34 namespace debug {
35 35
36 namespace { 36 namespace {
37 37
38 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(OS_WIN) 38 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
39 39
40 #if defined(__arm__) && defined(__GNUC__) && !defined(__clang__) 40 #if defined(__arm__) && defined(__GNUC__) && !defined(__clang__)
41 // GCC and LLVM generate slightly different frames on ARM, see 41 // GCC and LLVM generate slightly different frames on ARM, see
42 // https://llvm.org/bugs/show_bug.cgi?id=18505 - LLVM generates 42 // https://llvm.org/bugs/show_bug.cgi?id=18505 - LLVM generates
43 // x86-compatible frame, while GCC needs adjustment. 43 // x86-compatible frame, while GCC needs adjustment.
44 constexpr size_t kStackFrameAdjustment = sizeof(uintptr_t); 44 constexpr size_t kStackFrameAdjustment = sizeof(uintptr_t);
45 #else 45 #else
46 constexpr size_t kStackFrameAdjustment = 0; 46 constexpr size_t kStackFrameAdjustment = 0;
47 #endif 47 #endif
48 48
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 // TraceStackFramePointers() visits |parent_fp| after visiting |fp|. 135 // TraceStackFramePointers() visits |parent_fp| after visiting |fp|.
136 // Both frame pointers must come from __builtin_frame_address(). 136 // Both frame pointers must come from __builtin_frame_address().
137 // Returns previous stack frame |fp| was linked to. 137 // Returns previous stack frame |fp| was linked to.
138 void* LinkStackFrames(void* fpp, void* parent_fp) { 138 void* LinkStackFrames(void* fpp, void* parent_fp) {
139 uintptr_t fp = reinterpret_cast<uintptr_t>(fpp) - kStackFrameAdjustment; 139 uintptr_t fp = reinterpret_cast<uintptr_t>(fpp) - kStackFrameAdjustment;
140 void* prev_parent_fp = reinterpret_cast<void**>(fp)[0]; 140 void* prev_parent_fp = reinterpret_cast<void**>(fp)[0];
141 reinterpret_cast<void**>(fp)[0] = parent_fp; 141 reinterpret_cast<void**>(fp)[0] = parent_fp;
142 return prev_parent_fp; 142 return prev_parent_fp;
143 } 143 }
144 144
145 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) && !defined(OS_WIN) 145 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
146 146
147 } // namespace 147 } // namespace
148 148
149 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 149 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
150 uintptr_t GetStackEnd() { 150 uintptr_t GetStackEnd() {
151 #if defined(OS_ANDROID) 151 #if defined(OS_ANDROID)
152 // Bionic reads proc/maps on every call to pthread_getattr_np() when called 152 // Bionic reads proc/maps on every call to pthread_getattr_np() when called
153 // from the main thread. So we need to cache end of stack in that case to get 153 // from the main thread. So we need to cache end of stack in that case to get
154 // acceptable performance. 154 // acceptable performance.
155 // For all other threads pthread_getattr_np() is fast enough as it just reads 155 // For all other threads pthread_getattr_np() is fast enough as it just reads
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 OutputToStream(&stream); 218 OutputToStream(&stream);
219 #endif 219 #endif
220 return stream.str(); 220 return stream.str();
221 } 221 }
222 222
223 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 223 #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
224 224
225 size_t TraceStackFramePointers(const void** out_trace, 225 size_t TraceStackFramePointers(const void** out_trace,
226 size_t max_depth, 226 size_t max_depth,
227 size_t skip_initial) { 227 size_t skip_initial) {
228 // TODO(699863): Merge the frame-pointer based stack unwinder into the
229 // base::debug::StackTrace platform-specific implementation files.
230 #if defined(OS_WIN)
231 StackTrace stack(max_depth);
232 size_t count = 0;
233 const void* const* frames = stack.Addresses(&count);
234 if (count < skip_initial)
235 return 0u;
236 count -= skip_initial;
237 memcpy(out_trace, frames + skip_initial, count * sizeof(void*));
238 return count;
239 #elif defined(OS_POSIX)
240 // Usage of __builtin_frame_address() enables frame pointers in this 228 // Usage of __builtin_frame_address() enables frame pointers in this
241 // function even if they are not enabled globally. So 'fp' will always 229 // function even if they are not enabled globally. So 'fp' will always
242 // be valid. 230 // be valid.
243 uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) - 231 uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) -
244 kStackFrameAdjustment; 232 kStackFrameAdjustment;
245 233
246 uintptr_t stack_end = GetStackEnd(); 234 uintptr_t stack_end = GetStackEnd();
247 235
248 size_t depth = 0; 236 size_t depth = 0;
249 while (depth < max_depth) { 237 while (depth < max_depth) {
(...skipping 13 matching lines...) Expand all
263 if (next_fp) { 251 if (next_fp) {
264 fp = next_fp; 252 fp = next_fp;
265 continue; 253 continue;
266 } 254 }
267 255
268 // Failed to find next frame. 256 // Failed to find next frame.
269 break; 257 break;
270 } 258 }
271 259
272 return depth; 260 return depth;
273 #endif
274 } 261 }
275 262
276 #if !defined(OS_WIN)
277 ScopedStackFrameLinker::ScopedStackFrameLinker(void* fp, void* parent_fp) 263 ScopedStackFrameLinker::ScopedStackFrameLinker(void* fp, void* parent_fp)
278 : fp_(fp), 264 : fp_(fp),
279 parent_fp_(parent_fp), 265 parent_fp_(parent_fp),
280 original_parent_fp_(LinkStackFrames(fp, parent_fp)) {} 266 original_parent_fp_(LinkStackFrames(fp, parent_fp)) {}
281 267
282 ScopedStackFrameLinker::~ScopedStackFrameLinker() { 268 ScopedStackFrameLinker::~ScopedStackFrameLinker() {
283 void* previous_parent_fp = LinkStackFrames(fp_, original_parent_fp_); 269 void* previous_parent_fp = LinkStackFrames(fp_, original_parent_fp_);
284 CHECK_EQ(parent_fp_, previous_parent_fp) 270 CHECK_EQ(parent_fp_, previous_parent_fp)
285 << "Stack frame's parent pointer has changed!"; 271 << "Stack frame's parent pointer has changed!";
286 } 272 }
287 #endif // !defined(OS_WIN)
288 273
289 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) 274 #endif // BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
290 275
291 } // namespace debug 276 } // namespace debug
292 } // namespace base 277 } // namespace base
OLDNEW
« no previous file with comments | « base/debug/stack_trace.h ('k') | base/debug/stack_trace_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698