Matching core library .dSYMs with Xcode's version of Swift

Has anyone else run into the issue where the uuids of app crash logs for the core libraries don’t match those in the debug symbol’s links on the https://swift.org/download/ page? I’d imagine it’s because the Xcode team separately builds Swift when it ships, but even though they’re the same Swift version, they doesn’t have matching UUIDs when I do the dwarfdump command on the .dSYMs.

Does anyone have a solution for this that’s worked for them beyond editing their crash logs?

They aren’t necessarily the same, unfortunately. Apple may have non-open-source patches applied to its version of the standard libraries, just like it has for the compiler in the past.

What’s the symptom of this? What information would you like to get from the crash logs that you’re not getting? Specific line numbers in the stdlib seem like more implementation detail than you should be relying on, since if Swift ever gets shipped as part of the OS that’ll be the end of that.

@jrose the functions that are getting called in the internal libraries have helped me debug my crashes. Here’s a recent example.

Thread 0 name: 
Thread 0 Crashed:
0    libobjc.A.dylib                0x00000001907941a0 objc_retain + 16
1    libswiftFoundation.dylib       0x00000001036cb68c 0x1035a8000 + 1193612
2    libswiftCore.dylib             0x0000000102e7f594 0x102dbc000 + 800148
3    libswiftCore.dylib             0x0000000102e2dcbc 0x102dbc000 + 466108
4    libswiftCore.dylib             0x0000000103020ee0 0x102dbc000 + 2510560
5    libswiftCore.dylib             0x0000000103022268 0x102dbc000 + 2515560
6    libswiftCore.dylib             0x0000000102e6a964 0x102dbc000 + 715108
7    _98point6                      0x000000010091b1bc LogSender.syncFilesInDirectory(_:) + 9367996 (LogSender.swift:0)
8    _98point6                      0x000000010091ae8c closure #1 in LogSender.start() + 9367180 (LogSender.swift:45)
9    _98point6                      0x000000010069bb20 Timer.schedulerDidFire() + 6748960 (Timer.swift:31)
10   _98point6                      0x000000010069bb3c protocol witness for TimerSchedulerDelegate.schedulerDidFire() in conformance Timer + 6748988 (Timer.swift:0)
11   _98point6                      0x00000001005f72b8 closure #1 in RepeatingTimerScheduler.start() + 6075064 (TimerScheduler.swift:0)
12   _98point6                      0x00000001005f7164 thunk for @callee_owned (@owned Timer) -> () + 6074724 (TimerScheduler.swift:0)
13   Foundation                     0x000000019280c7b0 __NSFireTimer + 88
14   CoreFoundation                 0x0000000191cc5aa4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28

That takes me to LogSender.syncFilesInDirectory:

private func syncFilesInDirectory(_ url: URL) {
        sendQueue.addOperation { [unowned self] in
            do {
                let logFiles = try self.fileManagementService.contentsOfDirectory(url)

                let archivedLogFiles = logFiles.filter {
                    $0.pathExtension == Constants.archivedSuffix
                }

                for logFile in archivedLogFiles where !self.filesInQueue.contains(logFile) {
                    self.filesInQueue.insert(logFile)
                    self.syncLogFile(logFile)
                }
            } catch {
                Config.logger.error("Could not find log directory to send logs: \(error)")
            }
        }
    }

And basically, I’m pretty stuck. Swift throws a fatalError, which unfortunately doesn’t show up in crash logs that apps create. The way I ended up debugging it was to pull the debugging symbols from the swift download page, and then going into my crash log with a text editor and replacing the udid of Xcode’s Swift with the one dwarfdump gave me.

That gave me this:

Thread 0 name: 
Thread 0 Crashed:
0    libobjc.A.dylib                0x00000001907941a0 objc_retain + 16
1    libswiftFoundation.dylib       0x00000001036cb68c lazy protocol witness table accessor for type DefaultRandomAccessIndices<IndexPath> and conformance <A> DefaultRandomAccessIndices<A> + 1193612 (<unknown>:0)
2    libswiftCore.dylib             0x0000000102e7f594 _HashableTypedNativeDictionaryStorage.countByEnumerating(with:objects:count:) + 800148 (HashedCollections.swift:5670)
3    libswiftCore.dylib             0x0000000102e2dcbc Dictionary.encode(to:) + 466108 (Codable.swift:4110)
4    libswiftCore.dylib             0x0000000103020ee0 specialized Set._subtract<A>(_:) + 2510560 (HashedCollections.swift:0)
5    libswiftCore.dylib             0x0000000103022268 specialized _setUpCast<A, B>(_:) + 2515560 (HashedCollections.swift:4793)
6    libswiftCore.dylib             0x0000000102e6a964 Dictionary.init<A>(uniqueKeysWithValues:) + 715108 (<unknown>:0)
7    _98point6                      0x000000010091b1bc LogSender.syncFilesInDirectory(_:) + 9367996 (LogSender.swift:0)
8    _98point6                      0x000000010091ae8c closure #1 in LogSender.start() + 9367180 (LogSender.swift:45)
9    _98point6                      0x000000010069bb20 Timer.schedulerDidFire() + 6748960 (Timer.swift:31)
10   _98point6                      0x000000010069bb3c protocol witness for TimerSchedulerDelegate.schedulerDidFire() in conformance Timer + 6748988 (Timer.swift:0)
11   _98point6                      0x00000001005f72b8 closure #1 in RepeatingTimerScheduler.start() + 6075064 (TimerScheduler.swift:0)
12   _98point6                      0x00000001005f7164 thunk for @callee_owned (@owned Timer) -> () + 6074724 (TimerScheduler.swift:0)
13   Foundation                     0x000000019280c7b0 __NSFireTimer + 88
14   CoreFoundation                 0x0000000191cc5aa4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28

Which led me to something being wrong with the Set I was using, which led me to the fact that I needed to put a lock around my set.

I can do that udid overwrite everytime, but it can be really annoying. If Xcode could publish their dSYMs for the Swift core libraries, it would be helpful for situations like this.

Running with the thread sanitizer enabled can also help find threading issues, FYI.

It’s just an example of when desymbolicating the core libraries would help. There are many other cases.