Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Background isolate throws No top-level getter 'xxx' declared when app is obfuscated #49181

Open
absar opened this issue Jun 4, 2022 · 5 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends.

Comments

@absar
Copy link

absar commented Jun 4, 2022

When app is obfuscated background isolates run by flutter_workmanager throw Dart Unhandled Exception: NoSuchMethodError: No top-level getter 'xxx' declared in Flutter 2.10 and 3. However it works fine without obfuscation in both Flutter 2.10 and 3. It also works with obfuscation in Flutter 2.8.

Steps to reproduce:

  • Add workmanager: ^0.5.0 dependency in pubspec.yaml
  • Create a new flutter App with this code in main.dart
Code
import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';

void bgCallback() {
Workmanager().executeTask((task, inputData) async {
  WidgetsFlutterBinding.ensureInitialized();
  debugPrint('bgCallback | $task was executed. inputData = $inputData');
  return Future.value(true);
});
}

void main() {
WidgetsFlutterBinding.ensureInitialized();
Workmanager().initialize(bgCallback, isInDebugMode: true);
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
  return MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(primarySwatch: Colors.blue),
    home: const MyHomePage(),
  );
}
}

class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
  return Center(
    child: ElevatedButton(
      onPressed: scheduleJob,
      child: const Text('Run BG tasks'),
    ),
  );
}

Future scheduleJob() async {
  await Workmanager().registerOneOffTask(
    'aTestJob',
    'aTestJob',
    existingWorkPolicy: ExistingWorkPolicy.replace,
  );
}
}
  • Build the app with obfuscation using: flutter build apk --obfuscate --split-debug-info=./build/app/outputs/obfuscation_symbols

  • This will generate the APK
    image

  • Install app-release.apk on a physical Android device or a 64bit emulator

  • Run the App and press Run BG tasks, this should schedule a one time Android workmanager job, which should ideally run bgCallback, you will see in the notification that workmanager is trying to run the callback
    image

  • Expected result is to run bgCallback, but you can see in logcat, it will throw Dart Unhandled Exception: NoSuchMethodError: No top-level getter 'xxx' declared.

Complete Logcat
2022-06-04 23:30:58.669 6711-6830/com.example.untitled1 E/flutter: [ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: NoSuchMethodError: No top-level getter 'sKb' declared.
  Receiver: top-level
  Tried calling: sKb, stack trace: Warning: This VM has been configured to produce stack traces that violate the Dart standard.
  *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
  pid: 6711, tid: 6830, name Unknown
  build_id: '9771c8715b0df74d9646fccb467f9b57'
  isolate_dso_base: 78dc80f0b000, vm_dso_base: 78dc80f0b000
  isolate_instructions: 78dc80fa6e70, vm_instructions: 78dc80fa3000
      #00 abs 000078dc80fc7712 virt 00000000000bc712 _kDartIsolateSnapshotInstructions+0x208a2
2022-06-04 23:30:58.669 6711-6830/com.example.untitled1 E/flutter: [ERROR:flutter/runtime/dart_isolate.cc(668)] Could not resolve main entrypoint function.
2022-06-04 23:30:58.669 6711-6830/com.example.untitled1 E/flutter: [ERROR:flutter/runtime/dart_isolate.cc(167)] Could not run the run main Dart entrypoint.
2022-06-04 23:30:58.669 6711-6830/com.example.untitled1 E/flutter: [ERROR:flutter/runtime/runtime_controller.cc(382)] Could not create root isolate.
2022-06-04 23:30:58.669 6711-6830/com.example.untitled1 E/flutter: [ERROR:flutter/shell/common/shell.cc(600)] Could not launch engine with configuration.

Environment:

  • Dart SDK version: 2.17.1 (stable) (Tue May 17 17:58:21 2022 +0000) on "windows_x64"
  • Flutter Channel stable 3.0.1
  • OS: Windows 10
  • Android device and Android 11 emulator
@a-siva
Copy link
Contributor

a-siva commented Jun 6, 2022

//cc @aam

@xiaoyaoking
Copy link

Had the same problem. Turn off obfuscation The problem still exists.

@absar
Copy link
Author

absar commented Jun 14, 2022

@a-siva @mraleph can someone please look into it, it's preventing production rollouts for obfuscated apps

@mraleph
Copy link
Member

mraleph commented Jun 15, 2022

This is working as intended and ultimately has nothing to do with with obfuscation. If you try your code on master channel of Flutter you will discover that it does not work either even without obfuscation.

As it stands now to fix things you need to annotate bgCallback with @pragma('vm:entry-point'):

@pragma('vm:entry-point')
void bgCallback() {
  // ...
}

The underlying problem is that PluginUtilities.getCallbackHandle/getCallbackFromHandle assumes that you can lookup arbitrary top-level static functions by name, which is not true and only ever worked by accident rather than design.

We have a problem on our hands - plugins that use PluginUtilities without telling users to annotate static functions with entry-point pragma are essentially broken. We can opt-in to fix this by always retaining top-level functions in lookup dictionaries if they were ever torn-off, but I'd say this is rather suboptimal.

/cc @bkonyi @rmacnak-google @goderbauer @chinmaygarde @Hixie

@absar
Copy link
Author

absar commented Jun 15, 2022

Thank you very much mraleph it works with @pragma('vm:entry-point'). Am happy to close the issue as long as this is documented somewhere for plugin authors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends.
Projects
None yet
Development

No branches or pull requests

4 participants