| 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 <windows.h> | 7 #include <windows.h> | 
| 8 #include <dbghelp.h> | 8 #include <dbghelp.h> | 
| 9 | 9 | 
| 10 #include <iostream> | 10 #include <iostream> | 
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 207 StackTrace::StackTrace() { | 207 StackTrace::StackTrace() { | 
| 208   // When walking our own stack, use CaptureStackBackTrace(). | 208   // When walking our own stack, use CaptureStackBackTrace(). | 
| 209   count_ = CaptureStackBackTrace(0, arraysize(trace_), trace_, NULL); | 209   count_ = CaptureStackBackTrace(0, arraysize(trace_), trace_, NULL); | 
| 210 } | 210 } | 
| 211 | 211 | 
| 212 #if defined(COMPILER_MSVC) | 212 #if defined(COMPILER_MSVC) | 
| 213 #pragma optimize("", on) | 213 #pragma optimize("", on) | 
| 214 #endif | 214 #endif | 
| 215 | 215 | 
| 216 StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) { | 216 StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) { | 
| 217   // When walking an exception stack, we need to use StackWalk64(). |  | 
| 218   count_ = 0; |  | 
| 219   // StackWalk64() may modify context record passed to it, so we will | 217   // StackWalk64() may modify context record passed to it, so we will | 
| 220   // use a copy. | 218   // use a copy. | 
| 221   CONTEXT context_record = *exception_pointers->ContextRecord; | 219   CONTEXT context_record = *exception_pointers->ContextRecord; | 
|  | 220   InitTrace(&context_record); | 
|  | 221 } | 
|  | 222 | 
|  | 223 StackTrace::StackTrace(const CONTEXT* context) { | 
|  | 224   // StackWalk64() may modify context record passed to it, so we will | 
|  | 225   // use a copy. | 
|  | 226   CONTEXT context_record = *context; | 
|  | 227   InitTrace(&context_record); | 
|  | 228 } | 
|  | 229 | 
|  | 230 void StackTrace::InitTrace(CONTEXT* context_record) { | 
|  | 231 // When walking an exception stack, we need to use StackWalk64(). | 
|  | 232   count_ = 0; | 
| 222   // Initialize stack walking. | 233   // Initialize stack walking. | 
| 223   STACKFRAME64 stack_frame; | 234   STACKFRAME64 stack_frame; | 
| 224   memset(&stack_frame, 0, sizeof(stack_frame)); | 235   memset(&stack_frame, 0, sizeof(stack_frame)); | 
| 225 #if defined(_WIN64) | 236 #if defined(_WIN64) | 
| 226   int machine_type = IMAGE_FILE_MACHINE_AMD64; | 237   int machine_type = IMAGE_FILE_MACHINE_AMD64; | 
| 227   stack_frame.AddrPC.Offset = context_record.Rip; | 238   stack_frame.AddrPC.Offset = context_record->Rip; | 
| 228   stack_frame.AddrFrame.Offset = context_record.Rbp; | 239   stack_frame.AddrFrame.Offset = context_record->Rbp; | 
| 229   stack_frame.AddrStack.Offset = context_record.Rsp; | 240   stack_frame.AddrStack.Offset = context_record->Rsp; | 
| 230 #else | 241 #else | 
| 231   int machine_type = IMAGE_FILE_MACHINE_I386; | 242   int machine_type = IMAGE_FILE_MACHINE_I386; | 
| 232   stack_frame.AddrPC.Offset = context_record.Eip; | 243   stack_frame.AddrPC.Offset = context_record->Eip; | 
| 233   stack_frame.AddrFrame.Offset = context_record.Ebp; | 244   stack_frame.AddrFrame.Offset = context_record->Ebp; | 
| 234   stack_frame.AddrStack.Offset = context_record.Esp; | 245   stack_frame.AddrStack.Offset = context_record->Esp; | 
| 235 #endif | 246 #endif | 
| 236   stack_frame.AddrPC.Mode = AddrModeFlat; | 247   stack_frame.AddrPC.Mode = AddrModeFlat; | 
| 237   stack_frame.AddrFrame.Mode = AddrModeFlat; | 248   stack_frame.AddrFrame.Mode = AddrModeFlat; | 
| 238   stack_frame.AddrStack.Mode = AddrModeFlat; | 249   stack_frame.AddrStack.Mode = AddrModeFlat; | 
| 239   while (StackWalk64(machine_type, | 250   while (StackWalk64(machine_type, | 
| 240                      GetCurrentProcess(), | 251                      GetCurrentProcess(), | 
| 241                      GetCurrentThread(), | 252                      GetCurrentThread(), | 
| 242                      &stack_frame, | 253                      &stack_frame, | 
| 243                      &context_record, | 254                      context_record, | 
| 244                      NULL, | 255                      NULL, | 
| 245                      &SymFunctionTableAccess64, | 256                      &SymFunctionTableAccess64, | 
| 246                      &SymGetModuleBase64, | 257                      &SymGetModuleBase64, | 
| 247                      NULL) && | 258                      NULL) && | 
| 248          count_ < arraysize(trace_)) { | 259          count_ < arraysize(trace_)) { | 
| 249     trace_[count_++] = reinterpret_cast<void*>(stack_frame.AddrPC.Offset); | 260     trace_[count_++] = reinterpret_cast<void*>(stack_frame.AddrPC.Offset); | 
| 250   } | 261   } | 
| 251 | 262 | 
| 252   for (size_t i = count_; i < arraysize(trace_); ++i) | 263   for (size_t i = count_; i < arraysize(trace_); ++i) | 
| 253     trace_[i] = NULL; | 264     trace_[i] = NULL; | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 267       (*os) << "\t" << trace_[i] << "\n"; | 278       (*os) << "\t" << trace_[i] << "\n"; | 
| 268     } | 279     } | 
| 269   } else { | 280   } else { | 
| 270     (*os) << "Backtrace:\n"; | 281     (*os) << "Backtrace:\n"; | 
| 271     context->OutputTraceToStream(trace_, count_, os); | 282     context->OutputTraceToStream(trace_, count_, os); | 
| 272   } | 283   } | 
| 273 } | 284 } | 
| 274 | 285 | 
| 275 }  // namespace debug | 286 }  // namespace debug | 
| 276 }  // namespace base | 287 }  // namespace base | 
| OLD | NEW | 
|---|