[vm] Fix crash on GC after service id zone deletion.

TEST=ci
Bug: https://github.com/dart-lang/sdk/issues/62154
Change-Id: Ib1ca89aa7344614de1ffc2fae6e6f93850e4a1b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/466880
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak
2025-12-08 13:17:40 -08:00
committed by Commit Queue
parent f94c325bd1
commit e53115a98c
3 changed files with 24 additions and 25 deletions
@@ -25,6 +25,17 @@ void testeeMain() {
debugger(); // LINE_A
}
Future checkZone(isolateId, client, idZone) async {
final result = await client.evaluateInFrame(
isolateId,
0,
'abcString',
idZoneId: idZone.id,
);
await client.callMethod('_collectAllGarbage', isolateId: isolateId);
await client.getObject(isolateId, result.id, idZoneId: idZone.id);
}
final idZoneDeletionOnDisconnectTests = <IsolateTest>[
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_A),
@@ -38,12 +49,7 @@ final idZoneDeletionOnDisconnectTests = <IsolateTest>[
);
// Confirm that [idZone1] can be used.
await client1.evaluateInFrame(
isolateId,
0,
'abcString',
idZoneId: idZone1.id,
);
await checkZone(isolateId, client1, idZone1);
final client2 = await vmServiceConnectUri(client1.wsUri!);
final idZone2 = await client2.createIdZone(
@@ -53,35 +59,20 @@ final idZoneDeletionOnDisconnectTests = <IsolateTest>[
);
// Confirm that [idZone2] can be used.
await client2.evaluateInFrame(
isolateId,
0,
'abcString',
idZoneId: idZone2.id,
);
await checkZone(isolateId, client2, idZone2);
// Disposing of [client2] should delete [idZone2];
await client2.dispose();
// Confirm that [idZone2] can be no longer be used.
try {
await client1.evaluateInFrame(
isolateId,
0,
'abcString',
idZoneId: idZone2.id,
);
await checkZone(isolateId, client1, idZone2);
fail('successfully used an ID zone that should have been deleted');
} on RPCError catch (e) {
expect(e.code, RPCErrorKind.kInvalidParams.code);
}
// Confirm that [idZone1] can still be used.
await client1.evaluateInFrame(
isolateId,
0,
'abcString',
idZoneId: idZone1.id,
);
await checkZone(isolateId, client1, idZone1);
},
];
+6
View File
@@ -71,6 +71,8 @@ final tests = <IsolateTest>[
final cObjectId2 = cInstanceRef2.id!;
expect(cObjectId2, 'objects/1/1');
await service.callMethod('_collectAllGarbage', isolateId: isolateId);
final cInstance2 = await service.getObject(isolateId, cObjectId2);
expect(cInstance2.type, 'Instance');
@@ -188,6 +190,8 @@ final tests = <IsolateTest>[
idZone3.id!,
);
await service.callMethod('_collectAllGarbage', isolateId: isolateId);
try {
await service.getObject(isolateId, cObjectId1);
fail('successfully retrieved object using expired ID');
@@ -223,6 +227,8 @@ final tests = <IsolateTest>[
idZone4.id!,
);
await service.callMethod('_collectAllGarbage', isolateId: isolateId);
try {
await service.evaluateInFrame(
isolateId,
+3 -1
View File
@@ -3042,7 +3042,9 @@ void IsolateGroup::VisitSharedPointers(ObjectPointerVisitor* visitor,
if (visitor->trace_object_id_rings()) {
for (Isolate* isolate : isolates_) {
for (intptr_t i = 0; i < isolate->NumServiceIdZones(); ++i) {
isolate->GetServiceIdZone(i)->VisitPointers(visitor);
if (auto ring = isolate->GetServiceIdZone(i)) {
ring->VisitPointers(visitor);
}
}
}
}