[frames] Make interpreted frame detection stricter

When iterating over stack frames, make the interpreted frame detection
require that the frame header contains the bytecode array.

Currently, the stack frame iterator supports bytecode handlers that
don't create stack frames by checking if the top of the stack (i.e. the
return address) is the interpreter entry trampoline. However, optimized
code tail called from the interpreter entry trampoline can move the
stack pointer without clearing the stack, which means it can end up with
a pointer into the interpreter entry trampoline on the top of its stack
(in an uninitialized value), and be interpreted as an interpreted frame.

To avoid such optimized code frames being interpreted as interpreted
frames, we now additionally test the frame header, to see if it contains
a BytecodeArray.

Change-Id: I4bafcf0f7ce3c973a2e5a312f054d72312bb8a70
Reviewed-on: https://chromium-review.googlesource.com/535646
Reviewed-by: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45951}
This commit is contained in:
Leszek Swirski 2017-06-14 15:45:31 +01:00 committed by Commit Bot
parent c2a7550f47
commit f577b2bb38

View File

@ -230,14 +230,21 @@ SafeStackFrameIterator::SafeStackFrameIterator(
reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp)));
// If the top of stack is a return address to the interpreter trampoline,
// then we are likely in a bytecode handler with elided frame. In that
// case, set the PC properly and make sure we do not drop the frame.
// then we are likely in a bytecode handler with elided frame. Check if
// there is a bytecode array in the frame header, and if there is, case, set
// the PC properly and make sure we do not drop the frame.
if (IsValidStackAddress(sp)) {
MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize);
Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp));
if (IsInterpreterFramePc(isolate, tos)) {
state.pc_address = reinterpret_cast<Address*>(sp);
advance_frame = false;
Address bytecode_array =
fp + InterpreterFrameConstants::kBytecodeArrayFromFp;
if (IsValidStackAddress(bytecode_array)) {
if (Memory::Object_at(bytecode_array)->IsBytecodeArray()) {
state.pc_address = reinterpret_cast<Address*>(sp);
advance_frame = false;
}
}
}
}