A single crash when merging Dictionaries

Hi,


I got a very weird crash when merging dictionaries, and I couldn't find anything anywhere.


Have a method that is func getSubscriptions(for group: Group) -> [String: Bool].


And then this line crashes

func getSubscriptions(for groups: [Group]) -> [String: Bool] {

----> return groups.compactMap({ getSubscriptions(for: $0) }).reduce([:]) { $0.merging($1){ (current, _) in current } }

}


* I have validated that this all occurs only and always on main thread

Any ideas? Below is the stack trace:

Crashed: com.apple.main-thread

0 libswiftCore.dylib 0x102c7a1ac _hidden#6617_ (__hidden#17759_:135)

1 libswiftCore.dylib 0x102ae1dd0 _assertionFailure first-element-marker first-element-marker fileflags(_:_:_:_:_:) (__hidden#17736_)

2 HEED-EL 0x100c5929c specialized _VariantDictionaryBuffer.nativeMerge<A>(_:uniquingKeysWith:) (<compiler-generated>)

3 HEED-EL 0x100c5ae50 specialized Dictionary.init<A>(uniqueKeysWithValues:) (<compiler-generated>)

4 HEED-EL 0x100c491e8 MyViewController.getSubscriptions(for:) (<compiler-generated>)

Replies

It sounds like you can reproduce this crash at will. If so, run your program outside of Xcode, reproduce the crash, then grab the Apple crash report and post it here.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hey Eskimo,


Thanks for your reply, But this crash happened only once, and the log is from Crashlytics.

I looked into the code in order to post the idea of what the code is, and I have no idea how to make a crash like this occur again.


Is there any scenario that this crash should happen in a code like the one I posted? If the code always runs on main thread?


Thanks.

But this crash happened only once, and the log is from Crashlytics.

It is, alas, very hard to make quick progress on issues like this without an Apple crash report [1].

Is there any scenario that this crash should happen in a code like the one I posted?

Frame 1 of your backtrace shows that the app crashed because of some sort of assertion failure. Frame 2 shows that this came from a specialisation of

_VariantDictionaryBuffer.nativeMerge(_:uniquingKeysWith:)
. This is an implementation detail within
Dictionary.merging(_:uniquingKeysWith:)
, which is something you called in frame 4. That code is super complex, so it’s not easy to determine exactly which assertion you hit.

Note If you’d like to look at the code, you can find it here. Keep in mind that you should look at the branch for the Swift tools that you’re working with (I’ve assumed 4.2). This is especially important in this case, because

_VariantDictionaryBuffer
no longer exists in master (it’s been renamed to
Dictionary._Variant
).

Beyond that I’ve got very little:

  • The standard reason for

    Dictionary
    messing up in weird ways is broken hashing, but your dictionaries are all keyed by
    String
    . Unless you’re doing something weird with strings (a custom
    NSString
    subclass that’s then bridged to
    String
    ), I can’t see how you could hit that problem.
  • Another possibility is a threading problem. Earlier you wrote:

    always on main thread

    Are you sure that the data structures accessed by this code (and specifically the underlying

    getSubscriptions(for:)
    method) are all confined to the main thread?
  • Finally, there’s always the possibility of memory corruption, but that’s a long shot. Still, if you’ve not recently run your code under the standard memory debugging tools, it’s worth giving them a try.

If I were in your shoes I’d try disassemble the code in frame 2 to see if I could track down the parameters that are being passed to the assertion failure, which might indicate where this problem is coming from. However, I’m not sure that’s worth the effort given that you’ve only got one report of this crash.

Alternatively, you could ask about this over on Swift Forums. It’s possible that someone with deep knowledge about the internals of

Dictionary
might immediately recognise this crash.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] If you’re curious what challenges are involved here, check out this post.

Thanks for the full reply,


Just to make one thing certain, the call to this function is only from main thread, I am assuing, as it should be, that the dictionary copies with all the data, as a struct, and that if the strings inside are regular strings, I should not have hashing problem, becuase the dictionary instance is contain within this function, no?


I will ask in the swift forums as well, see if I get any luck there.

I will ask in the swift forums as well

Just for the record, this is A single crash when merging Dictionaries.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Just to add, also found this crash key: Fatal error: Duplicate values for key: '5c6765c3041c69001517afb0': file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang_Fall2018/swiftlang_Fall2018-1000.11.42/src/swift/stdlib/public/core/Dictionary.swift, line 3853

Interesting. You can find that error at that line number in the Swift standard library source file I referenced back on 7 Mar.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"