firebase / flutterfire

🔥 A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.7k stars 3.97k forks source link

[firebase_crashlytics] No stack traces for issues on Crashlytics dashboard #2644

Closed talent-apps closed 3 years ago

talent-apps commented 4 years ago

After upgrading to Flutter SDK 1.17, where dart obfuscation is supported by default, no stack traces appear for crashes that originate from dart code on the Crashlytics dashboard on the Firebase console. On earlier versions of the Flutter SDK they were reported with their obfuscated names.

TahaTesser commented 4 years ago

Hi @talent-apps Can you please provide your flutter doctor -v, your flutter run --verbose and a minimal complete reproducible code sample. Thank you

talent-apps commented 4 years ago

Output of flutter doctor -v:

[√] Flutter (Channel stable, v1.17.1, on Microsoft Windows [Version 10.0.18363.836], locale en-US) • Flutter version 1.17.1 at C:\flutter • Framework revision f7a6a7906b (2 weeks ago), 2020-05-12 18:39:00 -0700 • Engine revision 6bc433c6b6 • Dart version 2.8.2

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2) • Android SDK at C:\Users\XXX\AppData\Local\Android\Sdk • Platform android-29, build-tools 29.0.2 • ANDROID_HOME = C:\Users\XXX\AppData\Local\Android\Sdk • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04) • All Android licenses accepted.

[√] Android Studio (version 3.6) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin version 45.1.1 • Dart plugin version 192.8052 • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

[√] VS Code (version 1.45.1) • VS Code at C:\Users\XXX\AppData\Local\Programs\Microsoft VS Code • Flutter extension version 3.10.2

[!] Connected device ! No devices available

! Doctor found issues in 1 category.

talent-apps commented 4 years ago

The relevant piece of code is the main function of the app:

void main() async {

  Crashlytics.instance.enableInDevMode = false;
  // Pass all uncaught errors to Crashlytics.
  FlutterError.onError = (FlutterErrorDetails details) {
    Crashlytics.instance.recordFlutterError(details);
  };

  runApp(App());
}
talent-apps commented 4 years ago

Any update on this? The official crashlytics plugin is practically useless with Flutter 1.17.X versions. Uncaught exceptions are not reported properly.

renzo800000 commented 4 years ago

Please prioritize this issue, since crashlytics is useless without stack traces.

For example, If I now receive a NoSuchMethodError (toString() called on null), I have no idea where it comes from, so I can't actually fix it (and fixing issues is like the whole point of crashlytics).

talent-apps commented 4 years ago

Any update on this? The fact that this ticket is still open for months is nothing short of amazing. Crashes that occur in Flutter apps in production do not include stack traces, leaving developers practically blind and incapable of improving the stability of their Flutter apps.

talent-apps commented 3 years ago

Any update? At the moment, the firebase_crashlytics plugin is useless for apps that use Dart obfuscation. Does this plugin have any owners? Why such a crucial issue is left unaddressed?

untp commented 3 years ago

Obfuscated stack traces appear as:

last-state

Remove (.java) and add 4 spaces every line like this:

    #00 abs 0 virt 00000000001af92e _kDartIsolateSnapshotInstructions+0x1a192e
    #01 abs 0 virt 00000000001afaac _kDartIsolateSnapshotInstructions+0x1a1aac
    #02 abs 0 virt 0000000000086f92 _kDartIsolateSnapshotInstructions+0x78f92
    #03 abs 0 virt 000000000019de1c _kDartIsolateSnapshotInstructions+0x18fe1c
    #04 abs 0 virt 000000000006cb22 _kDartIsolateSnapshotInstructions+0x5eb22
    #05 abs 0 virt 000000000018c9ed _kDartIsolateSnapshotInstructions+0x17e9ed
    #06 abs 0 virt 00000000000f8ae9 _kDartIsolateSnapshotInstructions+0xeaae9
    #07 abs 0 virt 000000000011d7f6 _kDartIsolateSnapshotInstructions+0x10f7f6
    #08 abs 0 virt 000000000006b7c6 _kDartIsolateSnapshotInstructions+0x5d7c6
    #09 abs 0 virt 00000000001c71e6 _kDartIsolateSnapshotInstructions+0x1b91e6
    #10 abs 0 virt 00000000001c7169 _kDartIsolateSnapshotInstructions+0x1b9169
    #11 abs 0 virt 00000000000f6e25 _kDartIsolateSnapshotInstructions+0xe8e25
    #12 abs 0 virt 000000000005704c _kDartIsolateSnapshotInstructions+0x4904c
    #13 abs 0 virt 0000000000056fbe _kDartIsolateSnapshotInstructions+0x48fbe
    #14 abs 0 virt 00000000000bbbe6 _kDartIsolateSnapshotInstructions+0xadbe6
    #15 abs 0 virt 0000000000056e9a _kDartIsolateSnapshotInstructions+0x48e9a
    #16 abs 0 virt 0000000000056a9c _kDartIsolateSnapshotInstructions+0x48a9c
    #17 abs 0 virt 00000000000569af _kDartIsolateSnapshotInstructions+0x489af
    #18 abs 0 virt 0000000000056809 _kDartIsolateSnapshotInstructions+0x48809
    #19 abs 0 virt 000000000005bc39 _kDartIsolateSnapshotInstructions+0x4dc39
    #20 abs 0 virt 0000000000041e7c _kDartIsolateSnapshotInstructions+0x33e7c
    #21 abs 0 virt 000000000011a489 _kDartIsolateSnapshotInstructions+0x10c489
    #22 abs 0 virt 000000000012dea1 _kDartIsolateSnapshotInstructions+0x11fea1
    #23 abs 0 virt 0000000000026dc2 _kDartIsolateSnapshotInstructions+0x18dc2
    #24 abs 0 virt 0000000000026cc6 _kDartIsolateSnapshotInstructions+0x18cc6

After saving this to a file (error.txt), run flutter symbolize -d symbols/app.android-x64.symbols -i error.txt

#0      _MyAppState.build.<anonymous closure>.<anonymous closure> (package:firebase_crashlytics_example/main.dart:183)
#1      _MyAppState.build.<anonymous closure>.<anonymous closure> (package:firebase_crashlytics_example/main.dart:176)
#2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:993)
#3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1111)
#4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:183)
#5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:598)
#6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:304)
#7      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:222)
#8      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:476)
#9      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:77)
#10     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:122)
#11     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377)
#12     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:120)
#13     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:106)
#14     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:358)
#15     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:338)
#16     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:267)
#17     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:295)
#18     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:240)
#19     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:213)
#20     _rootRunUnary (dart:async/zone.dart:1206)
#21     _CustomZone.runUnary (dart:async/zone.dart:1100)
#22     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005)
#23     _invoke1 (dart:ui/hooks.dart:265)
#24     _dispatchPointerDataPacket (dart:ui/hooks.dart:174)
talent-apps commented 3 years ago

@untp Great news! When will it be merged?

untp commented 3 years ago

I don't know. I am not a maintainer. We need to wait the review process.

krokyze commented 3 years ago

Hopefully someday Firebase will support this automatically ❤️

talent-apps commented 3 years ago

@untp We tested the PR and we successfully managed to deobfuscate crashes from the Crashlytics reports. One question remains: each report on the dashboard contains a reason field which is also obfuscated. Example: Error thrown Instance of 'Ax'. Is there a way to deobfuscate it? It could be very helpful for the analysis.

untp commented 3 years ago

Hi @talent-apps

Thanks for testing my PR.

If you want to deobfuscate it too, you need CodeSourceMap. You can generate that file with adding build options:

android/gradle.properties

...
extra-gen-snapshot-options=--save-obfuscation-map=symbols/android.mapping.json

ios/Flutter/Release.xcconfig

...
EXTRA_GEN_SNAPSHOT_OPTIONS=--save-obfuscation-map=symbols/ios.mapping.json

Then you can run flutter build <target> --obfuscate --split-debug-info=symbols.

You will get a json file containing an array ["original[0]", "obfuscated[0]", "original[1]", "obfuscated[1]", ...]. With this file, you can find out what Ax symbol is.

talent-apps commented 3 years ago

@untp Thanks for the quick response. We will test it and update.

deepak786 commented 3 years ago

Have a similar issue:

Code to setup the Firebase crashlytics:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // initialize the firebase
  await Firebase.initializeApp();

  // Pass all uncaught errors from the framework to Crashlytics.
  FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;

 runApp(MyApp());
}

From the dart obfuscated code, when tried to record the Exception manually like:

throw Exception('exception from obfuscated apk');

Logcat shows:

I/flutter: Exception: exception from obfuscated apk
E/FLTFirebaseCrashlytics: Unable to generate stack trace element from Dart error.

After some time, Crashlytics shows the non-fattal error as below:

Screen Shot 2021-01-18 at 7 33 42 PM

But it is working fine if the dart code is not obfuscated.

deepak786 commented 3 years ago

Update with the pull request: Tested the pull request https://github.com/FirebaseExtended/flutterfire/pull/4407 and it generated the below stack trace. Now not getting the error Unable to generate stack trace element from Dart error. So I think it worked. Also tested the below stack trace with symbols to read it and it also worked fine.

But the crashlytics shows that This VM has been configured to produce stack traces that violate the Dart standard. @untp can you please check this?

Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: Exception: exception from obfuscated apk. Error thrown Instance of 'HA'.
       at This VM has been configured to produce stack traces that violate the Dart standard.(This VM has been configured to produce stack traces that violate the Dart standard.java)
       at .*** *** *** *** *** *** *** *** *** *** *** *** *** *** ***(.java)
       at .    #00 abs 0 virt 00556c27 _kDartIsolateSnapshotInstructions+0x54ac27(.java)
       at .    #01 abs 0 virt 00137df3 _kDartIsolateSnapshotInstructions+0x12bdf3(.java)
       at .    #02 abs 0 virt 0007a15f _kDartIsolateSnapshotInstructions+0x6e15f(.java)
       at .    #03 abs 0 virt 004168ab _kDartIsolateSnapshotInstructions+0x40a8ab(.java)
       at .    #04 abs 0 virt 001cf227 _kDartIsolateSnapshotInstructions+0x1c3227(.java)
       at .    #05 abs 0 virt 001cf11f _kDartIsolateSnapshotInstructions+0x1c311f(.java)
       at .    #06 abs 0 virt 0018d913 _kDartIsolateSnapshotInstructions+0x181913(.java)
       at .    #07 abs 0 virt 0018d663 _kDartIsolateSnapshotInstructions+0x181663(.java)
       at .    #08 abs 0 virt 00061477 _kDartIsolateSnapshotInstructions+0x55477(.java)
       at .    #09 abs 0 virt 00061063 _kDartIsolateSnapshotInstructions+0x55063(.java)
       at .    #10 abs 0 virt 0007117f _kDartIsolateSnapshotInstructions+0x6517f(.java)
       at .    #11 abs 0 virt 00071317 _kDartIsolateSnapshotInstructions+0x65317(.java)
       at .    #12 abs 0 virt 000717ef _kDartIsolateSnapshotInstructions+0x657ef(.java)
       at .    #13 abs 0 virt 0001c987 _kDartIsolateSnapshotInstructions+0x10987(.java)
       at .    #14 abs 0 virt 00466bfb _kDartIsolateSnapshotInstructions+0x45abfb(.java)
       at .    #15 abs 0 virt 0046bef7 _kDartIsolateSnapshotInstructions+0x45fef7(.java)
       at .    #16 abs 0 virt 0003a04f _kDartIsolateSnapshotInstructions+0x2e04f(.java)
       at .    #17 abs 0 virt 0003ed4f _kDartIsolateSnapshotInstructions+0x32d4f(.java)
       at .    #18 abs 0 virt 0003ecdf _kDartIsolateSnapshotInstructions+0x32cdf(.java)
untp commented 3 years ago

@deepak786 Thanks for testing my PR. You can ignore this warning. Also, this warning will be removed in future versions of Dart (See dart-lang/sdk#43388).

marcosmko commented 3 years ago

Hello!

Any update on this?

deepak786 commented 3 years ago

@untp I'm already using your pull request code for the crashlytics like below under dependency_overrides:

firebase_crashlytics:
    git:
      url: https://github.com/untp/flutterfire.git
      ref: obfuscated-stack-traces
      path: packages/firebase_crashlytics/firebase_crashlytics

But right now getting the error:

Because every version of firebase_crashlytics from git depends on firebase_core ^0.8.0-nullsafety.0 and your_app depends on firebase_core 1.0.3, firebase_crashlytics from git is forbidden.
So, because your_app depends on firebase_crashlytics from git, version solving failed.

Master branch: https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml

obfuscated-stack-traces: https://github.com/untp/flutterfire/blob/obfuscated-stack-traces/packages/firebase_crashlytics/firebase_crashlytics/pubspec.yaml

untp commented 3 years ago

@deepak786 ~I created updated branch. You can try obfuscated-stack-traces-updated.~ UPDATE: It is merged. You can use firebase_crashlytics: ^2.0.1