Firebase-ios-sdk: Adding Firebase/Firestore Creates EXC_BAD_ACCESS

Created on 23 Jul 2018  路  8Comments  路  Source: firebase/firebase-ios-sdk

[REQUIRED] Step 2: Describe your environment

  • Xcode version: 9F2000
  • Firebase SDK version: 5.4.0
  • Firebase Component: Firestore (Auth, Core, Database, Firestore, Messaging, Storage, etc)
  • Component version: 0.12.5

[REQUIRED] Step 3: Describe the problem

Swift application works just fine until adding Firebase/Firestore. Then on startup it throws an EXC_BAD_ACCESS. Remove Firestore and the problem clears up.

Steps to reproduce:

Add Firebase/Firestore.

Start application.

This seems to happen when another Framework is using OpenSSL and BoringSSL doesn't play well with.

The issue is an EXC_BAD_ACCESS in BoringSSL lhash.c

A screen shot of the error:

https://www.dropbox.com/s/f477glowcyiu8k9/Screenshot%202018-07-22%2023.23.12.png?dl=0

Backtrace:

``* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xfffff5cf06ff5b10) frame #0: 0x00000001046834ec AirCounsel___lldb_unnamed_symbol747$$AirCounsel

  • frame #1: 0x00000001085a6668 opensslget_next_ptr_and_hash(lh=0x00000001d0463e08, out_hash=0x000000016bd58b0c, data=0xfffff5cf06ff5b10) at lhash.c:143 frame #2: 0x00000001085a6748 openssllh_insert(lh=0x00000001d0463e08, old_data=0x00000001d02814a0, data=0xfffff5cf06ff5b10) at lhash.c:241
    frame #3: 0x0000000104683438 AirCounselCRYPTO_dbg_malloc + 496 frame #4: 0x00000001046824cc AirCounselCRYPTO_malloc + 180
    frame #5: 0x0000000104678ca8 AirCounselSSL_CTX_new + 48 frame #6: 0x00000001045d0514 AirCounselresip::BaseSecurity::BaseSecurity(resip::BaseSecurity::CipherList const&, resip::Data const&, resip::Data const&, bool) + 344
    frame #7: 0x00000001045d0d88 AirCounselresip::Security::Security(resip::Data const&, resip::BaseSecurity::CipherList const&, resip::Data const&, resip::Data const&, bool) + 68 frame #8: 0x000000010443258c AirCounselPortSIP::UserAgent::UserAgent(PortSIP::CallManager, resip::Data const&, resip::Data const&, resip::Data const&, bool, char const) + 532
    frame #9: 0x000000010445e31c AirCounselPortSIP::CallManager::initialize(PortSIP::ICallbackDispatcher*, bool, PORTSIP_LOG_LEVEL, char const*, char const*, int, char const*, char const*, int, int, char const*, char const*, bool, PortSIP::IVideoEncoderFactory*, char const*) + 1016 frame #10: 0x0000000104454640 AirCounsel___lldb_unnamed_symbol108$$AirCounsel + 768
    frame #11: 0x0000000104114b48 AirCounselLoginViewController.onLine(self=0x000000012e81b600) at LoginViewController.swift:258 frame #12: 0x0000000104111d5c AirCounselLoginViewController.doAutoRegister(self=0x000000012e81b600) at LoginViewController.swift:105
    frame #13: 0x0000000104111088 AirCounselLoginViewController.viewDidLoad(self=0x000000012e81b600) at LoginViewController.swift:97 frame #14: 0x00000001041112e4 AirCounsel@objc LoginViewController.viewDidLoad() at LoginViewController.swift:0
    frame #15: 0x000000018ee09e64 UIKit-[UIViewController loadViewIfRequired] + 1020 frame #16: 0x000000018eeb7e1c UIKit-[UINavigationController _updateScrollViewFromViewController:toViewController:] + 76
    frame #17: 0x000000018eeb72d8 UIKit-[UINavigationController _startTransition:fromViewController:toViewController:] + 172 frame #18: 0x000000018eeb6c14 UIKit-[UINavigationController _startDeferredTransitionIfNeeded:] + 1164
    frame #19: 0x000000018eeb66a4 UIKit-[UINavigationController __viewWillLayoutSubviews] + 164 frame #20: 0x000000018eeaa3a8 UIKit-[UILayoutContainerView layoutSubviews] + 188
    frame #21: 0x000000018ee026f4 UIKit-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1420 frame #22: 0x0000000189377e54 QuartzCore-[CALayer layoutSublayers] + 184
    frame #23: 0x000000018937bfe4 QuartzCoreCA::Layer::layout_if_needed(CA::Transaction*) + 324 frame #24: 0x00000001892e86c8 QuartzCoreCA::Context::commit_transaction(CA::Transaction*) + 320
    frame #25: 0x00000001893101b0 QuartzCoreCA::Transaction::commit() + 580 frame #26: 0x000000018f1ec680 UIKit__34-[UIApplication _firstCommitBlock]_block_invoke_2 + 140
    frame #27: 0x00000001851972bc CoreFoundation__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20 frame #28: 0x0000000185196a7c CoreFoundation__CFRunLoopDoBlocks + 264
    frame #29: 0x00000001851947b0 CoreFoundation__CFRunLoopRun + 1224 frame #30: 0x00000001850b4da8 CoreFoundationCFRunLoopRunSpecific + 552
    frame #31: 0x000000018709a020 GraphicsServicesGSEventRunModal + 100 frame #32: 0x000000018f0d4758 UIKitUIApplicationMain + 236
    frame #33: 0x00000001040dee7c AirCounselmain at AppDelegate.swift:18 frame #34: 0x0000000184b45fc0 libdyld.dylibstart + 4
    ```
firestore

All 8 comments

Your supposition is correct: BoringSSL and OpenSSL can't be statically linked in the same binary, since they export nearly the same symbols.

Firestore uses gRPC which in turn uses BoringSSL. It's known to work with OpenSSL, so it's possible you could exclude BoringSSL from the build and have this work. Unfortunately, I couldn't find any easy way to resolve this with CocoaPods. @paulb777 do you have any ideas?

This is ugly, but in theory should work - https://github.com/grpc/grpc/issues/6111#issuecomment-214576739

Thank you, @wilhuff and @paulb777, for the quick and helpful response. It is much appreciated.

I am giving the suggestion a try, at first blush replacing BoringSSL with OpenSSL isn't exactly helping and creating other issues, but I'm going to work through those to see if those are addressable. It seems like the BoringSSL v. OpenSSL thing is a can of worms/hard stop so hopefully this is at least addressable as the OpenSSL library is pulled in for a SIP stack we are using.

Searches have indicated that BoringSSL seems to introduce quite a few issues, what is the wisdom behind such a prolifically used library across Google's services not playing well with a very common piece of software like OpenSSL? Not trying to be snarky, but just very worried with this experience and with others' that I've read that if Google is so tied to BoringSSL/gRPC that its services may not be a good selection if stuff like this crops up.

The intent is that gRPC is compatible with both BoringSSL and OpenSSL. If you look through commit and issue history in the gRPC repo, you'll see that they take that compatibility very seriously.

For most users that don't care or don't otherwise use OpenSSL we believe BoringSSL is a better default choice. Unfortunately this creates a problem for users like yourself that are otherwise using OpenSSL. I'm hopeful that we can find a way to express the alternative in CocoaPods (perhaps via subspecs--not sure).

In any case let us know how this works out, and if the alternative podspec works, please share what you come up with.

@wilhuff - thanks for the insight and knowing that you guys will continue to think of/mind the needs of users needing to use OpenSSL is really helpful in committing to develop/use against services like Firebase, etc.

I think I have a solution...I'll share when I fully verify.

@24601 Did you ever fix it. I am having a similar issue: https://github.com/grpc/grpc/issues/16181

Yes, @bond, I will post a sample in a bit, it was a really involved solution until after I implemented I found someone who had already pretty much packaged a fix for something else that was also a solution for this. On my phone now, will come back from my laptop that has the source code on it.

@bond here's the reader's digest of the solution I found to work best.

First, clone the gRPC repo or download the *.podspec files in the repo (you don't need the whole repo, just the .podspec files in the top level). https://github.com/grpc/grpc

Second, place these in the root of your project or some folder, your choice, just remember where you put them.

Third, edit gRPC-Core.podspec and replace the line that is ss.dependency 'BoringSSL' (or similar, it was on line 182 in the rev/commit I had pulled, YMMV, but it's basically the only line in the file that specifies BoringSSL) to read: ss.dependency 'GRKOpenSSLFramework'. Simply replacing with OpenSSL did not work for me and just introduced even more issues around static libs vs dynamic libs/frameworks on Swift but this dep packages it appropriately and works properly as far as I can tell and have tested.

Fourth, add the following lines to your Podfile:

pod 'gRPC-RxLibrary', :podspec => "."
pod 'gRPC', :podspec => "."
pod 'gRPC-Core', :podspec => "."
pod 'gRPC-ProtoRPC', :podspec => "."

Finally, do a pod install and things should work. They did, at least, for me. You may need to clean the build folder, clean, delete derived data, and do the "Apple makes horribly idiotic developer tools of questionable quality" dance, etc and it should work.

Was this page helpful?
0 / 5 - 0 ratings