Skip to content

Commit 4617198

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm] Add option for GC at [re]throw.
Add a reduced test for crash / false ConcurrentModificationError observed by the isolate stress test. TEST=ci Bug: #60017 Change-Id: I665a7ec48c150d270e751ab13393384613d44674 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/408201 Commit-Queue: Ryan Macnak <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
1 parent 3700d33 commit 4617198

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
// VMOptions=--gc_at_throw --force_evacuation
6+
7+
import 'package:expect/expect.dart';
8+
import 'dart:async';
9+
10+
controlFlow() {
11+
for (final FutureOr<T> Function<T>(T) func in <dynamic>[id, future]) {
12+
try {
13+
try {
14+
throw "string";
15+
} catch (e) {
16+
Expect.equals("string", e);
17+
rethrow;
18+
} finally {
19+
Expect.equals(0, func(0));
20+
}
21+
} catch (e) {
22+
Expect.equals("string", e);
23+
} finally {
24+
Expect.equals(0, func(0));
25+
}
26+
}
27+
}
28+
29+
FutureOr<T> future<T>(T value) => value;
30+
FutureOr<T> id<T>(T value) => value;
31+
32+
main() {
33+
for (int i = 0; i < 100; i++) {
34+
controlFlow();
35+
}
36+
}

runtime/tools/dartfuzz/flag_fuzzer.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ final gcFlags = [
5252
"--verify_before_gc",
5353
"--verify_store_buffer",
5454
"--write_protect_code",
55+
"--gc_at_throw",
5556
];
5657

5758
final compilerFlags = [

runtime/vm/runtime_entry.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ DEFINE_FLAG(bool,
111111
verbose_stack_overflow,
112112
false,
113113
"Print additional details about stack overflow.");
114+
DEFINE_FLAG(bool, gc_at_throw, false, "Run evacuating GC at throw and rethrow");
114115

115116
DECLARE_FLAG(int, reload_every);
116117
DECLARE_FLAG(bool, reload_every_optimized);
@@ -1587,11 +1588,25 @@ DEFINE_RUNTIME_ENTRY(TypeCheck, 7) {
15871588
}
15881589

15891590
DEFINE_RUNTIME_ENTRY(Throw, 1) {
1591+
if (FLAG_gc_at_throw) {
1592+
isolate->group()->heap()->CollectGarbage(thread, GCType::kEvacuate,
1593+
GCReason::kDebugging);
1594+
isolate->group()->heap()->CollectAllGarbage(GCReason::kDebugging,
1595+
/*compact=*/true);
1596+
}
1597+
15901598
const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0));
15911599
Exceptions::Throw(thread, exception);
15921600
}
15931601

15941602
DEFINE_RUNTIME_ENTRY(ReThrow, 3) {
1603+
if (FLAG_gc_at_throw) {
1604+
isolate->group()->heap()->CollectGarbage(thread, GCType::kEvacuate,
1605+
GCReason::kDebugging);
1606+
isolate->group()->heap()->CollectAllGarbage(GCReason::kDebugging,
1607+
/*compact=*/true);
1608+
}
1609+
15951610
const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0));
15961611
const Instance& stacktrace =
15971612
Instance::CheckedHandle(zone, arguments.ArgAt(1));

0 commit comments

Comments
 (0)