diff options
Diffstat (limited to 'src/processor/stackwalker_x86.cc')
-rw-r--r-- | src/processor/stackwalker_x86.cc | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/processor/stackwalker_x86.cc b/src/processor/stackwalker_x86.cc index ab592b58..0d8b3edc 100644 --- a/src/processor/stackwalker_x86.cc +++ b/src/processor/stackwalker_x86.cc @@ -137,7 +137,8 @@ StackFrame* StackwalkerX86::GetContextFrame() { StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo( const vector<StackFrame*> &frames, - WindowsFrameInfo* last_frame_info) { + WindowsFrameInfo* last_frame_info, + bool stack_scan_allowed) { StackFrame::FrameTrust trust = StackFrame::FRAME_TRUST_NONE; StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back()); @@ -345,8 +346,9 @@ StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo( // frame pointer. uint32_t location_start = last_frame->context.esp; uint32_t location, eip; - if (!ScanForReturnAddress(location_start, &location, &eip, - frames.size() == 1 /* is_context_frame */)) { + if (!stack_scan_allowed + || !ScanForReturnAddress(location_start, &location, &eip, + frames.size() == 1 /* is_context_frame */)) { // if we can't find an instruction pointer even with stack scanning, // give up. return NULL; @@ -388,8 +390,9 @@ StackFrameX86* StackwalkerX86::GetCallerByWindowsFrameInfo( // looking one 32-bit word above that location. uint32_t location_start = dictionary[".raSearchStart"] + 4; uint32_t location; - if (ScanForReturnAddress(location_start, &location, &eip, - frames.size() == 1 /* is_context_frame */)) { + if (stack_scan_allowed + && ScanForReturnAddress(location_start, &location, &eip, + frames.size() == 1 /* is_context_frame */)) { // This is a better return address that what program string // evaluation found. Use it, and set %esp to the location above the // one where the return address was found. @@ -497,7 +500,8 @@ StackFrameX86* StackwalkerX86::GetCallerByCFIFrameInfo( } StackFrameX86* StackwalkerX86::GetCallerByEBPAtBase( - const vector<StackFrame*> &frames) { + const vector<StackFrame*> &frames, + bool stack_scan_allowed) { StackFrame::FrameTrust trust; StackFrameX86* last_frame = static_cast<StackFrameX86*>(frames.back()); uint32_t last_esp = last_frame->context.esp; @@ -538,8 +542,9 @@ StackFrameX86* StackwalkerX86::GetCallerByEBPAtBase( // return address. This can happen if last_frame is executing code // for a module for which we don't have symbols, and that module // is compiled without a frame pointer. - if (!ScanForReturnAddress(last_esp, &caller_esp, &caller_eip, - frames.size() == 1 /* is_context_frame */)) { + if (!stack_scan_allowed + || !ScanForReturnAddress(last_esp, &caller_esp, &caller_eip, + frames.size() == 1 /* is_context_frame */)) { // if we can't find an instruction pointer even with stack scanning, // give up. return NULL; @@ -581,7 +586,8 @@ StackFrameX86* StackwalkerX86::GetCallerByEBPAtBase( return frame; } -StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack) { +StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack, + bool stack_scan_allowed) { if (!memory_ || !stack) { BPLOG(ERROR) << "Can't get caller frame without memory or stack"; return NULL; @@ -595,7 +601,8 @@ StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack) { WindowsFrameInfo* windows_frame_info = frame_symbolizer_->FindWindowsFrameInfo(last_frame); if (windows_frame_info) - new_frame.reset(GetCallerByWindowsFrameInfo(frames, windows_frame_info)); + new_frame.reset(GetCallerByWindowsFrameInfo(frames, windows_frame_info, + stack_scan_allowed)); // If the resolver has DWARF CFI information, use that. if (!new_frame.get()) { @@ -607,7 +614,7 @@ StackFrame* StackwalkerX86::GetCallerFrame(const CallStack* stack) { // Otherwise, hope that the program was using a traditional frame structure. if (!new_frame.get()) - new_frame.reset(GetCallerByEBPAtBase(frames)); + new_frame.reset(GetCallerByEBPAtBase(frames, stack_scan_allowed)); // If nothing worked, tell the caller. if (!new_frame.get()) |