I regularly talk to developers debugging hard-to-reproduce problems. I have some general advice on that topic. I’ve posted this to DevForums before, and also sent similar info to folks who’ve opened a DTS incident, but I figured I should write it down properly.
If you have questions or comments, put them in a new thread here on DevForums. Put it in the Developer Tools & Services > General topic area and tag it with Debugging.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Using a Sysdiagnose Log to Debug a Hard-to-Reproduce Problem
Some problems are hard to reproduce in your office. These usually fall into one of two categories:
Environment specific — This is where some of your users can easily reproduce the problem, but you can’t reproduce it in your environment.
Intermittent — In this case the problem could affect any user, but it’s hard to predict when a given user will see the problem.
A key tool in debugging such problems is the sysdiagnose log. This post explains how to make this technology work for you.
IMPORTANT A sysdiagnose log might contain private information. If you ask a user to send you a log, make sure they understand the privacy impact of that. If you want to see how Apple handles this, run the sysdiagnose command on a fresh Mac and read through it’s initial prompt.
Sysdiagnose Logs
All Apple platforms can generate sysdiagnose logs. For instructions on how to do this, see our Bug Reporting > Profiles and Logs page.
The resulting log is a .tar.gz file. Unpacking that reveals a bunch of files. The most critical of these is system_logs.logarchive, which is a snapshot of the system log. For more information about the system log, including links to the documentation, see Your Friend the System Log.
This log snapshot includes many thousands of log entries (I just took a log snapshot on my Mac and it had 22.8 million log entries!). That can be rather daunting. To avoid chasing your tail, it pays to do some preparation.
Preparation
The goal here is to create a set of instructions that you can give to your user to capture an actionable sysdiagnose log. That takes some preparation.
To help orient yourself in the log, add log points to your code to highlight the problem. For example, if you’re trying to track down a keychain problem where SecItemCopyMatching intermittently fails with errSecMissingEntitlement ( -34018 ), add a log point like this:
import os.log
let log = Logger(subsystem: "com.example.waffle-varnish", category: "keychain")
func … {
let err = SecItemCopyMatching(…)
log.log("SecItemCopyMatching failed, err: \(err)")
}
When you look through a log, find this specific failure by searching for SecItemCopyMatching failed, err: -34018.
You might also add log points at the start and end of an operation, which helps establish a time range of interest.
Log points like this have a very low overhead and it’s fine to leave them enabled in your released product. However, in some cases you might want to make more extensive changes, creating a debug build specifically to help investigate your problem. Think about how you’re going to get that debug build to the affected users. You might, for example, set up a special TestFlight group for folks who’ve encountered this issue.
Go to Bug Reporting > Profiles and Logs and look for debug profiles that might help your investigation. For example, if you’re investigating a Network Extension issue, the VPN (Network Extension) debug profile will enable useful debug logging.
Now craft your instructions for your user. Include things like:
Your take on the privacy impact on this
Instructions on how to get the necessary build of your product
If there’s a debug profile, instructions on how to install that
Instructions on how to trigger the sysdiagnose log
And on how to send it to you
IMPORTANT Make sure to stress how important it is that the user triggers the sysdiagnose immediately after seeing the problem.
Finally, test your steps. Do an initial test in your office, to make sure that the log captures the info you need. Then do an end-to-end test with someone who’s about as technically savvy as your users, to make sure that your instructions make sense to Real People™.
Prompting for a Sysdiagnose Log
In some cases it might not be obvious to the user when to trigger a sysdiagnose log. Imagine you’re hunting the above-mentioned errSecMissingEntitlement error and it only crops up when your product is performing some task in the background. The user doesn’t see that failure, they’re not even running your app!, so they don’t know that action is required.
A good option here is to add code to actively monitor for the failure and post a local notification requesting that the user trigger a sysdiagnose log. Continuing the above example, you might write code like this:
func … {
let err = SecItemCopyMatching(…)
log.log("SecItemCopyMatching failed, err: \(err)")
if err == errSecMissingEntitlement {
… post a local notification …
}
}
Obviously this is quite intrusive so, depending on the market for your product, you might not want to deploy this to all users. Perhaps you can restrict it to your internal testers, or your external beta testers, or a particularly savvy set of customers.
You can use the applefeedback URL scheme to make it easy for users to run Feedback Assistant. For more info about that, see Developer > Bug Reporting.
Looking at the System Log
Once you have your sysdiagnose log, unpack it and open the system log snapshot (system_logs.logarchive) in Console. The hardest part is knowing where to start. That’s why adding your own log entries, as discussed in Preparation, is so important. A good general process is:
Search for log entries from your subsystem. An easy way to initiate that search is to paste the text subsystem:SSS, where SSS is your subsystem, into the Search field. Continuing the above example, find that log entry by pasting in subsystem:com.example.waffle-varnish.
Identify the log entry that indicates the problem and select it.
Then remove your search and work backwards through the log looking for system log entries related to your issue.
The relevant log entries might not be within the time range shown by Console. Customise that by selecting values from the Showing popup in the pane divider. Once you have a rough idea of the timeframe involved, select Custom from that popup to focus on that range.
If the log is showing stuff that’s not relevant to your problem, Console has some great facilities for filtering those out. For the details, choose Help > Console Help.
Talk to Apple
A key benefit of this approach is that, if your investigation suggests that this is a system bug, you can file a bug report and attach this sysdiagnose log to it. The setup described above is exactly the sort of info needed to analyse the bug.
Likewise, if you start a thread here on DevForums about your issue, your friendly neighbourhood DTS engineer will find that sysdiagnose log very handy.
Revision History
2024-11-14 Added a reference to the applefeedback URL scheme. Made other minor editorial changes.
2023-10-13 First posted.
Xcode
RSS for tagBuild, test, and submit your app using Xcode, Apple's integrated development environment.
Post
Replies
Boosts
Views
Activity
I have a project that has a number of plugins in it. They are compiled and placed in the correct location and the build runs fine in the Debug / Release schemes. If I archive the build with Xcode 15 the resulting build generates a number of errors symbol not found in flat namespace '_OBJC_CLASS_$_XXXX for various classes that are part of the main application including the AppDelegate and other classes. This does not occur with Xcode 14.3.1 or previous versions. It still occurs in Xcode 15.1 beta 1. This happens regardless if I notarize the build with Apple or not.
Has anyone seen anything like this? Any ideas how to resolve it?
My current workaround is to use xcodebuild to compile a Release build and notarize that build.
On Xcode 15, when I launch my app on "Wait for the executable to be lauched" mode, I can't debug because Xcode simply doesn't pause at my breakpoints. They change their look and turn to dotted blue outlined.
When I hover over breakpoint Xcode shows a message:
Xcode won't pause at this breakpoint because it has not been resolved Resolving it requires that:
The line at the breakpoint is compiled.
The compiler generates debug information that is not stripped out (check the Build Settings).
The library for the breakpoint is loaded.
On the other hand, when I launch it on "Automatically" mode, everything works fine.
Does anyone have any ideas how to solve it?
Best regards.
Hi all,
when I am trying to build a preview I am always getting the error "Failed to launch app in reasonable time". When clicking on Diagnostics I get the following report information:
AppLaunchTimeoutError: Failed to launch app ”SwiftUI-Weather.app” in reasonable time
The app ”SwiftUI-Weather.app” did not launch on ”iPhone 15 Pro” in 15 seconds.
bundle identifier: tregnet.SwiftUI-Weather
device name: iPhone 15 Pro
path: /Users/MyUser/Library/Developer/Xcode/DerivedData/SwiftUI-Weather-fvxpuqojpxxuqtbuzmjvlatlmuqy/Build/Intermediates.noindex/Previews/SwiftUI-Weather/Products/Debug-iphonesimulator/SwiftUI-Weather.app
Also clicking on "Generate Report" in the Diagnostics menu is not doing anything for me, even after waiting for a few minutes.
Any help would be appreciated.
Greetings
The docs for symbolicating a crash file state:
To symbolicate in Xcode, click the Device Logs button in the Devices and Simulators window, then drag and drop the crash report file into the list of device logs.
However, this button is no longer available on Xcode 15 (now replaced by a "Open Recent Logs" which opens a Finder window). Is it possible for the docs to be updated? What is the solution in Xcode 15?
I am having a very weird issue with Xcode 15.0.1. If you are running an app that was built with XCode 14 and install the new version of the app with XCode 15 it works fine.
If you delete the XCode 14 build of the app, and install the XCode 15 build of the app you get "This app cannot be installed because its integrity could not be verified" error message on launching the app.
Then when we rebuild the app again with XCode 14 the app works fine with no issues.
I have tried multiple solutions that I have found on various forums, but with no luck.
Anyone have any suggestions on how to fix this issue.
This is really a disgusting function and I can't turn it off. Because the check box is grey, no way to turn it off. Even I connect my device via cables.
Debug becomes slow. Although I connect my device via cable.
And I'm developing a VPN application, it's rediculous that once I connect VPN from my device, Xcode will disconnect from my device.
I can't stand this function any m
ore. Does anyone know how to turn it off?
I am trying to add a Mac command line tool target to an existing SwiftUI project, and use the swift-argument-parser framework in that command line tool.
I get build errors after adding the swift-argument-parser to my project.
Here are the minimum reproducible example steps that trigger this problem:
Create new Multiplatform app “Test”
File>New>Target macOS command line tool named “TestCmd”
Select Scheme “TestCmd” and verify that it runs successfully.
Select TestCmd target
File>Add Package dependencies>swift-argument-parser
Add both ArgumentParser and generate-manual packages to TestCmd target
Run from TestCmd scheme.
This yields a whole stream of errors:
Library not loaded:
@rpath/ArgumentParser.framework/Versions/A/ArgumentParser
Reason: tried:
‘/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/ArgumentParser.framework/Versions/A/ArgumentParser'
(no such file),
‘/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
(code signature in <9CBB1F37-8A3F-32FC-9744-3108CEF0D6A5>
‘/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
not valid for use in process: mapping process and mapped file
(non-platform) have different Team IDs),
'/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
(code signature in <9CBB1F37-8A3F-32FC-9744-3108CEF0D6A5>
'/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
not valid for use in process: mapping process and mapped file
(non-platform) have different Team IDs),
'/System/Volumes/Preboot/Cryptexes/OS/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
(no such file),
'/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
(code signature in <9CBB1F37-8A3F-32FC-9744-3108CEF0D6A5>
'/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
not valid for use in process: mapping process and mapped file
(non-platform) have different Team IDs),
'/System/Volumes/Preboot/Cryptexes/OS~/Library/Developer/Xcode/DerivedData/Test-hjtkgtqoywzwinaakrcdvgycyxhx/Build/Products/Debug/PackageFrameworks/ArgumentParser.framework/Versions/A/ArgumentParser'
(no such file)
Searching on the string "not valid for use in process: mapping process and mapped file (non-platform) have different Team IDs" yields some posts about signing a Mac product for distribution on Apple's developer forums.
I will eventually want to code sign the command line tool target so I can share it/distribute it on the App Store, but for now, I just want to develop the @#$@#$ command locally.
Question: How do I add the swift-argument-parser SPM package to my nascent command line tool so I can start writing my command?
I can upload the above minimum project to GitHub if it would be helpful, but it takes less than a minute to reproduce the errors above.
(I'm using Xcode 15.0, running on an M2 Mac with macOS Sonoma 14.0, if that matters.)
Does anybody know how to re-pair a watch with Xcode if you’ve anciently unpaired it?
Thanks
-> Failed to prepare device for development
Hi,
I am creating a custom NSSecureUnarchiveFromDataTransformer in order to handle attributes of entities of type NSDateComponents.
It all works and I did not see any warnings in the "Issue navigator" inside Xcode but with Xcode 15 I started seeing this warning:
/Users/.../CustomNSSecureUnarchiveFromDataTransformer/CoreData:1:1 no NSValueTransformer with class name 'CustomSecureUnarchiveFromDataTransformer' was found for attribute 'testDate' on entity 'Item'
My use case is very simple, I have this custom transformer:
@objc(CustomSecureUnarchiveFromDataTransformer)
final class CustomSecureUnarchiveFromDataTransformer: NSSecureUnarchiveFromDataTransformer {
override class var allowedTopLevelClasses: [AnyClass] {
return [NSDateComponents.self]
}
static let name = NSValueTransformerName(rawValue: String(describing: CustomSecureUnarchiveFromDataTransformer.self))
public static func register() {
let transformer = CustomSecureUnarchiveFromDataTransformer()
ValueTransformer.setValueTransformer(transformer, forName: name)
}
}
which is set to the Core data entity's "Transformer":
which leads to the warning in Xcode 15.
App works just fine and there are no problems during run time, but this warning is shown and I want to fix it.
Here is a simple test project https://github.com/VladimirAmiorkov/CustomNSSecureUnarchiveFromDataTransformer
Is it possible to use a string catalog to localize a settings bundle?
Currently, to localize a Settings.bundle, we need to create a folder for each language with a single strings file inside.
For example:
Settings.bundle
en.lproj > Root.strings
fr.lproj > Root.strings
de.lproj > Root.strings
...
Any way to convert that to a string catalog?
Thank you
This post is meant to provide useful information on how to build a set of xcframeworks from a hierarchy of Swift Packages containing a mix of ObjC and Swift. If you only want to build a single xcframework from a Swift Package, as this is not obvious either, you should find some useful info too.
Stuff that needs to be done for building an XCFramework from a Swift Package through xcodebuild
set library type to .dynamic in Package.swift
set SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES OTHER_SWIFT_FLAGS="-no-verify-emitted-module-interface" in xcodebuild command
no need to use 'archive' xcodebuild command, xcodebuild alone is enough
In generated framework :
copy public headers (in case of ObjC package)
copy (or create) module.modulemap file, or copy .swiftmodule file
copy umbrella header FooPackage-Swift.h from derived data (use -derivedDataPath xcodebuild option to retrieve it) in case of Swift Package, otherwise won't be useable from ObjC
copy resource bundle (if any)
In many cases I found that people are using xcodebuild archive for this task, but I find that not necessary. The archive doesn't contain anything more than what you get from xcodebuild only.
Here's the script I ended up writing : build_xcframework_from_swift_package.sh
Setup
A set of Swift Packages, containing Swift and ObjC code, with dependencies. We need to use these Packages in an app and also to create XCFrameworks from them.
The (simplified) dependencies are as follows :
CommonObjC <- Common <- Package1, Package2... <- GlobalPackage <- MainApp
Problems encountered, and their solutions
Many of these problems come from the fact that we need to use these modules both as Swift Packages and as XCFrameworks.
xcodebuild needs the library defined in the Swift Package to be explicitly declared of type .dynamic, otherwise only a .o is generated for a package
But if all libs are dynamic, then, in the Swift Package usecase, symbols in CommonObjC won't be visible from MainApp. If CommonObjC is explicitly added to MainApp's linked frameworks, Xcode issues a build error saying "CommonObjC is linked as a static library but cannot be built dynamically because there is a package product with the same name".
Solution : since we don't want libs to be dynamic for the case where the Swift Packages are used directly, have the library type set depending on a Environment var. There doesn't seem to be a way to pass Swift Compiler flags (-DFOO) to xcodebuild so that they are used when evaluating a Package.swift file.
This works :
func runtimeLibType() -> Product.Library.LibraryType?
{
return ProcessInfo.processInfo.environment["SPM_GENERATE_FRAMEWORK"] != nil ? .dynamic : nil
}
and then
let package = Package(
name: "FooPackage",
products: [
.library(
name: "FooPackage",
type: runtimeLibType(),
targets: ["FooPackage"]),
],
...
Symbols from a package Foo's dependency are not visible from another package or app using package Foo.
If Package Foo is in Swift, the solution is to use '@_exported' in the import statement for the dependency :
PackageFoo/SomeFile.swift :
@_exported import Dependency
then in App :
import PackageFoo
-> symbols from Dependency will be visible.
There is no equivalent solution in ObjC
Symbol export issues with "composed" package (ie a package built from two targets)
Solution is simply to not do that. Stick to one package being built from one target.
Importing a 2nd-level dependency in a public header works when building from SPM, but not when an app is importing the resulting xcframework (dependencies are not transient in this case)
For instance :
PackageRT depends on PackageCore which depends on PackageCoreObjC
PackageRT/include/public_header.h can '@import' PackageCoreObjC. It works as long as you build from SPM, but when you build PackageRT into an xcframework, importing the resulting xcframework will fail because the @import PackageCoreObjC in PackageRT/include/public_header.h fails because PackageCoreObjC module is not found.
Solution is to explicitly add PackageCoreObjC as a dependency to PackageRT.
It would be nice for Apple to integrate chatgpt, Open AI, and create their own artificial intelligence. Siri is not equipped to answer questions that AI can. With increasing AI prevalence and usability, Apple is behind.
Message to Apple: PLEASE UTILIZE AI TO MAKE APPLE THE BEST PLATFORM.
After the upgrade, some setting got splayed somewhere in Xcode. While running debug, now message console only shows a green line with with 'lldb' on the left hand side and some sort of input field.
Any clue as to what I need to change?
After update to ios17 and xcode 15 I cant use my 64gb Iphone 11 as Runner target
Xcode says that device capacity is unknown, but when I installed Xcode 14 - device recognised correctly
I tried to install xcode 15 beta, Mac 14 os beta, iOS 17 beta, nothing works, and I rollback to last stable versions, also I tried hard reset my Iphone, unpair device, clear Xcode cache
Please can someone help with this issue?
I'm trying to write performance tests with Xcode 15, but it's not working: even though setting a baseline seems to work (baseline data files are created), Xcode seems to ignore that baseline altogether whenever the test is run. As a result, performance tests never fail, no matter how bad performance gets.
The source editor persistently displays a “No baseline average for Time” message.
Has anyone else encountered this? Figured out how to sidestep the issue?
Of note, the issue is easily reproduced: create a new (macOS in my case) app project with tests, add a dummy performance test; run the test once and save its baseline, and despite this subsequent tests will always succeed, even if you significantly slow the dummy test down.
(I've filed this as FB13330139)
I havent been able to figure out a pattern/cause, but every week or so, my simulator loses most of its available iOS version options.
I should have 16.4 and 17 available, but you see I do not.
When I go into xcode, iOS 17.0 has 2 entries, one allegedly available, and one awaiting download.
Clicking "GET" on the grey one just pops a download windows which says its already downloaded.
The only thing that sorts this is a reboot and it's back to normal again - with all my iOS versions available in the simulator.
I dont want to keep having to reboot my dev machine.
What is going on with XCode and how do I fix it for good?
I have an app that links to two dynamic frameworks which both link to the same static library, as follows:
|--App
|--DynamicFramework1
|--StaticLibrary
|--DynamicFramework2
|--StaticLibrary <- the same library that DynamicFramework1 links to
The static library's symbols are included in each framework's binary because of the way dynamic frameworks are built by default. The app therefore finds duplicates of the static library's symbols at runtime.
Is it possible to link a dynamic framework to a static library (and to still be able to call on the classes and methods of the static library within the dynamic framework) in a manner that symbols from the static library are excluded from the dynamic framework's binary?
My hope in doing this is that the binary of each of the two dynamic frameworks will exclude the symbols of the static library. I will then make it the responsibility of the app to link to the static library directly.
Notes
I have tried linking my dynamic framework with the static library in two different ways thus far: (1) I added the static library to my framework's "Link Binary with Libraries" Build Phase; and (2) I referenced the static library in my framework's "Other Linker Flags" Build Setting. Both result in the static library's symbols being included in the framework's binary.
I am aware that changing a framework target's "Mach-O Type" from "Dynamic Framework" to "Static Library" will build the framework's binary without the symbols of the static libraries that it links to. I want to keep my frameworks as dynamic frameworks so that (1) I can benefit from how Xcode bundles together resources (strings, storyboards etc) automatically for dynamic frameworks; and (2) users of my framework can benefit from Mergeable Libraries in the near future.
I am aware that I can solve this problem by changing the static library to a dynamic framework. I want to avoid this as much as possible since the static library is from a third-party. I want to avoid forking the static library's source code and messing with its build scripts if I can.
Our CI pipeline produces .xcresult bundles that allow developers to diagnose failures by opening them in Xcode. If the test crashes, we used to be able to open the diagnostic folders and inspect the raw test logs. As of Xcode 15, that option is no longer available. I know the Diagnostic data is there because I can view it with Xcode 14. Am I just missing something in the Xcode 15 UI? Or has the capability to browse the Diagnostics actually been removed?