7 Replies
      Latest reply on Mar 15, 2019 4:31 AM by eskimo
      shachar.silbert Level 1 Level 1 (0 points)

        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>)

        • Re: A single crash when merging Dictionaries
          eskimo Apple Staff Apple Staff (11,265 points)

          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"

            • Re: A single crash when merging Dictionaries
              shachar.silbert Level 1 Level 1 (0 points)

              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.

                • Re: A single crash when merging Dictionaries
                  eskimo Apple Staff Apple Staff (11,265 points)

                  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.