Skip to content

Commit 9319d07

Browse files
rmacnak-googleCommit Queue
authored and
Commit Queue
committed
[vm] Fill in ArgumentValue.invalidObject when objects are rejected in isolate messages.
TEST=ci Change-Id: I5a2816ce7fd40463aaffd971d867955a7b2bd7e6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/265043 Reviewed-by: Alexander Aprelev <[email protected]> Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent dbb793a commit 9319d07

7 files changed

+68
-120
lines changed

runtime/lib/isolate.cc

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,9 @@ static ObjectPtr ValidateMessageObject(Zone* zone,
188188

189189
Class& klass = Class::Handle(zone);
190190
Closure& closure = Closure::Handle(zone);
191-
192-
bool error_found = false;
193-
Function& erroneous_closure_function = Function::Handle(zone);
194-
Class& erroneous_nativewrapper_class = Class::Handle(zone);
195-
Class& erroneous_finalizable_class = Class::Handle(zone);
196191
Array& array = Array::Handle(zone);
197-
const char* error_message = nullptr;
192+
Object& illegal_object = Object::Handle(zone);
193+
const char* exception_message = nullptr;
198194
Thread* thread = Thread::Current();
199195

200196
// working_set contains only elements that have not been visited yet that
@@ -214,7 +210,7 @@ static ObjectPtr ValidateMessageObject(Zone* zone,
214210
visited->SetValueExclusive(obj.ptr(), 1);
215211
working_set->Add(obj.ptr());
216212

217-
while (!working_set->is_empty() && !error_found) {
213+
while (!working_set->is_empty() && (exception_message == nullptr)) {
218214
thread->CheckForSafepoint();
219215

220216
ObjectPtr raw = working_set->RemoveLast();
@@ -265,9 +261,8 @@ static ObjectPtr ValidateMessageObject(Zone* zone,
265261

266262
#define MESSAGE_SNAPSHOT_ILLEGAL(type) \
267263
case k##type##Cid: \
268-
error_message = \
269-
"Illegal argument in isolate message : (object is a " #type ")"; \
270-
error_found = true; \
264+
illegal_object = raw; \
265+
exception_message = "is a " #type; \
271266
break;
272267

273268
MESSAGE_SNAPSHOT_ILLEGAL(DynamicLibrary);
@@ -284,45 +279,33 @@ static ObjectPtr ValidateMessageObject(Zone* zone,
284279
if (cid >= kNumPredefinedCids) {
285280
klass = class_table->At(cid);
286281
if (klass.num_native_fields() != 0) {
287-
erroneous_nativewrapper_class = klass.ptr();
288-
error_found = true;
282+
illegal_object = raw;
283+
exception_message = "is a NativeWrapper";
289284
break;
290285
}
291286
if (klass.implements_finalizable()) {
292-
erroneous_finalizable_class = klass.ptr();
293-
error_found = true;
287+
illegal_object = raw;
288+
exception_message = "is a Finalizable";
294289
break;
295290
}
296291
}
297292
}
298293
raw->untag()->VisitPointers(&visitor);
299294
}
300-
if (error_found) {
301-
const char* exception_message;
302-
if (error_message != nullptr) {
303-
exception_message = error_message;
304-
} else if (!erroneous_closure_function.IsNull()) {
305-
exception_message = OS::SCreate(zone,
306-
"Illegal argument in isolate message"
307-
" : (object is a closure - %s)",
308-
erroneous_closure_function.ToCString());
309-
} else if (!erroneous_nativewrapper_class.IsNull()) {
310-
exception_message =
311-
OS::SCreate(zone,
312-
"Illegal argument in isolate message"
313-
" : (object extends NativeWrapper - %s)",
314-
erroneous_nativewrapper_class.ToCString());
315-
} else {
316-
ASSERT(!erroneous_finalizable_class.IsNull());
317-
exception_message = OS::SCreate(zone,
318-
"Illegal argument in isolate message"
319-
" : (object implements Finalizable - %s)",
320-
erroneous_finalizable_class.ToCString());
321-
}
295+
296+
ASSERT((exception_message == nullptr) == illegal_object.IsNull());
297+
if (exception_message != nullptr) {
322298
working_set->Clear();
323-
return Exceptions::CreateUnhandledException(
324-
zone, Exceptions::kArgumentValue, exception_message);
299+
300+
const Array& args = Array::Handle(zone, Array::New(3));
301+
args.SetAt(0, illegal_object);
302+
args.SetAt(2, String::Handle(zone, String::New(exception_message)));
303+
const Object& exception = Object::Handle(
304+
zone, Exceptions::Create(Exceptions::kArgumentValue, args));
305+
return UnhandledException::New(Instance::Cast(exception),
306+
StackTrace::Handle(zone));
325307
}
308+
326309
ASSERT(working_set->length() == 0);
327310
isolate->set_forward_table_new(nullptr);
328311
return obj.ptr();

runtime/tests/vm/dart/sendandexit_test.dart

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,25 @@ class NativeWrapperClass extends NativeFieldWrapperClass1 {}
3030

3131
verifyCantSendNative() async {
3232
final receivePort = ReceivePort();
33+
final unsendable = NativeWrapperClass();
3334
Expect.throws(
34-
() => Isolate.exit(receivePort.sendPort, NativeWrapperClass()),
35-
(e) => e.toString().startsWith('Invalid argument: '
36-
'"Illegal argument in isolate message : '
37-
'(object extends NativeWrapper'));
35+
() => Isolate.exit(receivePort.sendPort, unsendable),
36+
(e) =>
37+
e is ArgumentError &&
38+
e.invalidValue == unsendable &&
39+
e.toString().contains("NativeWrapper"));
3840
receivePort.close();
3941
}
4042

4143
verifyCantSendReceivePort() async {
42-
final receivePort = ReceivePort();
44+
final receivePort = RawReceivePort();
45+
final unsendable = receivePort;
4346
Expect.throws(
4447
() => Isolate.exit(receivePort.sendPort, receivePort),
45-
(e) => e.toString().startsWith(
46-
'Invalid argument: "Illegal argument in isolate message : '
47-
'(object is a ReceivePort)\"'));
48+
(e) =>
49+
e is ArgumentError &&
50+
e.invalidValue == unsendable &&
51+
e.toString().contains("ReceivePort"));
4852
receivePort.close();
4953
}
5054

runtime/tests/vm/dart_2/sendandexit_test.dart

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,25 @@ class NativeWrapperClass extends NativeFieldWrapperClass1 {}
3232

3333
verifyCantSendNative() async {
3434
final receivePort = ReceivePort();
35+
final unsendable = NativeWrapperClass();
3536
Expect.throws(
36-
() => Isolate.exit(receivePort.sendPort, NativeWrapperClass()),
37-
(e) => e.toString().startsWith('Invalid argument: '
38-
'"Illegal argument in isolate message : '
39-
'(object extends NativeWrapper'));
37+
() => Isolate.exit(receivePort.sendPort, unsendable),
38+
(e) =>
39+
e is ArgumentError &&
40+
e.invalidValue == unsendable &&
41+
e.toString().contains("NativeWrapper"));
4042
receivePort.close();
4143
}
4244

4345
verifyCantSendReceivePort() async {
44-
final receivePort = ReceivePort();
46+
final receivePort = RawReceivePort();
47+
final unsendable = receivePort;
4548
Expect.throws(
46-
() => Isolate.exit(receivePort.sendPort, receivePort),
47-
(e) => e.toString().startsWith(
48-
'Invalid argument: "Illegal argument in isolate message : '
49-
'(object is a ReceivePort)\"'));
49+
() => Isolate.exit(receivePort.sendPort, unsendable),
50+
(e) =>
51+
e is ArgumentError &&
52+
e.invalidValue == unsendable &&
53+
e.toString().contains("ReceivePort"));
5054
receivePort.close();
5155
}
5256

runtime/vm/dart_api_impl_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8526,7 +8526,7 @@ TEST_CASE(DartAPI_NativePortPostUserClass) {
85268526
Dart_Handle dart_args[1];
85278527
dart_args[0] = send_port;
85288528
Dart_Handle result = Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
8529-
EXPECT_ERROR(result, "Illegal argument in isolate message");
8529+
EXPECT_ERROR(result, "Invalid argument");
85308530
}
85318531

85328532
// Test send with port closed.
@@ -8537,7 +8537,7 @@ TEST_CASE(DartAPI_NativePortPostUserClass) {
85378537
Dart_Handle dart_args[1];
85388538
dart_args[0] = send_port;
85398539
Dart_Handle result = Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
8540-
EXPECT_ERROR(result, "Illegal argument in isolate message");
8540+
EXPECT_ERROR(result, "Invalid argument");
85418541
}
85428542

85438543
Dart_ExitScope();

runtime/vm/message_snapshot.cc

Lines changed: 12 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ class MessageSerializer : public BaseSerializer {
276276
WriteUnsigned(index);
277277
}
278278

279-
const char* exception_message() const { return exception_message_; }
280279
Thread* thread() const {
281280
return static_cast<Thread*>(StackResource::thread());
282281
}
@@ -291,7 +290,6 @@ class MessageSerializer : public BaseSerializer {
291290
WeakTable* forward_table_new_;
292291
WeakTable* forward_table_old_;
293292
GrowableArray<Object*> stack_;
294-
const char* exception_message_;
295293
};
296294

297295
class ApiMessageSerializer : public BaseSerializer {
@@ -2161,10 +2159,8 @@ class TransferableTypedDataMessageSerializationCluster
21612159
TransferableTypedDataPeer* tpeer =
21622160
reinterpret_cast<TransferableTypedDataPeer*>(peer);
21632161
if (tpeer->data() == nullptr) {
2164-
s->IllegalObject(
2165-
*object,
2166-
"Illegal argument in isolate message"
2167-
" : (TransferableTypedData has been transferred already)");
2162+
s->IllegalObject(*object,
2163+
"TransferableTypedData has been transferred already");
21682164
}
21692165
}
21702166

@@ -3218,8 +3214,7 @@ MessageSerializer::MessageSerializer(Thread* thread)
32183214
: BaseSerializer(thread, thread->zone()),
32193215
forward_table_new_(),
32203216
forward_table_old_(),
3221-
stack_(thread->zone(), 0),
3222-
exception_message_(nullptr) {
3217+
stack_(thread->zone(), 0) {
32233218
isolate()->set_forward_table_new(new WeakTable());
32243219
isolate()->set_forward_table_old(new WeakTable());
32253220
}
@@ -3274,27 +3269,20 @@ void MessageSerializer::Trace(Object* object) {
32743269
if ((clazz.library() != object_store->core_library()) &&
32753270
(clazz.library() != object_store->collection_library()) &&
32763271
(clazz.library() != object_store->typed_data_library())) {
3277-
IllegalObject(*object,
3278-
"Illegal argument in isolate message"
3279-
" : (object is a regular Dart Instance)");
3272+
IllegalObject(*object, "is a regular instance");
32803273
}
32813274
if (clazz.num_native_fields() != 0) {
3282-
char* chars = OS::SCreate(thread()->zone(),
3283-
"Illegal argument in isolate message"
3284-
" : (object extends NativeWrapper - %s)",
3285-
clazz.ToCString());
3286-
IllegalObject(*object, chars);
3275+
IllegalObject(*object, "is a NativeWrapper");
32873276
}
32883277
}
32893278

32903279
// Keep the list in sync with the one in lib/isolate.cc
32913280
#define ILLEGAL(type) \
32923281
if (cid == k##type##Cid) { \
3293-
IllegalObject(*object, \
3294-
"Illegal argument in isolate message" \
3295-
" : (object is a " #type ")"); \
3282+
IllegalObject(*object, "is a " #type); \
32963283
}
32973284

3285+
ILLEGAL(Closure)
32983286
ILLEGAL(FunctionType)
32993287
ILLEGAL(MirrorReference)
33003288
ILLEGAL(ReceivePort)
@@ -3314,15 +3302,6 @@ void MessageSerializer::Trace(Object* object) {
33143302

33153303
#undef ILLEGAL
33163304

3317-
if (cid == kClosureCid) {
3318-
Closure* closure = static_cast<Closure*>(object);
3319-
const char* message = OS::SCreate(
3320-
zone(),
3321-
"Illegal argument in isolate message : (object is a closure - %s)",
3322-
Function::Handle(closure->function()).ToCString());
3323-
IllegalObject(*object, message);
3324-
}
3325-
33263305
if (cid >= kNumPredefinedCids || cid == kInstanceCid ||
33273306
cid == kByteBufferCid) {
33283307
Push(isolate_group()->class_table()->At(cid));
@@ -3570,8 +3549,10 @@ bool ApiMessageSerializer::Trace(Dart_CObject* object) {
35703549

35713550
void MessageSerializer::IllegalObject(const Object& object,
35723551
const char* message) {
3573-
exception_message_ = message;
3574-
thread()->long_jump_base()->Jump(1, Object::snapshot_writer_error());
3552+
const Array& args = Array::Handle(zone(), Array::New(3));
3553+
args.SetAt(0, object);
3554+
args.SetAt(2, String::Handle(zone(), String::New(message)));
3555+
Exceptions::ThrowByType(Exceptions::kArgumentValue, args);
35753556
}
35763557

35773558
BaseDeserializer::BaseDeserializer(Zone* zone, Message* message)
@@ -3994,31 +3975,7 @@ std::unique_ptr<Message> WriteMessage(bool same_group,
39943975

39953976
Thread* thread = Thread::Current();
39963977
MessageSerializer serializer(thread);
3997-
3998-
volatile bool has_exception = false;
3999-
{
4000-
LongJumpScope jump(thread);
4001-
if (setjmp(*jump.Set()) == 0) {
4002-
serializer.Serialize(obj);
4003-
} else {
4004-
has_exception = true;
4005-
}
4006-
}
4007-
4008-
if (has_exception) {
4009-
{
4010-
NoSafepointScope no_safepoint;
4011-
ErrorPtr error = thread->StealStickyError();
4012-
ASSERT(error == Object::snapshot_writer_error().ptr());
4013-
}
4014-
4015-
const String& msg_obj =
4016-
String::Handle(String::New(serializer.exception_message()));
4017-
const Array& args = Array::Handle(Array::New(1));
4018-
args.SetAt(0, msg_obj);
4019-
Exceptions::ThrowByType(Exceptions::kArgument, args);
4020-
}
4021-
3978+
serializer.Serialize(obj);
40223979
return serializer.Finish(dest_port, priority);
40233980
}
40243981

tests/ffi/vmspecific_native_finalizer_isolates_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ Future<void> testSendAndExitFinalizable() async {
5656
Isolate.exit(sendPort, MyFinalizable());
5757
} catch (e) {
5858
print('Expected exception: $e.');
59-
Isolate.exit(sendPort, e);
59+
Isolate.exit(sendPort, e.toString());
6060
}
6161
},
6262
receivePort.sendPort,
6363
);
6464
final result = await receivePort.first;
65-
Expect.type<ArgumentError>(result);
65+
Expect.contains("Invalid argument: is a Finalizable", result);
6666
}
6767

6868
Future<void> testSendAndExitFinalizer() async {
@@ -73,11 +73,11 @@ Future<void> testSendAndExitFinalizer() async {
7373
Isolate.exit(sendPort, MyFinalizable());
7474
} catch (e) {
7575
print('Expected exception: $e.');
76-
Isolate.exit(sendPort, e);
76+
Isolate.exit(sendPort, e.toString());
7777
}
7878
},
7979
receivePort.sendPort,
8080
);
8181
final result = await receivePort.first;
82-
Expect.type<ArgumentError>(result);
82+
Expect.contains("Invalid argument: is a Finalizable", result);
8383
}

tests/ffi_2/vmspecific_native_finalizer_isolates_test.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ Future<void> testSendAndExitFinalizable() async {
5858
Isolate.exit(sendPort, MyFinalizable());
5959
} catch (e) {
6060
print('Expected exception: $e.');
61-
Isolate.exit(sendPort, e);
61+
Isolate.exit(sendPort, e.toString());
6262
}
6363
},
6464
receivePort.sendPort,
6565
);
6666
final result = await receivePort.first;
67-
Expect.type<ArgumentError>(result);
67+
Expect.contains("Invalid argument: is a Finalizable", result);
6868
}
6969

7070
Future<void> testSendAndExitFinalizer() async {
@@ -75,11 +75,11 @@ Future<void> testSendAndExitFinalizer() async {
7575
Isolate.exit(sendPort, MyFinalizable());
7676
} catch (e) {
7777
print('Expected exception: $e.');
78-
Isolate.exit(sendPort, e);
78+
Isolate.exit(sendPort, e.toString());
7979
}
8080
},
8181
receivePort.sendPort,
8282
);
8383
final result = await receivePort.first;
84-
Expect.type<ArgumentError>(result);
84+
Expect.contains("Invalid argument: is a Finalizable", result);
8585
}

0 commit comments

Comments
 (0)