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

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

Issue 1387913002: Copy the register context before calling StackWalk64 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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') | no next file » | 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 <windows.h> 7 #include <windows.h>
8 #include <dbghelp.h> 8 #include <dbghelp.h>
9 9
10 #include <iostream> 10 #include <iostream>
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 } 215 }
216 216
217 #if defined(COMPILER_MSVC) 217 #if defined(COMPILER_MSVC)
218 #pragma optimize("", on) 218 #pragma optimize("", on)
219 #endif 219 #endif
220 220
221 StackTrace::StackTrace(EXCEPTION_POINTERS* exception_pointers) { 221 StackTrace::StackTrace(EXCEPTION_POINTERS* exception_pointers) {
222 InitTrace(exception_pointers->ContextRecord); 222 InitTrace(exception_pointers->ContextRecord);
223 } 223 }
224 224
225 StackTrace::StackTrace(CONTEXT* context) { 225 StackTrace::StackTrace(const CONTEXT* context) {
226 InitTrace(context); 226 InitTrace(context);
227 } 227 }
228 228
229 void StackTrace::InitTrace(CONTEXT* context_record) { 229 void StackTrace::InitTrace(const CONTEXT* context_record) {
230 // StackWalk64 modifies the register context in place, so we have to copy it
231 // so that downstream exception handlers get the right context. The incoming
232 // context may have had more register state (YMM, etc) than we need to unwind
233 // the stack. Typically StackWalk64 only needs integer and control registers.
234 CONTEXT context_copy;
235 memcpy(&context_copy, context_record, sizeof(context_copy));
236 context_copy.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
237
230 // When walking an exception stack, we need to use StackWalk64(). 238 // When walking an exception stack, we need to use StackWalk64().
231 count_ = 0; 239 count_ = 0;
232 // Initialize stack walking. 240 // Initialize stack walking.
233 STACKFRAME64 stack_frame; 241 STACKFRAME64 stack_frame;
234 memset(&stack_frame, 0, sizeof(stack_frame)); 242 memset(&stack_frame, 0, sizeof(stack_frame));
235 #if defined(_WIN64) 243 #if defined(_WIN64)
236 int machine_type = IMAGE_FILE_MACHINE_AMD64; 244 int machine_type = IMAGE_FILE_MACHINE_AMD64;
237 stack_frame.AddrPC.Offset = context_record->Rip; 245 stack_frame.AddrPC.Offset = context_record->Rip;
238 stack_frame.AddrFrame.Offset = context_record->Rbp; 246 stack_frame.AddrFrame.Offset = context_record->Rbp;
239 stack_frame.AddrStack.Offset = context_record->Rsp; 247 stack_frame.AddrStack.Offset = context_record->Rsp;
240 #else 248 #else
241 int machine_type = IMAGE_FILE_MACHINE_I386; 249 int machine_type = IMAGE_FILE_MACHINE_I386;
242 stack_frame.AddrPC.Offset = context_record->Eip; 250 stack_frame.AddrPC.Offset = context_record->Eip;
243 stack_frame.AddrFrame.Offset = context_record->Ebp; 251 stack_frame.AddrFrame.Offset = context_record->Ebp;
244 stack_frame.AddrStack.Offset = context_record->Esp; 252 stack_frame.AddrStack.Offset = context_record->Esp;
245 #endif 253 #endif
246 stack_frame.AddrPC.Mode = AddrModeFlat; 254 stack_frame.AddrPC.Mode = AddrModeFlat;
247 stack_frame.AddrFrame.Mode = AddrModeFlat; 255 stack_frame.AddrFrame.Mode = AddrModeFlat;
248 stack_frame.AddrStack.Mode = AddrModeFlat; 256 stack_frame.AddrStack.Mode = AddrModeFlat;
249 while (StackWalk64(machine_type, 257 while (StackWalk64(machine_type,
250 GetCurrentProcess(), 258 GetCurrentProcess(),
251 GetCurrentThread(), 259 GetCurrentThread(),
252 &stack_frame, 260 &stack_frame,
253 context_record, 261 &context_copy,
254 NULL, 262 NULL,
255 &SymFunctionTableAccess64, 263 &SymFunctionTableAccess64,
256 &SymGetModuleBase64, 264 &SymGetModuleBase64,
257 NULL) && 265 NULL) &&
258 count_ < arraysize(trace_)) { 266 count_ < arraysize(trace_)) {
259 trace_[count_++] = reinterpret_cast<void*>(stack_frame.AddrPC.Offset); 267 trace_[count_++] = reinterpret_cast<void*>(stack_frame.AddrPC.Offset);
260 } 268 }
261 269
262 for (size_t i = count_; i < arraysize(trace_); ++i) 270 for (size_t i = count_; i < arraysize(trace_); ++i)
263 trace_[i] = NULL; 271 trace_[i] = NULL;
(...skipping 12 matching lines...) Expand all
276 (*os) << "\t" << trace_[i] << "\n"; 284 (*os) << "\t" << trace_[i] << "\n";
277 } 285 }
278 } else { 286 } else {
279 (*os) << "Backtrace:\n"; 287 (*os) << "Backtrace:\n";
280 context->OutputTraceToStream(trace_, count_, os); 288 context->OutputTraceToStream(trace_, count_, os);
281 } 289 }
282 } 290 }
283 291
284 } // namespace debug 292 } // namespace debug
285 } // namespace base 293 } // namespace base
OLDNEW
« no previous file with comments | « base/debug/stack_trace.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698