Skip to content

Commit 5d9efbc

Browse files
buenaflorcodexcursoragent
committed
fix(flutter): Skip Android worker reads after close
Return null for Android core worker read paths after shutdown so closed workers do not fall back to JNI work on the main isolate. Co-Authored-By: GPT-5.5 <noreply@openai.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent b163866 commit 5d9efbc

2 files changed

Lines changed: 30 additions & 0 deletions

File tree

packages/flutter/lib/src/native/java/android_core_worker.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class AndroidCoreWorker {
100100
}
101101

102102
FutureOr<List<DebugImage>?> loadDebugImages(SentryStackTrace stackTrace) {
103+
if (_isClosed) return null;
104+
103105
final instructionAddresses =
104106
stackTrace.frames.map((f) => f.instructionAddr).nonNulls.toList(
105107
growable: false,
@@ -140,6 +142,8 @@ class AndroidCoreWorker {
140142
}
141143

142144
FutureOr<Map<String, dynamic>?> loadContexts() {
145+
if (_isClosed) return null;
146+
143147
final client = _worker;
144148
if (client == null) {
145149
return _loadContexts(automatedTestMode: _config.automatedTestMode);

packages/flutter/test/native/android_core_worker_test_real.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,20 @@ void main() {
272272
expect(await resultFuture, isNull);
273273
});
274274

275+
test('returns null for debug images after close', () async {
276+
final fixture = _Fixture();
277+
fixture.options.automatedTestMode = true;
278+
final worker = fixture.getSut();
279+
await worker.start();
280+
await worker.close();
281+
282+
final result = worker.loadDebugImages(SentryStackTrace(frames: [
283+
SentryStackFrame(instructionAddr: '0x1'),
284+
]));
285+
286+
expect(await Future<List<DebugImage>?>.value(result), isNull);
287+
});
288+
275289
test('requests native contexts', () async {
276290
final fixture = _Fixture();
277291
final worker = fixture.getSut();
@@ -303,6 +317,18 @@ void main() {
303317
expect(await resultFuture, isNull);
304318
});
305319

320+
test('returns null for native contexts after close', () async {
321+
final fixture = _Fixture();
322+
fixture.options.automatedTestMode = true;
323+
final worker = fixture.getSut();
324+
await worker.start();
325+
await worker.close();
326+
327+
final result = worker.loadContexts();
328+
329+
expect(await Future<Map<String, dynamic>?>.value(result), isNull);
330+
});
331+
306332
test('sends breadcrumb update and awaits response', () async {
307333
final fixture = _Fixture();
308334
final worker = fixture.getSut();

0 commit comments

Comments
 (0)