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 @@
#if defined(OS_WIN)
struct _EXCEPTION_POINTERS;
struct _CONTEXT;
#endif
namespace base {
......@@ -54,6 +55,7 @@ class BASE_EXPORT StackTrace {
// Note: this function will throw an import not found (StackWalk64) exception
// on system without dbghelp 5.1.
StackTrace(const _EXCEPTION_POINTERS* exception_pointers);
StackTrace(const _CONTEXT* context);
#endif
// Copying and assignment are allowed with the default functions.
......@@ -76,6 +78,10 @@ class BASE_EXPORT StackTrace {
std::string ToString() const;
private:
#if defined(OS_WIN)
void InitTrace(_CONTEXT* context_record);
#endif
// From http://msdn.microsoft.com/en-us/library/bb204633.aspx,
// 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
......
......@@ -214,24 +214,35 @@ StackTrace::StackTrace() {
#endif
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
// use a copy.
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.
STACKFRAME64 stack_frame;
memset(&stack_frame, 0, sizeof(stack_frame));
#if defined(_WIN64)
int machine_type = IMAGE_FILE_MACHINE_AMD64;
stack_frame.AddrPC.Offset = context_record.Rip;
stack_frame.AddrFrame.Offset = context_record.Rbp;
stack_frame.AddrStack.Offset = context_record.Rsp;
stack_frame.AddrPC.Offset = context_record->Rip;
stack_frame.AddrFrame.Offset = context_record->Rbp;
stack_frame.AddrStack.Offset = context_record->Rsp;
#else
int machine_type = IMAGE_FILE_MACHINE_I386;
stack_frame.AddrPC.Offset = context_record.Eip;
stack_frame.AddrFrame.Offset = context_record.Ebp;
stack_frame.AddrStack.Offset = context_record.Esp;
stack_frame.AddrPC.Offset = context_record->Eip;
stack_frame.AddrFrame.Offset = context_record->Ebp;
stack_frame.AddrStack.Offset = context_record->Esp;
#endif
stack_frame.AddrPC.Mode = AddrModeFlat;
stack_frame.AddrFrame.Mode = AddrModeFlat;
......@@ -240,7 +251,7 @@ StackTrace::StackTrace(const EXCEPTION_POINTERS* exception_pointers) {
GetCurrentProcess(),
GetCurrentThread(),
&stack_frame,
&context_record,
context_record,
NULL,
&SymFunctionTableAccess64,
&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