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

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

Issue 2707223002: Make --enable-heap-profiling=native "work" on Windows. (Closed)
Patch Set: Fix typos Created 3 years, 9 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 // HAVE_TRACE_STACK_FRAME_POINTERS 31 #endif // HAVE_TRACE_STACK_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 HAVE_TRACE_STACK_FRAME_POINTERS 38 #if HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_WIN)
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 // HAVE_TRACE_STACK_FRAME_POINTERS 145 #endif // HAVE_TRACE_STACK_FRAME_POINTERS && !defined(OS_WIN)
146 146
147 } // namespace 147 } // namespace
148 148
149 #if HAVE_TRACE_STACK_FRAME_POINTERS 149 #if HAVE_TRACE_STACK_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 HAVE_TRACE_STACK_FRAME_POINTERS 223 #if HAVE_TRACE_STACK_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)
228 // Usage of __builtin_frame_address() enables frame pointers in this 240 // Usage of __builtin_frame_address() enables frame pointers in this
229 // function even if they are not enabled globally. So 'fp' will always 241 // function even if they are not enabled globally. So 'fp' will always
230 // be valid. 242 // be valid.
231 uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) - 243 uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) -
232 kStackFrameAdjustment; 244 kStackFrameAdjustment;
233 245
234 uintptr_t stack_end = GetStackEnd(); 246 uintptr_t stack_end = GetStackEnd();
235 247
236 size_t depth = 0; 248 size_t depth = 0;
237 while (depth < max_depth) { 249 while (depth < max_depth) {
(...skipping 13 matching lines...) Expand all
251 if (next_fp) { 263 if (next_fp) {
252 fp = next_fp; 264 fp = next_fp;
253 continue; 265 continue;
254 } 266 }
255 267
256 // Failed to find next frame. 268 // Failed to find next frame.
257 break; 269 break;
258 } 270 }
259 271
260 return depth; 272 return depth;
273 #endif
261 } 274 }
262 275
276 #if !defined(OS_WIN)
263 ScopedStackFrameLinker::ScopedStackFrameLinker(void* fp, void* parent_fp) 277 ScopedStackFrameLinker::ScopedStackFrameLinker(void* fp, void* parent_fp)
264 : fp_(fp), 278 : fp_(fp),
265 parent_fp_(parent_fp), 279 parent_fp_(parent_fp),
266 original_parent_fp_(LinkStackFrames(fp, parent_fp)) {} 280 original_parent_fp_(LinkStackFrames(fp, parent_fp)) {}
267 281
268 ScopedStackFrameLinker::~ScopedStackFrameLinker() { 282 ScopedStackFrameLinker::~ScopedStackFrameLinker() {
269 void* previous_parent_fp = LinkStackFrames(fp_, original_parent_fp_); 283 void* previous_parent_fp = LinkStackFrames(fp_, original_parent_fp_);
270 CHECK_EQ(parent_fp_, previous_parent_fp) 284 CHECK_EQ(parent_fp_, previous_parent_fp)
271 << "Stack frame's parent pointer has changed!"; 285 << "Stack frame's parent pointer has changed!";
272 } 286 }
287 #endif // !defined(OS_WIN)
273 288
274 #endif // HAVE_TRACE_STACK_FRAME_POINTERS 289 #endif // HAVE_TRACE_STACK_FRAME_POINTERS
275 290
276 } // namespace debug 291 } // namespace debug
277 } // namespace base 292 } // 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