aboutsummaryrefslogtreecommitdiff
path: root/src/processor/stackwalker_x86.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/processor/stackwalker_x86.cc')
-rw-r--r--src/processor/stackwalker_x86.cc29
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())