Xcode 11.2 runtime error: type metadata accessor failed to demangle superclass from mangled name

A very bizarre error that only happens on Xcode 11.2.

Create a new iOS Single View App, and add this to ViewController.swift:

import UIKit
import GameplayKit

class GestureRecognizerComponent <GestureRecognizerType> : GKComponent, UIGestureRecognizerDelegate 
    where GestureRecognizerType: UIGestureRecognizer {}

class TapGestureRecognizerComponent: GestureRecognizerComponent <UITapGestureRecognizer> {}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let _ = TapGestureRecognizerComponent()
    }
}

Running this will cause a signal SIGABRT at
type metadata accessor for TapGestureRecognizerComponent

at the next instruction after symbol stub for: swift_getSingletonMetadata

Debug Console output:

failed to demangle superclass of GestureRecognizerComponent from mangled name 'So11GKComponentC'

Notes:

  • This error did NOT happen in Xcode 11.1 with the exact same code.

  • This error does NOT happen when GestureRecognizerComponent inherits from NSObject instead of GKComponent

  • This error does NOT happen with any other basic subclasses of GKComponent – only with class Component<T: UIGestureRecognizer>: GKComponent, UIGestureRecognizerDelegate

  • In another package, this error does NOT happen if GestureRecognizerComponent is a subclass of a subclass (grandchild) of GKComponent (and there are extensions on GKComponent) unless I override any superclass methods or properties.

Does it work around the problem if you add a reference to the GestureRecognizerComponent<UITapGestureRecognizer> class? You could try adding this to viewDidLoad:

    override func viewDidLoad() {
        super.viewDidLoad()
        let _ = TapGestureRecognizerComponent()
        print(GestureRecognizerComponent<UITapGestureRecognizer>.self)
    }

It crashes at the let statement, not even getting past the assignment.

The print statement may force the compiler to generate metadata for the missing type that it may not be.

If I put that print first, then it crashes on the print statement.

I see, thanks for giving it a try. How about if you print(GKComponent.self) instead?

1 Like

print(GKComponent.self)

Oh my, that works!!

Let me try that in my main project (which is a Swift Package with more complicated relationships) and I'll get back to you. Thank you!

No problem, thanks for reporting this! We'll investigate the regression.

I am still wrestling with this problem in the actual package.

If you'd like to see the exact code, it's on GitHub at: https://github.com/InvadingOctopus/octopuskit/blob/develop/Sources/OctopusKit/Components/Input/Touch%20Gestures/OctopusGestureRecognizerComponent.swift

(please overlook transgressions like not using 2-letter prefixes and #if instead of @available ..I'll get around to it :)

To reproduce, please create an iOS Single View App, add the OctopusKit package on the develop branch, and modify ViewController.swift:

import UIKit
import GameplayKit
import OctopusKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print(GKComponent.self)
        print(OctopusComponent.self)
        print(UIGestureRecognizer.self)
        print(UITapGestureRecognizer.self)
        print(UIGestureRecognizerDelegate.self)
        print(OctopusGestureRecognizerComponent.self) // EXC_BAD_ACCESS (code=1, address=0x0)
        print(OctopusGestureRecognizerComponent<UITapGestureRecognizer>.self)
    }
}
  • The peculiar thing is, it does not crash if I copy that class from the package and paste it verbatim inside ViewController.swift! (and rename it to avoid conflicts.)

  • It also does not crash if I comment out all overrides in OctopusGestureRecognizerComponent (excluding the init). Even a single override brings back the crash.

  • It does not crash if I inherit from GKComponent instead of OctopusComponent: GKComponent

In the Debug Console, I get this:

(lldb) po OctopusGestureRecognizerComponent.self

GenericCache(0x7fff89d01460): cyclic metadata dependency detected, aborting
error: Execution was interrupted, reason: signal SIGABRT.
The process has been returned to the state before expression evaluation.

Other things that I tried but did not help:

  • Other Linker Flags: -all_load
  • Compilation Mode: Whole Module
  • Adding print for every type that I think could be involved, in both the package and the client project.
  • There was a type in the package with the same name as the package (OctopusKit). Renaming that type did not help.

Trace

(lldb) thread backtrace
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x00007fff5132ba49 libswiftCore.dylib`_swift_initClassMetadataImpl(swift::TargetClassMetadata<swift::InProcess>*, swift::ClassLayoutFlags, unsigned long, swift::TypeLayout const* const*, unsigned long*, bool) + 1337
    frame #1: 0x0000000109744ea4 Bweh`type metadata completion function for OctopusGestureRecognizerComponent at <compiler-generated>:0
    frame #2: 0x00007fff51332ced libswiftCore.dylib`swift::MetadataCacheEntryBase<(anonymous namespace)::GenericCacheEntry, void const*>::doInitialization(swift::ConcurrencyControl&, swift::MetadataCompletionQueueEntry*, swift::MetadataRequest) + 285
    frame #3: 0x00007fff51329767 libswiftCore.dylib`swift_getGenericMetadata + 1527
    frame #4: 0x0000000109742dfc Bweh`type metadata accessor for OctopusGestureRecognizerComponent at <compiler-generated>:0
    frame #5: 0x00000001096b3b7f Bweh`type metadata accessor for OctopusGestureRecognizerComponent<UIGestureRecognizer> at <compiler-generated>:0
  * frame #6: 0x00000001096b3704 Bweh`ViewController.viewDidLoad(self=0x00007fadd7c080c0) at ViewController.swift:21:15
    frame #7: 0x00000001096b3d7b Bweh`@objc ViewController.viewDidLoad() at <compiler-generated>:0

@Joe_Groff Any workarounds or updates?

Still not fixed on Xcode 11.2.1 (11B500) :cry:

This bug has kind of stalled a part of my project (namely anything to do with gestures.)

@Michael_Gottesman has been investigating a problem similar to this that might be the same issue. What happens if you print OctopusGestureRecognizerComponent's superclasses instead of OctopusGestureRecognizerComponent itself?

Here it is:

import UIKit
import GameplayKit
import OctopusKit

/*
open class OctopusComponent: GKComponent {}

open class OctopusGestureRecognizerComponent<GestureRecognizerType>: OctopusComponent, UIGestureRecognizerDelegate
    where GestureRecognizerType: UIGestureRecognizer {}
*/

class LocalGestureRecognizerComponent<GestureRecognizerType>: OctopusComponent, UIGestureRecognizerDelegate
    where GestureRecognizerType: UIGestureRecognizer {}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print(NSObject.self)
        print(GKComponent.self)
        print(UIGestureRecognizerDelegate.self)
        print(UIGestureRecognizer.self)
        print(UITapGestureRecognizer.self)
        print(OctopusComponent.self)
        
        // ✅ Does NOT crash
        print(LocalGestureRecognizerComponent<UITapGestureRecognizer>.self)
        
        // ❗️ CRASH
        print(OctopusGestureRecognizerComponent<UITapGestureRecognizer>.self)
    }
}

As noted before, if I edit OctopusGestureRecognizerComponent in the package and comment out all the overrides of OctopusComponent: GKComponent, it does not crash.

If I copy OctopusGestureRecognizerComponent into the local file without editing anything, that also fixes the crash.

So the problem seems to be happening only when using the type from the Swift Package.

Terms of Service

Privacy Policy

Cookie Policy