Index: base/debug_util_win.cc |
=================================================================== |
--- base/debug_util_win.cc (revision 25620) |
+++ base/debug_util_win.cc (working copy) |
@@ -105,10 +105,12 @@ |
// This function should only be called if Init() has been called. We do not |
// LOG(FATAL) here because this code is called might be triggered by a |
// LOG(FATAL) itself. |
- void OutputTraceToStream(const std::vector<void*>& trace, std::ostream* os) { |
+ void OutputTraceToStream(const void* const* trace, |
+ int count, |
+ std::ostream* os) { |
AutoLock lock(lock_); |
- for (size_t i = 0; (i < trace.size()) && os->good(); ++i) { |
+ for (size_t i = 0; (i < count) && os->good(); ++i) { |
awong
2009/09/08 20:44:03
size_t -> int
|
const int kMaxNameLength = 256; |
DWORD_PTR frame = reinterpret_cast<DWORD_PTR>(trace[i]); |
@@ -220,19 +222,41 @@ |
} |
StackTrace::StackTrace() { |
- // From http://msdn.microsoft.com/en-us/library/bb204633(VS.85).aspx, |
- // the sum of FramesToSkip and FramesToCapture must be less than 63, |
- // so set it to 62. |
- const int kMaxCallers = 62; |
+ // When walking our own stack, use CaptureStackBackTrace(). |
+ count_ = CaptureStackBackTrace(0, arraysize(trace_), trace_, NULL); |
+} |
- void* callers[kMaxCallers]; |
- // TODO(ajwong): Migrate this to StackWalk64. |
- int count = CaptureStackBackTrace(0, kMaxCallers, callers, NULL); |
- if (count > 0) { |
- trace_.resize(count); |
- memcpy(&trace_[0], callers, sizeof(callers[0]) * count); |
- } else { |
- trace_.resize(0); |
+StackTrace::StackTrace(EXCEPTION_POINTERS* exception_pointers) { |
+ // When walking an exception stack, we need to use StackWalk64(). |
+ count_ = 0; |
+ // Initialize stack walking. |
+ STACKFRAME64 stack_frame; |
+ memset(&stack_frame, 0, sizeof(stack_frame)); |
+#if defined(_WIN64) |
+ int machine_type = IMAGE_FILE_MACHINE_AMD64; |
+ stack_frame.AddrPC.Offset = exception_pointers->ContextRecord->Rip; |
+ stack_frame.AddrFrame.Offset = exception_pointers->ContextRecord->Rbp; |
+ stack_frame.AddrStack.Offset = exception_pointers->ContextRecord->Rsp; |
+#else |
+ int machine_type = IMAGE_FILE_MACHINE_I386; |
+ stack_frame.AddrPC.Offset = exception_pointers->ContextRecord->Eip; |
+ stack_frame.AddrFrame.Offset = exception_pointers->ContextRecord->Ebp; |
+ stack_frame.AddrStack.Offset = exception_pointers->ContextRecord->Esp; |
+#endif |
+ stack_frame.AddrPC.Mode = AddrModeFlat; |
+ stack_frame.AddrFrame.Mode = AddrModeFlat; |
+ stack_frame.AddrStack.Mode = AddrModeFlat; |
+ while (StackWalk64(machine_type, |
+ GetCurrentProcess(), |
+ GetCurrentThread(), |
+ &stack_frame, |
+ exception_pointers->ContextRecord, |
+ NULL, |
+ &SymFunctionTableAccess64, |
+ &SymGetModuleBase64, |
+ NULL) && |
+ count_ < arraysize(trace_)) { |
+ trace_[count_++] = reinterpret_cast<void*>(stack_frame.AddrPC.Offset); |
} |
} |
@@ -246,11 +270,11 @@ |
if (error != ERROR_SUCCESS) { |
(*os) << "Error initializing symbols (" << error |
<< "). Dumping unresolved backtrace:\n"; |
- for (size_t i = 0; (i < trace_.size()) && os->good(); ++i) { |
+ for (size_t i = 0; (i < count_) && os->good(); ++i) { |
(*os) << "\t" << trace_[i] << "\n"; |
} |
} else { |
(*os) << "Backtrace:\n"; |
- context->OutputTraceToStream(trace_, os); |
+ context->OutputTraceToStream(trace_, count_, os); |
} |
} |