Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[Bug] [Android] Random JNI errors when calling provider_data() or uid() on a valid user right after initializing Auth.

未关闭
#1,671 0 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
android, cpp

调研方向

从 Auth::GetAuth 和 Auth::InitPlatformAuth 开始,然后通过 Auth::UpdateCurrentUser 和 SetImplFromLocalRef 跟踪 JniAuthStateListener_nativeOnAuthStateChanged。初始化后立即运行报告中的对 User::uid() 的重复访问;当压力场景不再产生已删除引用或空对象的 JNI 错误,并且 current_user 的属性仍可使用时,即表示完成。

由索引模型根据 Issue 内容生成。

描述

api: auth new type: question
[REQUIRED] Please fill in the following fields:
  • Pre-built SDK from the website or open-source from this repo: prebuilt release
  • Firebase C++ SDK version: 12.4.0 (already happened with Firebase C++ SDK 11.0.1)
  • Problematic Firebase Component: Auth
  • Other Firebase Components in use: Analytics, Crashlytics, Firestore, Functions, RemoteConfig
  • Platform you are using the C++ SDK on: Mac
  • Platform you are targeting: Android
[REQUIRED] Please describe the issue here:

Crashlytics reports some random crashes a few seconds after startup, during the initialization of our app, when accessing the state of a previously signed in user.
The stacks look like this:

JNI DETECTED ERROR IN APPLICATION: use of deleted global reference 0x3886

  #00  pc 0x000000000008cdd0  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164)
  #01  pc 0x000000000053b0a4  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+2340)
  #02  pc 0x000000000001394c  /system/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+76)
  #03  pc 0x00000000000130cc  /system/lib64/libbase.so (android::base::LogMessage::~LogMessage()+312)
  #04  pc 0x0000000000372930  /apex/com.android.art/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+2596)
  #05  pc 0x0000000000372aa0  /apex/com.android.art/lib64/libart.so (art::JavaVMExt::JniAbortF(char const*, char const*, ...)+188)
  #06  pc 0x000000000058edbc  /apex/com.android.art/lib64/libart.so (art::Thread::DecodeJObject(_jobject*) const+740)
  #07  pc 0x00000000005335bc  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+72)
  #08  pc 0x0000000000533918  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92)
  #09  pc 0x000000000038ca54  /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallObjectMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+656)
  #10  pc 0x0000000001efb0a8  /data/app/~~we2dODBK-dwTNyJ0WwgHVw==/XXX-PL2uZARhnKyZj-sBR8U9ag==/split_config.arm64_v8a.apk!libgame_android.so (_JNIEnv::CallObjectMethod(_jobject*, _jmethodID*, ...)+116) (BuildId: 49d308be143cc46526a72431ce8b6942c800f328)
  #11  pc 0x0000000001db7500  /data/app/~~we2dODBK-dwTNyJ0WwgHVw==/XXX-PL2uZARhnKyZj-sBR8U9ag==/split_config.arm64_v8a.apk!libgame_android.so (firebase::auth::User::provider_data() const+112) (BuildId: 49d308be143cc46526a72431ce8b6942c800f328)

it varies a bit and sometimes the JNI error is : JNI DETECTED ERROR IN APPLICATION: obj == null
Also, sometimes it will crash in firebase::auth::User::uid() instead, there is a call right after provider_data().

Our crash is very similar to this issue, but note that we are not registering any AuthStateListener ourselves: https://github.com/firebase/firebase-cpp-sdk/issues/753

Steps to reproduce:

Have you been able to reproduce this issue with just the Firebase C++ quickstarts ?
No, rate seems low: about 1 crash per day per 10000 users.

Relevant code

Here is what happens on app launch:
Our app starts by initializing the firebase app
firebase::App::Create(env, _activity->clazz);

then about 1 second later, we initialize Auth and try to retrieve some data if the user is signed in

    auth::Auth *auth = auth::Auth::GetAuth(App::GetInstance());           << First call of GetAuth
    auth::User user = auth->current_user();
    if (!user.is_valid())
        return;

    std::vector<auth::UserInfoInterface> data = user.provider_data();     << Crash here
    ...

All our calls to Auth are done from the same native cpp thread.

Investigation:

By looking at the SDK code, it seems this crash could happen if there is a data race where a thread calls Auth::UpdateCurrentUser (more specifically SetImplFromLocalRef(env, j_user, &auth_data->user_impl)) while our native thread is accessing the current_user's properties.

Potential culprit:

From my understanding, the initialization of Auth will synchronously call UpdateCurrentUser, so accessing the user right after should be fine.
But what I also noticed is that Auth::InitPlatformAuth will register a JniAuthStateListener.
I believe addAuthStateListener from FirebaseAuth.java will trigger a callback from a Java Thread after a random delay, which will eventually result in a call to JniAuthStateListener_nativeOnAuthStateChanged and Auth::UpdateCurrentUser from another thread, resulting in a data race.

I was not able to reproduce the crash with the production code, but I was able to get it by calling User::uid() many times right after the init of Auth. Something like this:

    auth::Auth *auth = auth::Auth::GetAuth(App::GetInstance());
    auth::User user = auth->current_user();
    if (!user.is_valid())
        return;

    for (int i = 0; i < 1000000; i++)
        user.uid();
    ...

This generates a crash similar to the one we see in production. It happens around every 5 to 10 app launches. I couldn't get it to crash with user.provider_data() though, maybe it's just less likely because it has more instructions.
Also, I haven't been able to generate the crash when Auth is initialized about 1s before the first user access.

Other notes:
  • We have never seen this crash on other calls to User::uid() or User::provider_data(), only the ones right after the Auth initialization crashes.
  • We also have an iOS version and have never seen any crash there when accessing a User's properties.
主要语言
C++
星标
326
派生
138
平均合并
2 天 16 小时
30 天内合并 PR
3

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

firebase/firebase-cpp-sdk 的其他 Issue

查看 firebase/firebase-cpp-sdk 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。