Closed elena-krakhmalova closed 4 years ago
I found a few problems with this issue:
@dmandar looks like we have a few references to AndroidConfigFetchProto. The stack trace doesn't show any symbols from the quickstart sample.
2019-11-18 00:15:53.983113+0200 ConfigExample[2859:108696] *** Assertion failure in -[GPBFieldDescriptor initWithFieldDescription:includesDefault:syntax:], /Volumes/Data/Projects/Heyzap/HZIOS-1074_investigation/quickstart-ios/config/Pods/Protobuf/objectivec/GPBDescriptor.m:532
2019-11-18 00:15:53.987145+0200 ConfigExample[2859:108696] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Class AndroidConfigFetchProto not defined'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23c4f02e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50b97b20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23c4eda8 +[NSException raise:format:arguments:] + 88
3 Foundation 0x00007fff256c9b61 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
4 protobuf 0x0000000108fe639e -[GPBFieldDescriptor initWithFieldDescription:includesDefault:syntax:] + 670
5 protobuf 0x0000000108fe3496 +[GPBDescriptor allocDescriptorForClass:rootClass:file:fields:fieldCount:storageSize:flags:] + 342
6 ConfigExample 0x0000000108a858e4 +[RCNConfigFetchRequest descriptor] + 180
7 protobuf 0x000000010901fbd7 +[GPBMessage initialize] + 183
8 libobjc.A.dylib 0x00007fff50b98103 CALLING_SOME_+initialize_METHOD + 17
9 libobjc.A.dylib 0x00007fff50b98ee9 initializeNonMetaClass + 624
10 libobjc.A.dylib 0x00007fff50b994ba _ZL24initializeAndMaybeRelockP10objc_classP11objc_objectR8mutex_ttILb0EEb + 157
11 libobjc.A.dylib 0x00007fff50ba3a5d lookUpImpOrForward + 595
12 libobjc.A.dylib 0x00007fff50b94219 _objc_msgSend_uncached + 73
13 libobjc.A.dylib 0x00007fff50ba3b2b _ZL20resolveMethod_lockedP11objc_objectP13objc_selectorP10objc_classi + 184
14 libobjc.A.dylib 0x00007fff50ba39de lookUpImpOrForward + 468
15 libobjc.A.dylib 0x00007fff50ba37be class_getInstanceMethod + 47
16 ConfigExample 0x0000000108a44c47 +[AppDelegate isRegisteredClass:] + 55
17 ConfigExample 0x0000000108a44e31 +[AppDelegate registeredClasses] + 417
18 ConfigExample 0x0000000108a44f1a -[AppDelegate application:didFinishLaunchingWithOptions:] + 106
19 UIKitCore 0x00007fff478467a8 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 232
20 UIKitCore 0x00007fff478481b7 -[UIApplication _callInitializationDelegatesWithActions:forCanvas:payload:fromOriginatingProcess:] + 3980
21 UIKitCore 0x00007fff4784dd06 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1281
22 UIKitCore 0x00007fff46f843e9 -[_UISceneLifecycleMultiplexer completeApplicationLaunchWithFBSScene:transitionContext:] + 122
23 UIKitCore 0x00007fff47471c01 _UIScenePerformActionsWithLifecycleActionMask + 83
24 UIKitCore 0x00007fff46f84efb __101-[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:]_block_invoke + 198
25 UIKitCore 0x00007fff46f8490a -[_UISceneLifecycleMultiplexer _performBlock:withApplicationOfDeactivationReasons:fromReasons:] + 296
26 UIKitCore 0x00007fff46f84d28 -[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:] + 818
27 UIKitCore 0x00007fff46f845bd -[_UISceneLifecycleMultiplexer uiScene:transitionedFromState:withTransitionContext:] + 345
28 UIKitCore 0x00007fff46f88beb __186-[_UIWindowSceneFBSSceneTransitionContextDrivenLifecycleSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:]_block_invoke_2 + 178
29 UIKitCore 0x00007fff473976bb +[BSAnimationSettings(UIKit) tryAnimatingWithSettings:actions:completion:] + 865
30 UIKitCore 0x00007fff4749053f _UISceneSettingsDiffActionPerformChangesWithTransitionContext + 240
31 UIKitCore 0x00007fff46f88906 __186-[_UIWindowSceneFBSSceneTransitionContextDrivenLifecycleSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:]_block_invoke + 153
32 UIKitCore 0x00007fff47490442 _UISceneSettingsDiffActionPerformActionsWithDelayForTransitionContext + 84
33 UIKitCore 0x00007fff46f88774 -[_UIWindowSceneFBSSceneTransitionContextDrivenLifecycleSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:] + 381
34 UIKitCore 0x00007fff46ddf143 __64-[UIScene scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke + 657
35 UIKitCore 0x00007fff46dddcc8 -[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:] + 248
36 UIKitCore 0x00007fff46ddee6d -[UIScene scene:didUpdateWithDiff:transitionContext:completion:] + 210
37 UIKitCore 0x00007fff4784c363 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 535
38 UIKitCore 0x00007fff473b922d -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 361
39 FrontBoardServices 0x00007fff36555225 -[FBSSceneImpl _callOutQueue_agent_didCreateWithTransitionContext:completion:] + 442
40 FrontBoardServices 0x00007fff3657b598 __86-[FBSWorkspaceScenesClient sceneID:createWithParameters:transitionContext:completion:]_block_invoke.154 + 102
41 FrontBoardServices 0x00007fff3655fd05 -[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 220
42 FrontBoardServices 0x00007fff3657b229 __86-[FBSWorkspaceScenesClient sceneID:createWithParameters:transitionContext:completion:]_block_invoke + 355
43 libdispatch.dylib 0x00000001090ebd48 _dispatch_client_callout + 8
44 libdispatch.dylib 0x00000001090eecb9 _dispatch_block_invoke_direct + 300
45 FrontBoardServices 0x00007fff365a143e __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
46 FrontBoardServices 0x00007fff365a112c -[FBSSerialQueue _queue_performNextIfPossible] + 441
47 FrontBoardServices 0x00007fff365a163b -[FBSSerialQueue _performNextFromRunLoopSource] + 22
48 CoreFoundation 0x00007fff23bb2221 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
49 CoreFoundation 0x00007fff23bb214c __CFRunLoopDoSource0 + 76
50 CoreFoundation 0x00007fff23bb1924 __CFRunLoopDoSources0 + 180
51 CoreFoundation 0x00007fff23bac62f __CFRunLoopRun + 1263
52 CoreFoundation 0x00007fff23babe16 CFRunLoopRunSpecific + 438
53 GraphicsServices 0x00007fff38438bb0 GSEventRunModal + 65
54 UIKitCore 0x00007fff4784fb68 UIApplicationMain + 1621
55 ConfigExample 0x0000000108a450a0 main + 112
56 libdyld.dylib 0x00007fff51a1dc25 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
@dmandar can you investigate why the class is being loaded into the runtime despite it not having a definition?
@elena-krakhmalova in the meantime you can work around this bug by skipping the generated Protobuf classes when enumerating classes in the runtime.
@morganchen12 thanks for looking into the issue! Things are a bit more complicated, since I’m working on SDKs. Logging system of one of our SDKs enumerates classes at runtime. The second SDK includes the first SDK as submodule. User who integrated our second, bigger SDK, and also FirebaseRemoteConfig in his app complains about crash. We’ll have to make two releases until workaround will be reachable for user. I was considering possibility to add in user’s app AndroidConfigFetchProto class with empty implementation, without any properties or methods (serving just like a stub to prevent crash). I am not sure however, maybe there are some messages later at runtime to this class, when remote config is fetched, updated etc? Could you please confirm if this a possible workaround or not a good one? Could I recommend it to the user of our SDK? Thanks a lot in advance!
I am experiencing this crash as well, when I enumerate all classes using the objc/runtime. I have tried the suggested workaround of skipping enumeration of the offending class, but that doesn't seem to work unless I'm missing something about how to skip them. Here is what I'm trying:
int numberOfClasses = objc_getClassList(NULL, 0);
Class *classList = (Class *)malloc(numberOfClasses * sizeof(Class));
numberOfClasses = objc_getClassList(classList, numberOfClasses);
for (int idx = 0; idx < numberOfClasses; idx++) {
Class class = classList[idx];
NSString *name = NSStringFromClass(class);
NSLog(@"name = %@", name);
if ([name compare:@"AndroidConfigFetchProto"] == NSOrderedSame) {
NSLog(@"skipping");
}
else {
// This will crash as of Nov 19, 2019 due to an issue in the Google Protobuf stuff
// used by Firebase. Refer to https://github.com/firebase/firebase-ios-sdk/issues/4334 for
// details on the issue. Basially, there is a forward declaration of a class named
// AndroidConfigFetchProto in the FirebaseRemoteConfig library. When you use the Objective-C
// runtime ability to enumerate classes it crashes because the class is not actually present.
//
// A suggested workaround is to skip enumeration of the generated Protobuf classes.
if (class_getClassMethod(class, @selector(conformsToProtocol:)) && [class conformsToProtocol:protocol]) {
if (class != [RMFModeTraitsImpl class]) {
id<RMFModeTraits> traitsClass = [[class alloc] init];
[modes addObject:traitsClass];
}
}
}
}
Unfortunately, it now crashes on this line:
NSString *name = NSStringFromClass(class);
for the missing class.
What is the suggested way to work around this issue without being able to check the name of the offending class?
@BennettSmith I haven't tested this solution, but you should be able to test for the missing class with
if (class != nil) {
NSString *name = NSStringFromClass(class);
// ...
}
Adding an empty stub implementation should work as well.
Yeah, as I mention, when you try NSStringFromClass it causes the runtime crash too. So, it seems the Objective-C runtime is asserting that since the class doesn't exist, it won't even return the name of it. :-(
I'll give the stub approach a try.
What is the likelihood of this being resolve within the library? Is there a suggested earlier version of the pod that could be used to work around the issue?
This will definitely be resolved in the library; missing implementations at runtime is a bug.
I'm not sure if earlier versions of RemoteConfig will fix this issue since that class has existed for a long time.
Thanks for the additional info. Using the stub approach I am able to enumerate classes again.
Oddly, until the most recent pod update
here our unit tests were all passing without an issue. We don't use RemoteConfig directly, but do use Firebase Analytics which I believe depends on RemoteConfig. I wonder if the internal inconsistency check and subsequent exception are something newly added by Apple in Xcode 11.2.1.
FirebaseAnalytics
does not depend on FirebaseRemoteConfig
. Check the Podfile.lock to see what causes the dependency.
Hi @BennettSmith it's interesting that with Xcode v11.2 (11B52) your code is not crashing at NSString *name = NSStringFromClass(class);
@morganchen12 thanks for your response!
Just out of curiosity could you please describe in few words how is Android stuff relevant in iOS SDK? I can see in addition to AndroidConfigFetchProto
class, for example hasAndroidId
, androidId
properties.
FirebaseAnalytics
does not depend onFirebaseRemoteConfig
. Check the Podfile.lock to see what causes the dependency.
I misspoke - meant Firebase Performance, not Analytics.
@elena-krakhmalova Android is not relevant in iOS, iirc when the service was originally written we put Android in some of the proto names and then re-used them on iOS.
Thanks @morganchen12 for your answer.
I couldn’t find usage of AndroidConfigFetchProto *config
property and I hope it’s not used on iOS.
Investigating.
Hi @morganchen12 , @dmandar! any updates about this issue?
Having the exact same issue
@paulb777 Could you please tell me in which version of FirebaseRemoteConfig is this issue fixed? Is it already released or when is it planned to be released? Thanks a lot!
@elena-krakhmalova YW! It was released in Firebase 6.26.0. (You can see from the milestone field on this issue.)
@paulb777 if I'm using pod 'FirebaseRemoteConfig'
in Podfile, I'm getting FirebaseRemoteConfig (4.4.11) installed.
If using pod 'Firebase/RemoteConfig'
in Podfile - getting Firebase 6.26.0 and FirebaseRemoteConfig 4.5.0 installed. So FirebaseRemoteConfig 4.5.0 is the last one and with fix, correct?
@elena-krakhmalova Correct. 4.5.0 has the fix. That should also show up if you do a pod update
with Firebase/RemoteConfig
from Firebase 6.26.0.
@paulb777 I see, thanks a lot!
[READ] Step 1: Are you in the right place?
Yes, seems to me in the right place.
[REQUIRED] Step 2: Describe your environment
Environment
[REQUIRED] Step 3: Describe the problem
Steps to reproduce:
Please note in this example app crashes for simulator, but the same will happen for device as well. The real problem is that AndroidConfigFetchProto class is neither defined, nor implemented but referenced in Config.pbobjc.h and Config.pbobjc.m in FirebaseRemoteConfig pod.
Relevant Code:
xcode_log_crash.txt AppDelegate.txt