| Index: runtime/vm/profiler.cc
|
| diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
|
| index 2781637e589d1af4f77e5348d69f7988a5a3927e..7811b0bfc5b77943aff488f9f1da8814f31d3dcc 100644
|
| --- a/runtime/vm/profiler.cc
|
| +++ b/runtime/vm/profiler.cc
|
| @@ -133,7 +133,7 @@ void Profiler::BeginExecution(Isolate* isolate) {
|
| Sample* sample = sample_buffer->ReserveSample();
|
| sample->Init(Sample::kIsolateStart, isolate, OS::GetCurrentTimeMicros(),
|
| Thread::GetCurrentThreadId());
|
| - ThreadInterrupter::Register(ThreadInterruptNoOp, isolate);
|
| + ThreadInterrupter::Register(RecordSampleInterruptCallback, isolate);
|
| }
|
|
|
|
|
| @@ -462,11 +462,21 @@ ProfilerSampleStackWalker::ProfilerSampleStackWalker(Sample* sample,
|
|
|
|
|
| int ProfilerSampleStackWalker::walk() {
|
| + const intptr_t kMaxStep = 0x1000; // 4K.
|
| uword* pc = reinterpret_cast<uword*>(original_pc_);
|
| #define WALK_STACK
|
| #if defined(WALK_STACK)
|
| uword* fp = reinterpret_cast<uword*>(original_fp_);
|
| uword* previous_fp = fp;
|
| + if (original_sp_ > original_fp_) {
|
| + // Stack pointer should not be above frame pointer.
|
| + return 0;
|
| + }
|
| + if ((original_fp_ - original_sp_) >= kMaxStep) {
|
| + // Gap between frame pointer and stack pointer is
|
| + // too large.
|
| + return 0;
|
| + }
|
| if (original_sp_ < lower_bound_) {
|
| // The stack pointer gives us a better lower bound than
|
| // the isolates stack limit.
|
| @@ -481,8 +491,11 @@ int ProfilerSampleStackWalker::walk() {
|
| pc = CallerPC(fp);
|
| previous_fp = fp;
|
| fp = CallerFP(fp);
|
| - if ((fp <= previous_fp) || !ValidFramePointer(fp)) {
|
| - // Frame pointers should only move to higher addresses.
|
| + intptr_t step = fp - previous_fp;
|
| + if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) {
|
| + // Frame pointer step is too large.
|
| + // Frame pointer did not move to a higher address.
|
| + // Frame pointer is outside of isolate stack bounds.
|
| break;
|
| }
|
| // Move the lower bound up.
|
|
|