Commit 7808da74 authored by wittman's avatar wittman Committed by Commit bot

Support creation of StackTrace directly from CONTEXT struct

BUG=

Review URL: https://codereview.chromium.org/896533003

Cr-Commit-Position: refs/heads/master@{#314361}
parent 89258215
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#if defined(OS_WIN) #if defined(OS_WIN)
struct _EXCEPTION_POINTERS; struct _EXCEPTION_POINTERS;
struct _CONTEXT;
#endif #endif
namespace base { namespace base {
...@@ -54,6 +55,7 @@ class BASE_EXPORT StackTrace { ...@@ -54,6 +55,7 @@ class BASE_EXPORT StackTrace {
// Note: this function will throw an import not found (StackWalk64) exception // Note: this function will throw an import not found (StackWalk64) exception
// on system without dbghelp 5.1. // on system without dbghelp 5.1.
StackTrace(const _EXCEPTION_POINTERS* exception_pointers); StackTrace(const _EXCEPTION_POINTERS* exception_pointers);
StackTrace(const _CONTEXT* context);
#endif #endif
// Copying and assignment are allowed with the default functions. // Copying and assignment are allowed with the default functions.
...@@ -76,6 +78,10 @@ class BASE_EXPORT StackTrace { ...@@ -76,6 +78,10 @@ class BASE_EXPORT StackTrace {
std::string ToString() const; std::string ToString() const;
private: private:
#if defined(OS_WIN)
void InitTrace(_CONTEXT* context_record);
#endif
// From http://msdn.microsoft.com/en-us/library/bb204633.aspx, // From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
// the sum of FramesToSkip and FramesToCapture must be less than 63, // the sum of FramesToSkip and FramesToCapture must be less than 63,
// so set it to 62. Even if on POSIX it could be a larger value, it usually // so set it to 62. Even if on POSIX it could be a larger value, it usually
......
...@@ -214,24 +214,35 @@ StackTrace::StackTrace() { ...@@ -214,24 +214,35 @@ StackTrace::StackTrace() {
#endif #endif
StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) { StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) {
// When walking an exception stack, we need to use StackWalk64().
count_ = 0;
// StackWalk64() may modify context record passed to it, so we will // StackWalk64() may modify context record passed to it, so we will
// use a copy. // use a copy.
CONTEXT context_record = *exception_pointers->ContextRecord; CONTEXT context_record = *exception_pointers->ContextRecord;
InitTrace(&context_record);
}
StackTrace::StackTrace(const CONTEXT* context) {
// StackWalk64() may modify context record passed to it, so we will
// use a copy.
CONTEXT context_record = *context;
InitTrace(&context_record);
}
void StackTrace::InitTrace(CONTEXT* context_record) {
// When walking an exception stack, we need to use StackWalk64().
count_ = 0;
// Initialize stack walking. // Initialize stack walking.
STACKFRAME64 stack_frame; STACKFRAME64 stack_frame;
memset(&stack_frame, 0, sizeof(stack_frame)); memset(&stack_frame, 0, sizeof(stack_frame));
#if defined(_WIN64) #if defined(_WIN64)
int machine_type = IMAGE_FILE_MACHINE_AMD64; int machine_type = IMAGE_FILE_MACHINE_AMD64;
stack_frame.AddrPC.Offset = context_record.Rip; stack_frame.AddrPC.Offset = context_record->Rip;
stack_frame.AddrFrame.Offset = context_record.Rbp; stack_frame.AddrFrame.Offset = context_record->Rbp;
stack_frame.AddrStack.Offset = context_record.Rsp; stack_frame.AddrStack.Offset = context_record->Rsp;
#else #else
int machine_type = IMAGE_FILE_MACHINE_I386; int machine_type = IMAGE_FILE_MACHINE_I386;
stack_frame.AddrPC.Offset = context_record.Eip; stack_frame.AddrPC.Offset = context_record->Eip;
stack_frame.AddrFrame.Offset = context_record.Ebp; stack_frame.AddrFrame.Offset = context_record->Ebp;
stack_frame.AddrStack.Offset = context_record.Esp; stack_frame.AddrStack.Offset = context_record->Esp;
#endif #endif
stack_frame.AddrPC.Mode = AddrModeFlat; stack_frame.AddrPC.Mode = AddrModeFlat;
stack_frame.AddrFrame.Mode = AddrModeFlat; stack_frame.AddrFrame.Mode = AddrModeFlat;
...@@ -240,7 +251,7 @@ StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) { ...@@ -240,7 +251,7 @@ StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) {
GetCurrentProcess(), GetCurrentProcess(),
GetCurrentThread(), GetCurrentThread(),
&stack_frame, &stack_frame,
&context_record, context_record,
NULL, NULL,
&SymFunctionTableAccess64, &SymFunctionTableAccess64,
&SymGetModuleBase64, &SymGetModuleBase64,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment