Index: src/frames.cc |
diff --git a/src/frames.cc b/src/frames.cc |
index 76a441b64d8ec84d70804dff4852e8f128edc3cb..3cdb0157e7d9acbfbbe91cc9d6f41c8ab47e4a59 100644 |
--- a/src/frames.cc |
+++ b/src/frames.cc |
@@ -143,8 +143,8 @@ void StackFrameIterator::Reset() { |
state.pc_address = |
reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)); |
type = StackFrame::ComputeType(&state); |
- if (SingletonFor(type) == NULL) return; |
} |
+ if (SingletonFor(type) == NULL) return; |
frame_ = SingletonFor(type, &state); |
} |
@@ -203,13 +203,24 @@ bool StackTraceFrameIterator::IsValidFrame() { |
// ------------------------------------------------------------------------- |
+bool SafeStackFrameIterator::ExitFrameValidator::IsValidFP(Address fp) { |
+ if (!validator_.IsValid(fp)) return false; |
+ Address sp = ExitFrame::ComputeStackPointer(fp); |
+ if (!validator_.IsValid(sp)) return false; |
+ StackFrame::State state; |
+ ExitFrame::FillState(fp, sp, &state); |
+ if (!validator_.IsValid(reinterpret_cast<Address>(state.pc_address))) { |
+ return false; |
+ } |
+ return *state.pc_address != NULL; |
+} |
+ |
+ |
SafeStackFrameIterator::SafeStackFrameIterator( |
Address fp, Address sp, Address low_bound, Address high_bound) : |
- maintainer_(), low_bound_(low_bound), high_bound_(high_bound), |
- is_valid_top_( |
- IsWithinBounds(low_bound, high_bound, |
- Top::c_entry_fp(Top::GetCurrentThread())) && |
- Top::handler(Top::GetCurrentThread()) != NULL), |
+ maintainer_(), |
+ stack_validator_(low_bound, high_bound), |
+ is_valid_top_(IsValidTop(low_bound, high_bound)), |
is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), |
is_working_iterator_(is_valid_top_ || is_valid_fp_), |
iteration_done_(!is_working_iterator_), |
@@ -217,6 +228,14 @@ SafeStackFrameIterator::SafeStackFrameIterator( |
} |
+bool SafeStackFrameIterator::IsValidTop(Address low_bound, Address high_bound) { |
+ Address fp = Top::c_entry_fp(Top::GetCurrentThread()); |
+ ExitFrameValidator validator(low_bound, high_bound); |
+ if (!validator.IsValidFP(fp)) return false; |
+ return Top::handler(Top::GetCurrentThread()) != NULL; |
+} |
+ |
+ |
void SafeStackFrameIterator::Advance() { |
ASSERT(is_working_iterator_); |
ASSERT(!done()); |
@@ -258,9 +277,8 @@ bool SafeStackFrameIterator::IsValidCaller(StackFrame* frame) { |
// sure that caller FP address is valid. |
Address caller_fp = Memory::Address_at( |
frame->fp() + EntryFrameConstants::kCallerFPOffset); |
- if (!IsValidStackAddress(caller_fp)) { |
- return false; |
- } |
+ ExitFrameValidator validator(stack_validator_); |
+ if (!validator.IsValidFP(caller_fp)) return false; |
} else if (frame->is_arguments_adaptor()) { |
// See ArgumentsAdaptorFrame::GetCallerStackPointer. It assumes that |
// the number of arguments is stored on stack as Smi. We need to check |
@@ -415,6 +433,22 @@ Address ExitFrame::GetCallerStackPointer() const { |
} |
+StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { |
+ if (fp == 0) return NONE; |
+ Address sp = ComputeStackPointer(fp); |
+ FillState(fp, sp, state); |
+ ASSERT(*state->pc_address != NULL); |
+ return EXIT; |
+} |
+ |
+ |
+void ExitFrame::FillState(Address fp, Address sp, State* state) { |
+ state->sp = sp; |
+ state->fp = fp; |
+ state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize); |
+} |
+ |
+ |
Address StandardFrame::GetExpressionAddress(int n) const { |
const int offset = StandardFrameConstants::kExpressionsOffset; |
return fp() + offset - n * kPointerSize; |