firebase-cpp-sdk icon indicating copy to clipboard operation
firebase-cpp-sdk copied to clipboard

Crash in Functions on MacOS when using authentication

Open OpenJeDi opened this issue 5 years ago • 8 comments

Please fill in the following fields:

Pre-built SDK from the website Firebase C++ SDK version: 6.12.0 Firebase plugins in use (Auth, Database, etc.): Auth, Firestore, Functions, Storage Additional SDKs you are using (Facebook, AdMob, etc.): Qt 5.14.1 clang 64bit Platform you are using the C++ SDK on (Mac, Windows, or Linux): Mac Platform you are targeting (iOS, Android, and/or desktop): desktop

Please describe the issue here:

My application crashes when trying to call a Firebase callable function in combination with authentication:

auto pFireBaseApp = firebase::App::Create();
// No crash when I comment out the following line
auto pAuth = firebase::auth::Auth::GetAuth(pFireBaseApp);
auto pFunctions = functions::Functions::GetInstance(pFireBaseApp);

auto ref = pFunctions->GetHttpsCallable("testFunction");
auto future = ref.Call();
future.OnCompletion([](const Future<functions::HttpsCallableResult> &result) {
    // Crash before this is reached but not when commenting out pAuth code
});

It does not crash, and behaves as expected, when not initializing Auth. Note that this behaves the same with a function that doesn't use authentication: testFunction is a very simple function that returns a fixed object.

This is the call stack of the crashed thread:

1 firebase::rest::BackgroundTransportCurl::PerformBackground(firebase::rest::Request *)                                                                       (x86_64) /Users/jdierckx/work/Bioracer Motion/Bioracer Aero/build-BioracerAero-Desktop_Qt_5_14_1_clang_64bit-Debug/build-output/BRMApplicationTest.app/Contents/Frameworks/libBRMData.1.dylib  0x10038143b    
2 firebase::rest::CurlThread::ProcessRequests()                                                                                                               (x86_64) /Users/jdierckx/work/Bioracer Motion/Bioracer Aero/build-BioracerAero-Desktop_Qt_5_14_1_clang_64bit-Debug/build-output/BRMApplicationTest.app/Contents/Frameworks/libBRMData.1.dylib  0x10038318e    
3 void * std::__thread_proxy<std::tuple<std::unique_ptr<std::__thread_struct, std::default_delete<std::__thread_struct>>, void ( *)(void *), void *>>(void *) (x86_64) /Users/jdierckx/work/Bioracer Motion/Bioracer Aero/build-BioracerAero-Desktop_Qt_5_14_1_clang_64bit-Debug/build-output/BRMApplicationTest.app/Contents/Frameworks/libBRMData.1.dylib  0x1003a0cec    
4 _pthread_start                                                                                                                                              (x86_64) /usr/lib/system/libsystem_pthread.dylib                                                                                                                                               0x7fff64a29e65 
5 thread_start                                                                                                                                                (x86_64) /usr/lib/system/libsystem_pthread.dylib                                                                                                                                               0x7fff64a2583b 

Please answer the following, if applicable:

Have you been able to reproduce this issue with just the Firebase C++ quickstarts ? Did not try (the quickstart example doesn't use Auth)

What's the issue repro rate? (eg 100%, 1/5 etc) 100%

OpenJeDi avatar Apr 15 '20 12:04 OpenJeDi

Another strange thing that could help:

It also crashes when using auto pFirestore = firestore::Firestore::GetInstance(pFireBaseApp); before the function call, even when not using Auth.

Even stranger: when I move the auto pFirestore = firestore::Firestore::GetInstance(pFireBaseApp); after the function call, the completed callback is never reached. At shutdown, I then get this error:

WARNING: Auth object 0x5d786ce0 should be deleted before the App 0x5d78b790 it depends upon.

When I put the auto pAuth = firebase::auth::Auth::GetAuth(pFireBaseApp); line after the function call, or both pAuth and pFirestore lines, the OnCompleted callback is never reached but no complaints at shutdown.

OpenJeDi avatar Apr 15 '20 12:04 OpenJeDi

Hi @OpenJeDi !

So first, it would really help if you were able to reproduce this issue in the quickstart. Here's the Firestore one and here's the Auth one. This helps get us much closer to the source of the issue much faster.

Further, it might help if you switch to the open source SDK in this repository. I cover a little bit about the differences between the two here, but the TLDR is that the source release is identical to the binary one. It will just be easier to track any bugs and there's a small chance that one or more of the binaries we ship won't work in your configuration (Firebase ships a C++ SDK, and as you may know, the ABI isn't always stable between even different versions of the same operating system. I haven't seen this cause an issue on MacOS, but occasionally it crops up in Linux).

If you cannot repro it here and going to the open source sdk doesn't help, I see that you're using Qt. The next most useful thing may be to get steps from a new Qt project (I assume you're using QMake or are you on CMake?) to an error state.

Let me know how this all goes! --Patrick

patm1987 avatar Apr 15 '20 16:04 patm1987

Also, can you share the full stack trace (including the exception message)?

morganchen12 avatar Apr 15 '20 16:04 morganchen12

Thanks, I will take all the steps you propose.

We are still using qmake although the transition to cmake has been on my list for a long time. Transitioning to a different cloud system is a big task though, so I'm not going to overcomplicate it with combining those efforts now.

Also, note that I was using Auth, Firestore (and before that Database) and Storage successfully already. It is only Functions that is not working.

I'll try the Auth, Firestore and Functions quickstart examples with the latest tag from GitHub anyway. Or should I use the master branch?

OpenJeDi avatar Apr 15 '20 17:04 OpenJeDi

I tried the functions quickstart example with the current master of the cpp SDK (d0fc238). This is the output:

Initialized Firebase App. Initializing Firebase Auth and Cloud Functions. Attempt to initialize Firebase Auth. Attempt to initialize Cloud Functions. Successfully initialized Firebase Auth and Cloud Functions. ERROR: Could not sign in anonymously. Error 1: An internal error has occurred. Ensure your application has the Anonymous sign-in provider enabled in Firebase Console. Attempting to connect to Cloud Functions anyway. This may fail depending on the function. Calling addNumbers FAILED! Error 13: INTERNAL Shutting down the Functions library. SUCCESS: Reference was invalidated on library shutdown. Signing out from anonymous account. Shutting down the Auth library. Shutting down Firebase App.

I did enable anonymous login though. The application hangs at that last line, it doesn't actually shut down.

I will try the source version of the cpp SDK with my application to see if there is any change in behviour.

OpenJeDi avatar Apr 15 '20 18:04 OpenJeDi

As a follow-up for those interested: I tried a lot of things:

  • Compile master in MacOS --> same crash (memmove operation in the Curl background thread)
  • Compile master in Windows --> same crash

This made me realize it was probably not a dependency issue, as it behaves exactly the same on MacOS and Windows, in both the binary release and compiled from source (master).

The quickstart example did not crash.

After a lot of testing, I figured out there is no crash when waiting for the future to be complete (like in the quickstart example) instead of using the OnCompleted callback.

It still works if I do use the OnCompleted callback, but wait for the future to be complete after Call'ing the function.

So that is what I am doing now. It is not a bad workaround in my case because I call the function from the logon completed callback anyway, so I don't block the main thread.

OpenJeDi avatar Apr 28 '20 15:04 OpenJeDi

Thanks for the investigation and workaround!

morganchen12 avatar Apr 28 '20 17:04 morganchen12

Was running into the exact same issue.

In my case I resolved the issue by ensuring the HttpsCallableReference was not destroyed until the future had resolved. The destructor for this class releases the future and calls rest::CleanupTransportCurl() which I imagine is the cause of the problem.

HyperNexus avatar Jul 07 '20 00:07 HyperNexus