Prevent stack frame cache usage during isolate serialization

Individual frames of a stack frame in the frame cache might point
to the JSFunction of that corresponding stack frame. It is illegal to
serialize JSFunction objects in the isolate snapshot, so the attempt
to serialize the stack frame cache results in a crash. This can happen
when a warmup script is run, before a snapshot is created.

This CL fixes the crash by not utilizing the stack frame cache in case
the serializer is enabled.

Change-Id: I8b79a06b8cff36e1f54b54d3d8e5397b07ba52e7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1923068
Auto-Submit: Simon Zünd <szuend@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65026}
This commit is contained in:
Simon Zünd 2019-11-19 08:00:02 +01:00 committed by Commit Bot
parent 4547c5ef30
commit dec6dc4baf
2 changed files with 50 additions and 1 deletions

View File

@ -749,7 +749,8 @@ class FrameArrayBuilder {
for (int i = 0; i < frame_count; ++i) {
// Caching stack frames only happens for user JS frames.
const bool cache_frame =
enable_frame_caching && !elements_->IsAnyWasmFrame(i) &&
enable_frame_caching && !isolate_->serializer_enabled() &&
!elements_->IsAnyWasmFrame(i) &&
elements_->Function(i).shared().IsUserJavaScript();
if (cache_frame) {
MaybeHandle<StackTraceFrame> maybe_frame =

View File

@ -3992,5 +3992,53 @@ UNINITIALIZED_TEST(SnapshotCreatorAnonClassWithKeep) {
delete[] blob.data;
}
class DisableLazySourcePositionScope {
public:
DisableLazySourcePositionScope()
: backup_value_(FLAG_enable_lazy_source_positions) {
FLAG_enable_lazy_source_positions = false;
}
~DisableLazySourcePositionScope() {
FLAG_enable_lazy_source_positions = backup_value_;
}
private:
bool backup_value_;
};
UNINITIALIZED_TEST(NoStackFrameCacheSerialization) {
// Checks that exceptions caught are not cached in the
// stack frame cache during serialization. The individual frames
// can point to JSFunction objects, which need to be stored in a
// context snapshot, *not* isolate snapshot.
DisableAlwaysOpt();
DisableLazySourcePositionScope lazy_scope;
v8::SnapshotCreator creator;
v8::Isolate* isolate = creator.GetIsolate();
isolate->SetCaptureStackTraceForUncaughtExceptions(true);
{
v8::HandleScope handle_scope(isolate);
{
v8::Local<v8::Context> context = v8::Context::New(isolate);
v8::Context::Scope context_scope(context);
v8::TryCatch try_catch(isolate);
CompileRun(R"(
function foo() { throw new Error('bar'); }
function bar() {
foo();
}
bar();
)");
creator.SetDefaultContext(context);
}
}
v8::StartupData blob =
creator.CreateBlob(v8::SnapshotCreator::FunctionCodeHandling::kKeep);
delete[] blob.data;
}
} // namespace internal
} // namespace v8