Skip to content

Commit c1caa5c

Browse files
aamCommit Queue
authored andcommitted
[vm/isolates] Confirm isolate terminate capability before terminating it.
Fixes #61313 TEST=isolate_restricted_kill_test Change-Id: I52a41b1c71ceb02c3f91c580dc7939eb3cfae4c8 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/445300 Commit-Queue: Alexander Aprelev <[email protected]> Reviewed-by: Slava Egorov <[email protected]>
1 parent fb809c2 commit c1caa5c

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
//
5+
// Verifies that restricted isolate can't be terminated.
6+
//
7+
import 'dart:isolate';
8+
9+
import 'package:expect/async_helper.dart';
10+
import 'package:expect/expect.dart';
11+
12+
main() async {
13+
asyncStart();
14+
15+
int receivedCounter = -1;
16+
final rp = RawReceivePort((value) {
17+
receivedCounter = value;
18+
});
19+
final rpExit = ReceivePort();
20+
21+
final isolate = await Isolate.spawn(
22+
(sendPort) async {
23+
int counter = 0;
24+
while (true) {
25+
sendPort.send(counter++);
26+
await Future.delayed(Duration(milliseconds: 100));
27+
}
28+
},
29+
rp.sendPort,
30+
onExit: rpExit.sendPort,
31+
);
32+
33+
// Wait for the isolate to start.
34+
while (receivedCounter < 0) {
35+
await Future.delayed(Duration(milliseconds: 100));
36+
}
37+
38+
// Create restricted isolate, the one that can't be terminated.
39+
final restricted = Isolate(isolate.controlPort);
40+
restricted.kill();
41+
final before_kill = receivedCounter;
42+
// Wait couple cycles to ensure isolate is still alive.
43+
while (receivedCounter < before_kill + 2) {
44+
await Future.delayed(Duration(milliseconds: 100));
45+
}
46+
47+
// Now kill the original isolate and wait for it to exit.
48+
isolate.kill();
49+
await rpExit.first;
50+
51+
rp.close();
52+
asyncEnd();
53+
}

runtime/vm/isolate.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,9 +1269,9 @@ ErrorPtr IsolateMessageHandler::HandleLibMessage(const Array& message) {
12691269
if (!obj.IsSmi()) return Error::null();
12701270
const intptr_t priority = Smi::Cast(obj).Value();
12711271
if (priority == Isolate::kImmediateAction) {
1272-
Thread::Current()->StartUnwindError();
12731272
obj = message.At(2);
12741273
if (I->VerifyTerminateCapability(obj)) {
1274+
Thread::Current()->StartUnwindError();
12751275
// We will kill the current isolate by returning an UnwindError.
12761276
if (msg_type == Isolate::kKillMsg) {
12771277
const String& msg = String::Handle(

0 commit comments

Comments
 (0)