Fix crash that happens when we send an object whose type is in a defer

loaded a library that is loaded in the isolate that is sending the message but has not been loaded yet in the isolate which is receiving the message.

R=hausner@google.com

Review URL: https://codereview.chromium.org//926073002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@43774 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
asiva@google.com 2015-02-13 19:17:01 +00:00
parent c7c2b4584b
commit 62d6e2e0bc
4 changed files with 85 additions and 2 deletions

View file

@ -7,6 +7,7 @@
#include "platform/assert.h"
#include "vm/bootstrap.h"
#include "vm/class_finalizer.h"
#include "vm/dart_entry.h"
#include "vm/exceptions.h"
#include "vm/heap.h"
#include "vm/lockers.h"
@ -223,11 +224,15 @@ RawClass* SnapshotReader::ReadClassId(intptr_t object_id) {
// Read the library/class information and lookup the class.
str_ ^= ReadObjectImpl(class_header);
library_ = Library::LookupLibrary(str_);
ASSERT(!library_.IsNull());
if (library_.IsNull() || !library_.Loaded()) {
SetReadException("Invalid object found in message.");
}
str_ ^= ReadObjectImpl();
cls = library_.LookupClass(str_);
if (cls.IsNull()) {
SetReadException("Invalid object found in message.");
}
cls.EnsureIsFinalized(isolate());
ASSERT(!cls.IsNull());
return cls.raw();
}
@ -247,6 +252,24 @@ intptr_t SnapshotReader::NextAvailableObjectId() const {
}
void SnapshotReader::SetReadException(const char* msg) {
Isolate* isolate = Isolate::Current();
const String& error_str = String::Handle(isolate, String::New(msg));
const Array& args = Array::Handle(isolate, Array::New(1));
args.SetAt(0, error_str);
Object& result = Object::Handle(isolate);
const Library& library = Library::Handle(isolate, Library::CoreLibrary());
result = DartLibraryCalls::InstanceCreate(library,
Symbols::ArgumentError(),
Symbols::Dot(),
args);
const Stacktrace& stacktrace = Stacktrace::Handle(isolate);
const UnhandledException& error = UnhandledException::Handle(
isolate, UnhandledException::New(Instance::Cast(result), stacktrace));
isolate->long_jump_base()->Jump(1, error);
}
RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) {
if (IsVMIsolateObject(header_value)) {
return ReadVMIsolateObject(header_value);

View file

@ -368,6 +368,8 @@ class SnapshotReader : public BaseReader {
intptr_t NextAvailableObjectId() const;
void SetReadException(const char* msg);
Snapshot::Kind kind_; // Indicates type of snapshot(full, script, message).
Isolate* isolate_; // Current isolate.
Heap* heap_; // Heap of the current isolate.

View file

@ -0,0 +1,9 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
class FromChildIsolate {
String toString() => 'from child isolate';
int get fld => 10;
}

View file

@ -0,0 +1,49 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:isolate';
import 'dart:async';
import "package:expect/expect.dart";
import "deferred_loaded_lib.dart" deferred as lib;
// In this test case we send an object created from a deferred library
// that is loaded in the child isolate but not the parent isolate. The
// parent isolate does not know about the type of this object and throws
// an unhandled exception.
funcChild(args) {
var replyPort = args[0];
// Deferred load a library, create an object from that library and send
// it over to the parent isolate which has not yet loaded that library.
lib.loadLibrary().then((_) {
replyPort.send(new lib.FromChildIsolate());
});
}
void helperFunction() {
var receivePort = new ReceivePort();
// Spawn an isolate using spawnFunction.
Isolate.spawn(funcChild, [receivePort.sendPort]).then(
(isolate) {
receivePort.listen(
(msg) {
// We don't expect to receive any valid messages.
Expect.fail("We don't expect to receive any valid messages");
receivePort.close();
},
onError: (e) {
// We don't expect to receive any error messages, per spec listen
// does not receive an error object.
Expect.fail("We don't expect to receive any error messages");
receivePort.close();
}
);
}
);
}
main() {
helperFunction(); /// 01: runtime error
}