Hello,
I am working on updating my system for Xcode but it has hanged here from last 4 hours I checked my internet.
Thanks
Zippy Games
Xcode
RSS for tagBuild, test, and submit your app using Xcode, Apple's integrated development environment.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello everyone, I've encountered an issue with SwiftUI Preview and would appreciate your help.
Problem Description In a mixed Objective-C and Swift project, I'm experiencing the following situation with SwiftUI Preview:
Crashes when previewing on a physical device
The same code runs normally when launched directly through Xcode
Project uses CocoaPods for dependency management with static frameworks
Project Environment:
Project Type: Mixed (Objective-C + Swift)
Dependency Management: CocoaPods
Dependency Type: Static frameworks
Device: Physical device preview
Steps to Reproduce:
Write Preview code in SwiftUI file
Select physical device as Preview device
Click Preview button
Application crashes
Hi folks:
I see previous chatter re this linker error message here on the forums and out in the wild, but I haven't been able to figure out where or how to track down the details necessary to resolve. For background, I've had iOS apps in the AppStore since 2021. They're fine, but, I want to update them for newer iOS releases, and use Catalyst to create MacOS versions. After updating to Xcode 15.2 but without changing the code, these apps no longer compile. "404 duplicate symbols" linker error. Update the Cocoapods and frameworks: same. Very difficult to find details in Xcode - it would be great if the error message took one to exact sources, but clicking the error does nothing. Added the -v flag with no change. From Internet chatter this behavior seems to be new in 15.x. I would imagine some of you have overcome this before now. How do I resolve it and get back to work?
Thanks so much,
--Mark
Topic:
Developer Tools & Services
SubTopic:
Xcode
I'm working on dext project (c++), Base SDK and Supported Platforms are set to DriverKit.
#include causes errors:
error "The iostreams library is not supported since libc++ has been configured without support for localization."
error "<locale.h> is not supported since libc++ has been configured without support for localization."
Also it's not possible to define custom log object: undeclared identifier 'os_log_create'. <os/log.h> included and os_log function is compiled correct.
macOS as additional SDK did not help. Thanks a lot for any hint.
A new app I submitted to review was rejected due to a crash.
I cannot reproduce the crash, even running it on exact the same device model used by App Review.
So I need to symbolicate the ips crash log they provided me.
Using MacSymbolicate and the archive located using Xcode Organizer I was able to partially symbolicate the crash log.
To fully symbolicate the crash log, however, according to MacSymbolicate, I would need two more symbol files, which can't be located, because they relate to system frameworks (SwiftData and _SwiftData_SwiftUI).
I have tried to follow the instructions provided on
https://developer.apple.com/documentation/xcode/adding-identifiable-symbol-names-to-a-crash-report
but I had no success.
It seems to me that the instructions contained there for symbolicating using Xcode do not apply for crash logs downloaded from appstoreconnect after an App Review rejection. Also, the instructions seem to be out of date, e.g. "To symbolicate in Xcode, click the Device Logs button in the Devices and Simulators window.": This button was replaced by "Open Recent Logs", which opens what seems to be a different window (according to some online research).
Is it possible to fully symbolicate such an ips file downloaded from App Review team?
If so, how can this be achieved?
Thanks
This is how the partially symbolicated crash log looks like:
Hardware Model: iPad13,16
...
AppStoreTools: 16C5031b
Code Type: ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
...
OS Version: iPhone OS 18.2.1 (22C161)
Release Type: User
Report Version: 104
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000018c100e2c
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [6226]
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libswiftCore.dylib 0x18c100e2c _assertionFailure(_:_:file:line:flags:) + 264
1 SwiftData 0x24fa6f3b4 0x24fa4a000 + 152500
...
14 SwiftData 0x24fa89700 0x24fa4a000 + 259840
15 _SwiftData_SwiftUI 0x250cd34e4 0x250cce000 + 21732
16 _SwiftData_SwiftUI 0x250cd1364 0x250cce000 + 13156
17 XXX 0x10451f7ac closure #1 in closure #2 in closure #1 in PaymentsMonthView.body.getter (in XXX) (PaymentsMonthView.swift:119) + 1324972
18 XXX 0x10451ea14 closure #1 in PaymentsMonthView.body.getter (in XXX) (PaymentsMonthView.swift:99) + 1321492
19 SwiftUICore 0x24fd5d304 specialized ViewBodyAccessor.updateBody(of:changed:) + 1240
20 SwiftUICore 0x24fd5cd4c closure #1 in DynamicBody.updateValue() + 600
21 SwiftUICore 0x24fd5c008 DynamicBody.updateValue() + 928
...
...
Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x000000011128b208 x1: 0x0000000200000003 x2: 0x0000000000000001 x3: 0x00000001130be744
x4: 0xfffffffffe1cd413 x5: 0x0000000000000013 x6: 0x0000000000000020 x7: 0x00000000000007fc
x8: 0xfffffffe00000000 x9: 0x0000000200000003 x10: 0x0000000000000003 x11: 0x0000000000000000
x12: 0x00180080004019e0 x13: 0x00100000004017fc x14: 0x00000001046d23e0 x15: 0x00000000000001e0
x16: 0x952d0001130bde00 x17: 0x00000000020007fc x18: 0x0000000000000000 x19: 0x000000024fb661e0
x20: 0x000000011128b200 x21: 0x0000000000000000 x22: 0x000000000000000b x23: 0x000000000000001d
x24: 0x0000000000000040 x25: 0x000000024fb64790 x26: 0xf000000000000977 x27: 0x0000000000000000
x28: 0x000000024fb64750 fp: 0x000000016ba188f0 lr: 0x000000018c100e2c
sp: 0x000000016ba18820 pc: 0x000000018c100e2c cpsr: 0x60001000
far: 0x0000000000000000 esr: 0xf2000001 (Breakpoint) brk 1
Binary Images:
0x1043dc000 - 0x104633fff Locador arm64 <78fc8961d731321ba0c8f9bb051109c5> /private/var/containers/Bundle/Application/FE1C10C5-49C1-4022-860A-6C3515E2F8BB/Locador.app/Locador
0x1047fc000 - 0x104807fff libobjc-trampolines.dylib arm64e <be05652226b13a508ad193ac99fcdc9c> /private/preboot/Cryptexes/OS/usr/lib/libobjc-trampolines.dylib
0x18c0c9000 - 0x18c66afff libswiftCore.dylib arm64e <e9b1dc6b7fef3bbbb083f4e8faaa53df> /usr/lib/swift/libswiftCore.dylib
0x24fa4a000 - 0x24fb88ff7 SwiftData arm64e <90275b26954b349996ff44ada39f0358> /System/Library/Frameworks/SwiftData.framework/SwiftData
0x250cce000 - 0x250cebff8 _SwiftData_SwiftUI arm64e <d250fe30854c3f1c85fc8a89dec5d484> /System/Library/Frameworks/_SwiftData_SwiftUI.framework/_SwiftData_SwiftUI
0x24fcf8000 - 0x2508d4fff SwiftUICore arm64e <647b91f1620d3741bd708f9f26b5674b> /System/Library/Frameworks/SwiftUICore.framework/SwiftUICore
0x1ba831000 - 0x1ba874fff AttributeGraph arm64e <5eeff865ac123665a9dba9d612eb0e9f> /System/Library/PrivateFrameworks/AttributeGraph.framework/AttributeGraph
0x19220e000 - 0x1934d0fff SwiftUI arm64e <0b283f5831ae385f9c8ff128fd0e30b8> /System/Library/Frameworks/SwiftUI.framework/SwiftUI
0x1902f8000 - 0x19220dfff UIKitCore arm64e <f80c6ee450ca346f90ebbb3da9817503> /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore
0x18dadc000 - 0x18e01ffff CoreFoundation arm64e <6a60be13e6573beca9acba239ae29862> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
0x1dacec000 - 0x1dacf4fff GraphicsServices arm64e <f4e7a885f4913721862dc57403f4d821> /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices
0x1b3d31000 - 0x1b3db413f dyld arm64e <4eb7459fe23738ce82403f3e2e1ce5ab> /usr/lib/dyld
0x0 - 0xffffffffffffffff ??? unknown-arch <00000000000000000000000000000000> ???
0x1df105000 - 0x1df13efe3 libsystem_kernel.dylib arm64e <e3965df1a3a3374a94eaf86739c5cc8e> /usr/lib/system/libsystem_kernel.dylib
0x18c6e1000 - 0x18d411fff Foundation arm64e <7274dde368d634a08e677726e1265e80> /System/Library/Frameworks/Foundation.framework/Foundation
0x2185fc000 - 0x218608ff3 libsystem_pthread.dylib arm64e <b2fe0dfa67de3d7282676c42073e0e8d> /usr/lib/system/libsystem_pthread.dylib
0x1958ce000 - 0x19594dffb libsystem_c.dylib arm64e <8d425c7257c93e54a1e1e243cbdfc446> /usr/lib/system/libsystem_c.dylib
EOF
I am using Xcode16, old React Native.
I don't know why CLANG_CXX_LANGUAGE_STANDARD in Pods is gnu++14 when I pod install locally, but gnu++20 when I pod install with CircleCI
How to collaborate project between Unity Dev and Xcode SwiftUI Dev, is it possible..?
and how is the workflow for that if possible..?
Today I got stuck with a weird behaviour with my c++ project. There is the code which doesn't catch exception from standard library (the same snippet works well on intel mac and under linux machines).
Code snippet:
#include <exception>
#include <stdexcept>
#include <iostream>
#include <string>
int main() {
try {
std::stod("notanumber");
} catch (const std::invalid_argument&) {
std::cerr << "Caught std::invalid_argument" << std::endl;
}
}
Compilation command:
clang++ -fno-rtti main.cpp -o main && ./main
Clang versions:
clang++ --version
Homebrew clang version 15.0.3
Target: arm64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm/bin
Also tried:
Apple clang version 14.0.0 (clang-1400.0.29.102)
Target: arm64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Output:
libc++abi: terminating with uncaught exception of type std::invalid_argument: stod: no conversion
[1] 65643 abort ./main
Expected output:
Caught std::invalid_argument
Other info:
Chip: Apple M1
OS: 12.6
I have tried all of the above options, cleaned cached data, restarted several times, did not work.
The tunnel connection failed while the system tried to connect to the device.
Domain: com.apple.dt.RemotePairingError
Code: 4
System Information
macOS Version 15.2 (Build 24C101)
Xcode 16.2 (23507) (Build 16C5032a)
iOs 18.1.1
Hi,
I have recently noticed a very-very annoying thing in my CI pipeline, that I managed to reproduce locally.
Using macOS Sonoma 14.7.1 and Xcode 15.4, running a test target from Terminal, the first run produces this output:
$ xcodebuild test -workspace [redacted].xcworkspace -scheme [redacted] -quiet
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:[redacted], name:My Mac }
{ platform:macOS, arch:x86_64, id:[redacted], name:My Mac }
{ platform:macOS, name:Any Mac }
Testing started
Test suite '[redacted]' started on 'My Mac - [redacted] (75944)'
Test case '[redacted].[redacted]()' passed on 'My Mac - [redacted] (75944)' (0.001 seconds)
Test case '[redacted].[redacted]()' passed on 'My Mac - [redacted] (75944)' (0.001 seconds)
2024-11-29 19:31:02.311 xcodebuild[75908:47784216] [MT] IDETestOperationsObserverDebug: 1.380 elapsed -- Testing started completed.
2024-11-29 19:31:02.311 xcodebuild[75908:47784216] [MT] IDETestOperationsObserverDebug: 0.000 sec, +0.000 sec -- start
2024-11-29 19:31:02.311 xcodebuild[75908:47784216] [MT] IDETestOperationsObserverDebug: 1.380 sec, +1.380 sec -- end
so the test actually completes, but the process does not end, because I get a popup that
“Terminal.app” would like to access data from other apps.
Removing the "App Sandbox" entitlement immediately alleviates this problem, but it would be very silly to do so because of unit tests.
This ultimately means that whenever we use a new device or include a new project or test target, this popup comes up. Very undesirable for CI servers (especially if the servers are ephemeral virtual machines created for the current job).
Is there a permanent solution that disables this popup for test runs?
My widget uses the @Environment(.isActivityFullscreen) variable. When running on ios 17, it will crash and report an error:
dyld[55031]: Symbol not found: _$s7SwiftUI17EnvironmentValuesV9WidgetKitE20isActivityFullscreenSbvg
Expected in: /Library/Developer/CoreSimulator/Volumes/iOS_21E213/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/WidgetKit.framework/WidgetKit
I’ve developed an Apple Watch extension for an existing iOS app. When I run the app on the watch via Xcode using the simulator, everything works fine. However, when I try to install it on my iPhone, the Watch app doesn’t show it in the "Available Apps" list, so I can't install it on the watch.
The Apple Watch is connected to my iPhone, and I can see other apps available for installation without any issues.
I also created a brand new project with watchOS support to troubleshoot, but the same problem occurred.
Any ideas on how to resolve this?
I followed this guide, and added com.apple.developer.spatial-audio.profile-access as an entitlement to the app (via the + Capability button – Spatial Audio Profile). I have a audio graph that outputs to AVAudioEngine.
However, the Xcode Cloud build ended up with this error:
Invalid Code Signing Entitlements. Your application bundle's signature contains code signing entitlements that are not supported on iOS. Specifically, key 'com.apple.developer.spatial-audio.profile-access' in 'Payload/…' is not supported.
This guide says it's available on iOS. Does it mean not on iOS 17? In which case how can I provide fallback for iOS 17?
It looks like Xcode 16 has changed this behavior so I'm not sure if this is a bug or not.
When a SwiftUI Button wraps a UIButton, the button doesn't work on iOS 18.0+
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Button(action: {
print("Not called on iOS 18")
}) {
WrapperButton()
.frame(width: 200, height: 50)
}
}
}
}
struct WrapperButton: UIViewRepresentable {
func makeUIView(context: Context) -> some UIView {
let button = UIButton(type: .system)
button.setTitle("OK", for: .normal)
return button
}
func updateUIView(_ uiView: UIViewType, context: Context) {}
}
This occurs with the app build with Xcode 16 and running on iOS 18
but it was worked with Xcode 15 builds and running on iOS 18
I am currently investigating an issue with my app's slow launch time in Xcode 16. However, when I open the Launches pane in the Xcode Organizer, I can only see the report list, but I encounter an error message like the one below in the stack trace.
This issue also occurs in the Disk Writes, Energy, and Hangs panes, but not in the Crashes pane.
Can someone advise me on what steps I should take? Any help would be greatly appreciated.
I have an AppleTV app which I released in 2016. I've updated it and released a new version every year without much hassle.
This year, with tvOS 17.2, the layered app icon isn't working right. This is a two-layer image made with PNGs.
When it's selected, it looks right and the layers move correctly:
But when it's not selected, the background layer disappears:
Screenshots are from the simulator but it also happens on the device. It's inconsistent; sometimes it's the front layer that disappears. Occasionally both layers work, but I can't tell why.
I've spent a day trying everything. Very frustrated.
The icon previews correctly in Xcode and in Parallax Viewer.
The image sizes are correct: 400 x 240 for Small, 800 x 480 for Small@2x, 1280 x 768 for Large.
The back layer is a non-transparent PNG.
I tried adding a Large@2x set. Didn't help.
Originally I had a three-layer image with no middle layer PNG. I deleted the empty middle layer, but that didn't help.
All the PNG files are from GnuIMP. Same color space, even.
I was using the filenames tvicon-back-s.png and tvicon-back-s@2x.png. I tried taking out the @ sign in case that was confusing Xcode. (It never has before, but I am flailing here.)
Anybody have any clues? If it's an Apple bug and there's nothing I can do, I'm going to just push the release button and hope it fixes itself someday.
Hi, so a little context, by environment variables I mean like $HOME in linux. I know that there are some standard and some app specific environment variables in the above mentioned platforms.
Is is possible for the user to set environment variables? If so, what are the ways in which users can set environment variables in the platforms mentioned across the system or for the app as they would in macOS/linux/windows?
And is it possible for developers of the app do the same? If so how?
What I have found so far is that it cannot be done by users, and there is one place in xcode where I, as a developer can set environment variables for my app from the scheme. This isn't available when I ship just the installation binary to the end user, but rather is available only when the app is run using xcode. I just need validation that what I understand is correct and that there aren't other ways to do this by the user/developer without jailbreaking.
I have an XCTest unit test that's running in an iOS host but with the My Mac (Designed For iPad) Target.
Enabling mergeable libraries causes two errors:
Symbol not found: _$s10Foundation3URLV9RVAPIPackE8isGCSURLSbvg
And "loading failed because of an error Error Domain=NSCocoaErrorDomain Code=3588" for the Test bundle because one of the frameworks that's supposed to be merged couldn't be loaded.
Disabling mergeable libraries fixes it. It also works with mergeable libraries enabled but with a regular simulator target. So not sure if I'm missing something or if I need to disable mergeable libraries now:/
I created a new iOS project (storyboard if it matters) and added a bunch of C files to it. Some portion of the C files depend on libcurl. I would like to be able to build for both simulator and device if possible. Google claims that Xcode can provide the dependency as part of the inbuilt libraries however I do not see libcurl.4.tbd (or any version) as an option to choose. Is this feature no longer available or is there something I am missing here?
For context here is a screen shot of my build error situation
I often get questions about third-party crash reporting. These usually show up in one of two contexts:
Folks are trying to implement their own crash reporter.
Folks have implemented their own crash reporter and are trying to debug a problem based on the report it generated.
This is a complex issue and this post is my attempt to untangle some of that complexity.
If you have a follow-up question about anything I've raised here, please put it in a new thread with the Debugging tag.
IMPORTANT All of the following is my own direct experience. None of it should be considered official DTS policy. If you have a specific question that needs a direct answer — perhaps you’re trying to convince your boss that implementing your own crash reporter is a very bad idea — start a dedicated thread here on the forums and we can discuss the details there. Use whatever subtopic is appropriate for your issue, but make sure to add the Debugging tag so that I see it go by.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Scope
First, I can only speak to the technical side of this issue. There are other aspects that are beyond my remit:
I don’t work for App Review, and only they can give definitive answers about what will or won’t be allowed on the store.
Implementing your own crash reporter has significant privacy implications.
IMPORTANT If you implement your own crash reporter, discuss the privacy impact with a lawyer.
This post assumes that you are implementing your own crash reporter. A lot of folks use a crash reporter from another third party. From my perspective these are the same thing. If you use a custom crash reporter, you are responsible for its behaviour, both good and bad, regardless of where the actual code came from.
Note If you use a crash reporter from another third party, run the tests outlined in Preserve the Apple Crash Report to verify that it’s working well.
General Advice
I strongly advise against implementing your own crash reporter. It’s very easy to create a basic crash reporter that works well enough to debug simple problems. It’s impossible to implement a good crash reporter, one that’s reliable, binary compatible, and sufficient to debug complex problems. The bulk of this post is a low-level explanation of that impossibility.
Rather than attempting the impossible, I recommend that you lean in to Apple’s crash reporter. In recent years it’s acquired some really cool new features:
If you’re creating an App Store app, the Xcode organiser gives you easy, interactive access to Apple crash reports.
If you’re an enterprise developer, consider switching to Custom App Distribution. This yields all the benefits of App Store distribution without your app being generally available on the store.
iOS 14 and macOS 12 report crashes in MetricKit. This is a very cool feature, and I’m surprised by how few people use it effectively.
If you previously dismissed Apple crash reports as insufficient, I encourage you to reconsider that decision.
Why Is This Impossible?
Earlier I said “It’s impossible to implement a good crash reporter”, and I want to explain why I’m confident enough in my conclusions to use that specific word. There are two fundamental problems here:
On iOS (and the other iOS-based platforms, watchOS and tvOS) your crash reporter must run inside the crashed process. That means it can never be 100% reliable. If the process is crashing then, by definition, it’s in an undefined state. Attempting to do real work in that state is just asking for problems [1].
To get good results your crash reporter must be intimately tied to system implementation details. These can change from release to release, which invalidates the assumptions made by your crash reporter. This isn’t a problem for the Apple crash reporter because it ships with the system. However, a crash reporter that’s built in to your product is always going to be brittle.
I’m speaking from hard-won experience here. I worked for DTS during the PowerPC-to-Intel transition, and saw a lot of folks with custom crash reporters struggle through that process.
Still, this post exists because lots of folks ignore this reality, so the subsequent sections contain advice about specific technical issues.
WARNING Do not interpret any of the following as encouragement to implement your own crash reporter. I strongly advise against that. However, if you ignore my advice then you should at least try to minimise the risk, which is what the rest of this document is about.
[1] On macOS it’s possible for your crash reporter to run out of process, just like the Apple crash reporter. However, possible is not the same as easy. In fact, running out of process can make things worse: It prevents you from geting critical state for the crashed process without being tightly bound to OS implementation details. It would be nice if Apple provided APIs for this sort of thing, but that’s currently not the case.
Preserve the Apple Crash Report
You must ensure that your crash reporter doesn’t disrupt the Apple crash reporter. This is important for three reasons:
Some fraction of your crashes will not be caused by your code but by problems in framework code, and accurate Apple crash reports are critical in diagnosing such issues.
When dealing with really hard-to-debug problems, you need the more obscure info that’s shown in the Apple crash report.
If you’re working with someone from Apple (here on the forums, via a bug report, or a DTS case, or whatever), they’re going to want an accurate Apple crash report. If your crash reporter is disrupting the Apple crash reporter — either preventing it from generating crash reports entirely [1], or distorting those crash reports — that limits how much they can help you.
IMPORTANT This is not a theoretical concern. The forums have many threads where I’ve been unable to help folks debug a gnarly problem because their third-party crash reporter didn’t preserve the Apple crash report (see here, here, and here for some examples).
To avoid these issues I recommend that you test your crash reporter’s impact on the Apple crash reporter. The basic idea is:
Create a program that generates a set of specific crashes.
Run through each crash.
Verify that your crash reporter produces sensible results.
Verify that the Apple crash reporter produces the same results as it does without your crash reporter
With regards step 1, your test suite should include:
An un-handled language exception thrown by your code
An un-handled language exception thrown by the OS (accessing an NSArray out of bounds is an easy way to get this)
Various machine exceptions (at a minimum, memory access, illegal instruction, and breakpoint exceptions)
Stack overflow
Make sure to test all of these cases on both the main thread and a secondary thread.
With regards step 4, check that the resulting Apple crash report includes correct values for:
The exception info
The crashed thread
That thread’s state
Any application-specific info, and especially the last exception backtrace
[1] A particularly pathological behaviour here is to end your crash reporter by calling exit. This completely suppresses the Apple crash report. Some third-party language runtimes ‘helpfully’ include such a crash reporter, which makes it very hard to debug problems that occur within your process but outside of that language.
Signals
Many third-party crash reporters use UNIX signals to catch the crash. This is a shame because using Mach exception handling, the mechanism used by the Apple crash reporter, is generally a better option. However, there are two reasons to favour UNIX signals over Mach exception handling:
On iOS-based platforms your crash reporter must run in-process, and doing in-process Mach exception handling is not feasible.
Folks are a lot more familiar with UNIX signals. Mach exception handling, and Mach messaging in general, is pretty darned obscure.
If you use UNIX signals for your crash reporter, be aware that this API has some gaping pitfalls. First and foremost, your signal handler can only use async signal safe functions [1]. You can find a list of these functions in sigaction man page [2] [3].
WARNING This list does not include malloc. This means that a crash reporter’s signal handler cannot use Objective-C or Swift, as there’s no way to constrain how those language runtimes allocate memory [4]. That means you’re stuck with C or C++, but even there you have to be careful to comply with this constraint.
The Operative: It’s worse than you know.
Captain Malcolm Reynolds: It usually is.
Many crash reports use functions like backtrace (see its man page) to get a backtrace from their signal handler. There’s two problems with this:
backtrace is not an async signal safe function.
backtrace uses a naïve algorithm that doesn’t deal well with cross signal handler stack frames [5].
The latter point is particularly worrying, because it hides the identity of the stack frame that triggered the signal.
If you’re going to backtrace out of a signal, you must use the crashed thread’s state (accessible via the handlers uap parameter) to start your backtrace.
Apropos that, if your crash reporter wants to log the state of the crashed thread, that’s the place to get it.
Your signal handler must be prepared to be called by multiple threads. A typical crashing signal (like SIGSEGV) is delivered to the thread that triggered the machine exception. While your signal handler is running on that thread, other threads in your process continue to run. One of these threads could crash, causing it to call your signal handler.
It’s a good idea to suspend all threads in your process early in your signal handler. However, there’s no way to completely eliminate this window.
Note The need to suspend all the other threads in your process is further evidence that sticking to async signal safe functions is required. An unsafe function might depend on a thread you’ve suspended.
A typical crashing signal is delivered on the thread that triggered the machine exception. If the machine exception was caused by a stack overflow, the system won’t have enough stack space to call your signal handler. You can tell the system to switch to an alternative stack (see the discussion of SA_ONSTACK in the sigaction man page) but that isn’t a complete solution (because of the thread issue discussed immediately above).
Finally, there’s the question of how to exit from your signal handler. You must not call exit. There’s two problems with doing that:
exit is not async signal safe. In fact, exit can run arbitrary code via handlers registered with atexit. If you want to exit the process, call _exit.
Exiting the process is a bad idea anyway, because it will prevent the Apple crash reporter from running. This is very poor form. For an explanation as to why, see Preserve the Apple Crash Report (above).
A better solution is to unregister your signal handler (set it to SIG_DFL) and then return. This will cause the crashed process to continue execution, crash again, and generate a crash report via the Apple crash reporter.
[1] While the common signals caught by a crash reporter are not technically async signals (except SIGABRT), you still have to treat them as async signals because they can occur on any thread at any time.
[2] It’s reasonable to extend this list to other routines that are implemented as thin shims on a system call. For example, I have no qualms about calling vm_read (see below) from a signal handler.
[3] Be aware, however, that even this list has caveats. See my Async Signal Safe Functions vs Dyld Lazy Binding post for details.
[4] I expect that it’ll eventually be possible to write signal handlers in Swift, possibly using some facility that evolves from the the existing, but unsupported, @_noAllocation and @_noLocks attributes. If you’d like to get involved with that effort, I recommend that engage with the Swift Evolution process.
[5] Cross signal handler stack frames are pushed on to the stack by the kernel when it runs a signal handler on a thread. As there’s no API to learn about the structure of these frames, there’s no way to backtrace across one of these frames in isolation. I’m happy to go into details but it’s really not relevant to this discussion [6]. If you’re interested, start a new thread with the Debugging tag and we can chat there.
[6] (Arg, my footnotes have footnotes!) The exception to this is where your trying to generate a crash report for code running in a signal handler. That’s not easy, and frankly you’re better off avoiding signal handlers in general. Where possible, handle signals via a Dispatch event source.
Reading Memory
A signal handler must be very careful about the memory it touches, because the contents of that memory might have been corrupted by the crash that triggered the signal. My general rule here is that the signal handler can safely access:
Its code
Its stack (subject to the constraints discussed earlier)
Its arguments
Immutable global state
In the last point, I’m using immutable to mean immutable after startup. It’s reasonable to set up some global state when the process starts, before installing your signal handler, and then rely on it in your signal handler.
Changing any global state after the signal handler is installed is dangerous, and if you need to do that you must be careful to ensure that your signal handler sees consistent state, even though a crash might occur halfway through your change.
You can’t protect this global state with a mutex because mutexes are not async signal safe (and even if they were you’d deadlock if the mutex was held by the thread that crashed). You should be able to use atomic operations for this, but atomic operations are notoriously hard to use correctly (if I had a dollar for every time I’ve pointed out to a developer they’re using atomic operations incorrectly, I’d be very badly paid (-: but that’s still a lot of developers!).
If your signal handler reads other memory, it must take care to avoid crashing while doing that read. There’s no BSD-level API for this [1], so I recommend that you use vm_read.
[1] The traditional UNIX approach for doing this is to install a signal handler to catch any memory access exceptions triggered by the read, but now we’re talking signal handling within a signal handler and that’s just silly.
Writing Files
If your want to write a crash report from your signal handler, you must use low-level UNIX APIs (open, write, close) because only those low-level APIs are documented to be async signal safe. You must also set up the path in advance because the standard APIs for determining where to write the file (NSFileManager, for example) are not async signal safe.
Offline Symbolication
Do not attempt to do symbolication from your signal handler. Rather, write enough information to your crash report to support offline symbolication. Specifically:
The addresses to symbolicate
For each Mach-O image in the process:
The image’s path
The image’s build UUID [1]
The image’s load address
You can get most of the Mach-O image information using the APIs in <mach-o/dyld.h> [2]. Be aware, however, that these APIs are not async signal safe. You’ll need to get this information in advance and cache it for your signal handler to record.
This is complicated by the fact that the list of Mach-O images can change as you process loads and unloads code. This requires you to share mutable state with your signal handler, which is exactly what I recommend against in Reading Memory.
Note You can learn about images loading and unloading using _dyld_register_func_for_add_image and _dyld_register_func_for_remove_image respectively.
[1] If you’re unfamiliar with that term, see TN3178 Checking for and resolving build UUID problems and the documents it links to.
[2] I believe you’ll need to parse the Mach-O load commands to get the build UUID.
What to Include
When deciding what to include in a crash report, there’s a three-way balance to be struck:
The more information you include, the easier it is to diagnose problems.
Some information is hard to obtain, either because there’s no public API to get that information, or because the API is not available to your crash reporter.
Some information is so privacy-sensitive that it has no place in a crash report.
Apple’s crash reporter strikes its own balance here, and I recommend that you try to include everything that it includes, subject to the limitations described in the second point.
Here’s what I’d considered to be a minimal list:
Information about the machine exception that triggered the crash
For memory access exceptions, the address of the access that triggered the crash
Backtraces of all the threads (sometimes the backtrace of a non-crashing thread can yield critical information about the crash)
The crashed thread
Its thread state
A list of Mach-O images, as discussed in the Offline Symbolication section
IMPORTANT Make sure you report the thread backtraces in a consistent order. Without that it’s hard to correlate information across crash reports.
Revision History
2025-08-25 Added some links to examples of third-party crash reports not preserving the Apple crash report. Added a link to TN3178. Made other minor editorial changes.
2022-05-16 Fixed a broken link.
2021-09-10 Expanded the General Advice section to include pointers to Apple crash report resources, including MetricKit. Split the second half of that section out in to a new Why Is This Impossible? section. Made minor editoral changes.
2021-02-27 Fixed the formatting. Made minor editoral changes.
2019-05-13 Added a reference to my Async Signal Safe Functions vs Dyld Lazy Binding post.
2019-02-15 Expanded the introduction to the Preserve the Apple Crash Report section.
2019-02-14 Clarified the complexities of an out-of-process crash reporter. Added the What to Include section. Enhanced the Signals section to cover reentrancy and stack overflow. Made minor editoral changes.
2019-02-13 Made minor editoral changes. Added a new footnote to the Signals section.
2019-02-12 First posted.