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

NPE in obfuscated code after calling trace.stop() #1383

Closed
sn-michiyo opened this issue Mar 23, 2020 · 11 comments
Closed

NPE in obfuscated code after calling trace.stop() #1383

sn-michiyo opened this issue Mar 23, 2020 · 11 comments
Assignees
Milestone

Comments

@sn-michiyo
Copy link

Describe your environment

  • Android Studio version: 3.6.1
  • Firebase Component: Performance
  • Component version: 19.0.0

Describe the problem

Crashlytics is reporting 80 users experiencing a null pointer exception When calling trace.stop(); We haven't seen this during development and trace object itself itsn't null; the crash comes in the obfuscated firebase code. Is there anything we can to prevent the crash?

Fatal Exception: java.lang.NullPointerException
Attempt to invoke virtual method 'com.google.android.gms.internal.firebase-perf.zzcr com.google.firebase.perf.internal.zzq.zzbf()' on a null object reference
com.google.firebase.perf.internal.zzq.zza (zzq.java:39)
com.google.firebase.perf.metrics.zzd.zzcd (zzd.java:20)
com.google.firebase.perf.metrics.Trace.stop (Trace.java:87)

app-level build.gradle:

implementation 'com.google.firebase:firebase-perf:19.0.0'
...
apply plugin: 'com.google.firebase.firebase-perf'

I don't see anything in the Trace docs about NPEs, and didn't find any mention of this in the issues for this repo.

I also looked at the release notes for Performance Monitoring for 19.0.1, 19.0.2, 19.0.3, 19.0.4, and 19.0.5 for mention of a NPE to see if upgrading would fix the issue, but don't see any mention of it.

@ramanpreetSinghKhinda
Copy link
Contributor

ramanpreetSinghKhinda commented Mar 23, 2020

Internally Tracking in b/152218504

@ramanpreetSinghKhinda
Copy link
Contributor

ramanpreetSinghKhinda commented Mar 23, 2020

Dry run on a Sample App doesn't yield any NPE and looks like it's not reproducible at your end too.

Can you please (if possible) ping here the usage of that Trace object (Crashlytics provides that information in the Stack Trace I guess) which is throwing NPE, like:

  • How you are creating and stopping that Trace?

  • Are you using Trace.CREATOR?

  • Do all users report NPE from the same usage or there are different code paths each time?

  • Any multithreading or something different you are doing in between would be helpful to know as well

@sn-michiyo
Copy link
Author

Right, I haven't been able to reproduce.

The basic usage looks like

    val firebasePerformance: FirebasePerformance = ...
    val attributes: MutableMap<String, String> = ...
    val newTrace = firebasePerformance.newTrace(name)

    for ((k, v) in attributes) {
        newTrace.putAttribute(k, v)
    }

    newTrace.start()

and

 val trace: Trace? =  // get trace from data structure where it was stored
 trace?.stop() ?: return

We are not using Trace.CREATOR. There may be multiple traces that have been started and not yet stopped.

I belatedly realized that the crash has affected many more users if I expand the time period, so I just looked at the first 100 crash reports. While the "stop trace" code is being called from four different places in our app, the stack traces (that I looked at) only come from two of them.

The crashing call to the "stop tracking" code originates in a call to Completable's doFinally block in one case or in a call to Single's doFinally block in the other. The other two usages of "stop trace" code, which I did not see in the stack traces, do not originate from inside rxjava code.

In case it's relevant:

    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.0'

@sn-michiyo
Copy link
Author

I should note, though, that the calls to "stop tracking" code in the doFinally blocks happen a lot more frequently than the other calls to "stop tracking" code.

@sn-michiyo
Copy link
Author

@ramanpreetSinghKhinda would putting the call to stop() inside a try block have any negative repercussions? (Beyond not getting results for that particular trace, but presumably we aren't getting those anyway when the app crashes.)

@ramanpreetSinghKhinda
Copy link
Contributor

Thanks @sn-michiyo for the details.

I am preparing a fix for this and plan to rollout in the upcoming release. Will update here with more details on that.

@ramanpreetSinghKhinda
Copy link
Contributor

Regarding this comment: There should not be any negative effect due to this

@zijianjoy zijianjoy added this to the M68 milestone Mar 31, 2020
@ramanpreetSinghKhinda
Copy link
Contributor

Hi @sn-michiyo ,

I have some more questions:

Q1. Can you explain what type of data structure are you using to store and thus retrieve the trace object?

Q2. Are you passing the trace object within activities? For e.g. using Intent or something?

Q3. Are you accessing the trace object outside of the lifecycle of the activity? For e.g is the action closing the app and then reopening trying to access your previously created trace objects from your data structure?

@google-oss-bot
Copy link
Contributor

Hey @sn-michiyo. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@MichalFrSN
Copy link

Hi @ramanpreetSinghKhinda , Following your conversation with @sn-michiyo:
We store the Trace object locally on ApplicationScope class within a MutableMap:
val customTraceMap : MutableMap<String, Trace>

We don't pass the Trace obj within activities, we create & store the Trace object in the same class:
for ((k, v) in mutableAttributes) { newTrace.putAttribute(k, v) }
customTraceMap[name] = newTrace customTraceMap[name]?.start()

and stop the traces:
customTraceMap[name]?.stop() ?: return

@ramanpreetSinghKhinda
Copy link
Contributor

This should be fixed in v19.0.6.

Release Notes

Please reopen if the issue persists.

@firebase firebase locked and limited conversation to collaborators May 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants