firebase / firebase/firebase-cpp-sdk
[Bug] Deadlock in firebase::auth::IdTokenRefreshThread
- 主要言語
- C++
- スター
- 326
- フォーク
- 137
- 平均マージ
- 3日 9時間
- マージ済み PR(30日)
- 5
説明
### [REQUIRED] Please fill in the following fields:
* Pre-built SDK from the [website](https://firebase.google.com/download/cpp) or open-source from this repo: open-source from this repo
* Firebase C++ SDK version: 11.4.0
* Problematic Firebase Component: auth
* Other Firebase Components in use: database
* Platform you are using the C++ SDK on: Mac, Windows
* Platform you are targeting: desktop
### [REQUIRED] Please describe the issue here:
Deadlock in IdTokenRefreshThread which causes the entire app to hang, e.g., Database cannot be safely deleted since it is deadlocked on destruction by waiting IdTokenRefreshThread to finish
1. IdTokenRefreshThread holds `refresh_thread->ref_count_mutex_` and `auth->auth_data_->future_impl.mutex()`. Then it accesses `refresh_thread->token_refresh_listener_.GetTokenTimestamp()` which has its own mutex
```
#0 firebase::auth::IdTokenRefreshThread::Initialize(firebase::auth::AuthData*)::$_4::operator()(firebase::auth::IdTokenRefreshThread*) const at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/auth_desktop.cc:818
#1 firebase::auth::IdTokenRefreshThread::Initialize(firebase::auth::AuthData*)::$_4::__invoke(firebase::auth::IdTokenRefreshThread*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/auth_desktop.cc:805
```
2. Another worker thread fires an event about token change. `IdTokenRefreshListener::OnIdTokenChanged` locks its own mutex first and then `auth->auth_data_->future_impl.mutex()`
```
#0 firebase::auth::IdTokenRefreshListener::OnIdTokenChanged(firebase::auth::Auth*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/auth_desktop.cc:135
#1 firebase::auth::NotifyIdTokenListeners(firebase::auth::AuthData*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/auth.cc:362
#2 0firebase::auth::AuthenticationResult::SetAsCurrentUser(firebase::auth::AuthData*) const at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/authentication_result.cc:64
#3 void firebase::auth::PerformSignInFlow(firebase::auth::AuthDataHandle*) at /Users/venhe/tmp/Firebase/Firebase/auth/src/desktop/sign_in_flow.h:125
```
Deadlock happens if IdTokenRefreshThread just about to call `GetTokenTimestamp` and if IdTokenRefreshListener::OnIdTokenChanged successfully acquired its mutex.
#### Steps to reproduce:
Hard to reproduce, but happens quite often.
What happened? How can we make the problem occur?
Simulate it, e.g., call IdTokenRefreshListener::OnIdTokenChanged in a loop, and it will definitely deadlock at some point
If you have a downloadable sample project that reproduces the bug you're reporting, you will
likely receive a faster response on your issue.
コントリビューションガイド
調査の方向性
auth/src/desktop/auth_desktop.cc の IdTokenRefreshThread::Initialize(805-818 行付近)と、135 行目の IdTokenRefreshListener::OnIdTokenChanged から始め、auth/src/auth.cc、authentication_result.cc、sign_in_flow.h にある関連する呼び出しを追跡します。OnIdTokenChanged を繰り返し呼び出して報告された順序を再現し、競合する mutex の取得を調べます。シミュレートした race でデッドロックが発生しなくなり、application または Database の破棄を完了できれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- cpp
- 領域
- authentication, databases
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- 説明が足りない
- 初心者へのやさしさ
- 30/100