EXC_BAD_ACCESS (code=10... when calling init on a struct

We're seeing the following error when trying to init the UP struct by calling UP() anywhere in a unit test.

Is it Swift runtime related?

The exception is: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=10, ads=0x12a500a80)

We see it on the following line: public var mS: MS = .none

The struct can be created without any issues in a minimal sample test-case, but calling init always fails on Xcode 13.2.1 when testing in a full test suite that tests the offending .framework containing the creation of the struct.

(note in case it matters: 1) the thread sanitizer is disabled to avoid another bug and 2) the scheme for the full app containing the .framework is used to run the unit tests, 3) variable names have been simplified)

import Foundation

public struct ADS: Codable {

    public var a1: String?
    public var a2: String?
    public var c: String?
    public var st: String?
    public var cnt: String?
    public var pC: String?
    public var ph: String?
    public var phExt: String?
    public init(from decoder: Decoder) throws {
// unneeded
    }



    public init(a1: String? = nil,
                a2: String? = nil,
                c: String? = nil,
                st: String? = nil,
                cnt: String? = nil,
                pC: String? = nil,
                ph: String? = nil,
                phExt _: String? = nil)
    {
        self.a1 = a1
        self.a2 = a2
        self.c = c
        self.st = st
        self.cnt = cnt
        self.pC = pC
        self.ph = ph
    }
}

public struct PI: Codable {
    public let id: String
    public let cTD: CTD
    public let nu: String
    public let em: String
    public let er: String
}

public struct CTD: Codable {
    public let code: String
    public let name: String
}

public struct LYY: Codable {
    public let id: String?
    public let tsSS: String
    public let tsTC: String
    public let tsWC: String
    public let tsWG: String
    public let tsSD: String
    public let tsSDu: String
    public let sdSDEd: String
    public let sdSV: String
    public let tsO: String
    public let tsP: String
    public let tsSH: String
    var nu: String?
    public let banner: String?
    public let eL: Int?
    public let let: String?
    public let pi: String?
}

public enum MS: String, Codable {
    case pe = "end"
    case sb = "it"
    case none
}

public struct UP: Decodable {
    public var una: String?
    public var lan: String?
    public var dob: String?
    public var fN: String?
    public var lN: String?
    public var eai: String?
    public var gen: String?
    public var bac: Double?
    public var nP: String?
    public var cuI: String?

    public var mS: MS = .none // crashes here 

    public var acS: String?
    public var eSc: Bool?
    public var tBac: Double?
    public var lyy: LYY?
    public var hAds: ADS?
    public var bAds: ADS?
    public var pIs: [PI]?
    public let lUd = Date()
    public var cry: String?
    public var lmP: Int?

    public var lyyNu: String? {
        get {
            lyy?.nu
        }

        set {
            lyy?.nu = newValue
        }
    }

    public func getProfileDictionary() -> [String: Any]? {
        return nil // unneeded
    }

    public var isUserLYY: Bool {
       false // unneeded
    }

    public init() {
    }

    public init(from decoder: Decoder) throws {
// unneeded
    }

}

Accepted Reply

Issue resolved. It doesn't look to be a Swift runtime (or Xcode related) bug. Thanks @eskimo for your thoughts and feedback!

We were simply missing the following line in our Xcodeproject for the framework with the crashing tests:

S475A718279U3V7600S7P2D8 /* SomeDependencyFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SomeDependencyFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };

Interestingly for posterity: unit testing that Xcodeproject framework with/without an xctestplan did/didn't cause its unit tests to fail respectively.

Replies

Well, that’s definitely weird. Normally in these situations I recommend that you try to cut down your code to isolate the problem but it seems like you’ve tried that already and the problem just goes away in that case. I hate it when that happens )-:

You wrote:

when testing in a full test suite

If you build and test with your main app — so you have your full suite of tests available — but just run one specific test (by clicking the diamond next to that test) do you still see the crash?

Your answer here tells us whether the crash is caused by the way things were built or by some interaction between your tests.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Haha, thanks!

Yes the crash still occurs for the exact scenario you described (build and test with the main app — so the full suite of tests is available — running just one specific test by clicking the diamond next to it).

  • I also made sure that UP() is called first thing in the setUp function and the crash still happens for that too.
  • I also tested on Xcode 12.5: this exact scenario passes on it, so the issue seems to be new to one of the Xcode 13.x releases...

OK, so this definitely sounds like some sort of code generation / Swift runtime bug. That leaves us with two problems:

  • How to file an actionable bug report?

  • What can you do to work around this?

With regards the latter, do you actually need a workaround? Is this UP initialiser used elsewhere in your test suite? If not, you could simply disable the test and that’s your workaround.

With regards an actionable bug report, that’s going to be tricky. You mentioned an app, a framework, and a unit test bundle. Presumably your app has the framework embedded in it and your unit test bundle is targeting the app, not the framework. That is, in the General tab of the test target editor, the Host Application popup is set to your app. Is that right?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

For the later, a workaround: we found the proposed form of it won't work.

That is, even if the framework under discussion has all its tests disabled we actually get similar code=10 crashes in other areas of the codebase (e.g. even in methods called from the app delegate on launching the host app to unit test), that don't look to have to do with initializing structs, both on iOS 14.5 and 15 simulators (all testing was previously on iOS 14.5).

For the former, an actionable bug report: correct, the host application popup is set to our app.

We also tried without it, i.e. by unit testing the offending framework directly without building the full app—and the crash does still occur, so that might help narrow things down. The current plan is to try getting the framework to build with as few dependencies as possible to see if any of them (or even their quantity?) is the issue (there are currently ~13-30 local and remote SPM packages and frameworks—depending how one counts—marked as dependencies for the Xcodeproject that creates the .framework).

so that might help narrow things down

Yeah, that’s excellent news because it radically reduces the scope of potential causes.

The current plan is to try getting the framework to build with as few dependencies as possible

Yeah, that’d be my next step as well. Let us know how that goes.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Issue resolved. It doesn't look to be a Swift runtime (or Xcode related) bug. Thanks @eskimo for your thoughts and feedback!

We were simply missing the following line in our Xcodeproject for the framework with the crashing tests:

S475A718279U3V7600S7P2D8 /* SomeDependencyFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SomeDependencyFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };

Interestingly for posterity: unit testing that Xcodeproject framework with/without an xctestplan did/didn't cause its unit tests to fail respectively.

I hope my finding will help someone. We faced exactly the same crash in one of our unit tests after tweaking the library dependencies. And the problem was not in the Xcodeproject. May be the reason of the crash is still not clear, but here is the story:

What happened: We have project A, which depends on library X, and we had library B. A->X - depends as subproject A->B - :path => dependency in Podfile.

We decided to refactor B, and make the following: A -> B, X - both in Podfile (:path =>) B -> X - Podfile (:path =>)

After that, one of the tests which has no differences with other tests, stated crashing with the issue above.

The problem was in Generics:

  • S<T: P>: NSObject - service class in A
  • P - protocol in X
  • F: P - fake class in TEST target of A (AT)
  • R: P - class in A

We are using this service in A as follows: S<R>, but in unit tests we need instance of type S<F>.

After moving F: P from AT to A (in Target Membership), the crash disappear. Seems it's something related to : P in F: P - unit test bundle was not able to create S<F>.

P.S. Before we found the solution we tried to change Podfile (:path => ) to normal versioned dependences (pod X, '0.1.0', pod B, '0.1.0') - no effect.