OLD | NEW |
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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 OutputToStream(&stream); | 216 OutputToStream(&stream); |
217 #endif | 217 #endif |
218 return stream.str(); | 218 return stream.str(); |
219 } | 219 } |
220 | 220 |
221 #if HAVE_TRACE_STACK_FRAME_POINTERS | 221 #if HAVE_TRACE_STACK_FRAME_POINTERS |
222 | 222 |
223 size_t TraceStackFramePointers(const void** out_trace, | 223 size_t TraceStackFramePointers(const void** out_trace, |
224 size_t max_depth, | 224 size_t max_depth, |
225 size_t skip_initial) { | 225 size_t skip_initial) { |
| 226 #if defined(OS_WIN) |
| 227 // LOG(ERROR) << "&fp=" << _AddressOfReturnAddress(); |
| 228 // LOG(ERROR) << "fp=" << _ReturnAddress(); |
| 229 StackTrace stack(max_depth); |
| 230 size_t count = 0; |
| 231 const void* const* frames = stack.Addresses(&count); |
| 232 if (count < skip_initial) |
| 233 return 0u; |
| 234 count -= skip_initial; |
| 235 memcpy(out_trace, frames + skip_initial, count); |
| 236 return count; |
| 237 #elif defined(OS_POSIX) |
226 // Usage of __builtin_frame_address() enables frame pointers in this | 238 // Usage of __builtin_frame_address() enables frame pointers in this |
227 // function even if they are not enabled globally. So 'fp' will always | 239 // function even if they are not enabled globally. So 'fp' will always |
228 // be valid. | 240 // be valid. |
229 uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) - | 241 uintptr_t fp = reinterpret_cast<uintptr_t>(__builtin_frame_address(0)) - |
230 kStackFrameAdjustment; | 242 kStackFrameAdjustment; |
231 | 243 |
232 uintptr_t stack_end = GetStackEnd(); | 244 uintptr_t stack_end = GetStackEnd(); |
233 | 245 |
234 size_t depth = 0; | 246 size_t depth = 0; |
235 while (depth < max_depth) { | 247 while (depth < max_depth) { |
(...skipping 13 matching lines...) Expand all Loading... |
249 if (next_fp) { | 261 if (next_fp) { |
250 fp = next_fp; | 262 fp = next_fp; |
251 continue; | 263 continue; |
252 } | 264 } |
253 | 265 |
254 // Failed to find next frame. | 266 // Failed to find next frame. |
255 break; | 267 break; |
256 } | 268 } |
257 | 269 |
258 return depth; | 270 return depth; |
| 271 #endif |
259 } | 272 } |
260 | 273 |
261 ScopedStackFrameLinker::ScopedStackFrameLinker(void* fp, void* parent_fp) | 274 ScopedStackFrameLinker::ScopedStackFrameLinker(void* fp, void* parent_fp) |
262 : fp_(fp), | 275 : fp_(fp), |
263 parent_fp_(parent_fp), | 276 parent_fp_(parent_fp), |
264 original_parent_fp_(LinkStackFrames(fp, parent_fp)) {} | 277 original_parent_fp_(LinkStackFrames(fp, parent_fp)) {} |
265 | 278 |
266 ScopedStackFrameLinker::~ScopedStackFrameLinker() { | 279 ScopedStackFrameLinker::~ScopedStackFrameLinker() { |
267 void* previous_parent_fp = LinkStackFrames(fp_, original_parent_fp_); | 280 void* previous_parent_fp = LinkStackFrames(fp_, original_parent_fp_); |
268 CHECK_EQ(parent_fp_, previous_parent_fp) | 281 CHECK_EQ(parent_fp_, previous_parent_fp) |
269 << "Stack frame's parent pointer has changed!"; | 282 << "Stack frame's parent pointer has changed!"; |
270 } | 283 } |
271 | 284 |
272 #endif // HAVE_TRACE_STACK_FRAME_POINTERS | 285 #endif // HAVE_TRACE_STACK_FRAME_POINTERS |
273 | 286 |
274 } // namespace debug | 287 } // namespace debug |
275 } // namespace base | 288 } // namespace base |
OLD | NEW |