My app's top crash is a mysterious one and I can't seem to figure it out. It always crashes on
_objc_fatalv(unsigned long long, unsigned long long, char const*, char*)
But the stack traces include a few different possible culprits like
NavigationBridge_PhoneTV.pushTarget(isDetail:)
UIKitNavigationBridge.update(environment:)
ViewRendererHost.updateGraph()
UIScrollView(SwiftUI) _swiftui_adjustsContentInsetWhenScrollDisabled
Crash reports here:
2024-12-02_21-37-21.7864_-0600-1e78918e5586309b96a1c2986ff722778dec8a77.crash
2024-12-02_19-18-29.1251_-0500-a2fc5513683cd647b4adbbe03cc59e4a09237b5f.crash
2024-12-01_11-59-09.8888_-0500-9eb224ab3d37e76d0b966ea83473f584ac3bbe18.crash
2024-11-28_17-17-38.4808_+0100-46208989f016fbefd16c30873a88c2ef61dd91a1.crash
Hopefully someone here can shed some light. For context we use a lot of UIHostingController's to bridge our SwiftUI views.
Objective-C Runtime
RSS for tagThe Objective-C runtime is a runtime library that supports the dynamic properties of the Objective-C language.
Posts under Objective-C Runtime tag
25 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hey there! My app's top crash is a mysterious one and I can't seem to figure it out. Hopefully someone here can shed some light. For context we use a lot of UIHostingController's to bridge our SwiftUI views.
Crashed: com.apple.main-thread
0 libsystem_kernel.dylib 0x13ec4 __abort_with_payload + 8
1 libsystem_kernel.dylib 0x33bec abort_with_payload_wrapper_internal + 104
2 libsystem_kernel.dylib 0x33b84 abort_with_payload_wrapper_internal + 30
3 libobjc.A.dylib 0xbea0 _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 116
4 libobjc.A.dylib 0xbe2c _objc_fatalv(unsigned long long, unsigned long long, char const*, char*) + 30
5 libobjc.A.dylib 0xb040 weak_register_no_lock + 396
6 libobjc.A.dylib 0xa9bc objc_initWeak + 440
7 libswiftCore.dylib 0x43abe8 swift_unknownObjectWeakInit + 92
8 SwiftUI 0xf40cc NavigationBridge_PhoneTV.pushTarget(isDetail:) + 376
9 SwiftUI 0xf9490 UIKitNavigationBridge.update(environment:) + 1060
10 SwiftUI 0x5b51c UIHostingController._update(environment:) + 156
11 SwiftUI 0x96a30 _UIHostingView.updateEnvironment() + 3484
12 SwiftUICore 0xa0d0a0 closure #1 in ViewRendererHost.updateGraph() + 364
13 SwiftUICore 0xa0ca08 ViewRendererHost.updateGraph() + 180
14 SwiftUICore 0xa0d7d4 closure #1 in ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 368
15 SwiftUICore 0xa0b0d4 ViewRendererHost.render(interval:updateDisplayList:targetTimestamp:) + 556
16 SwiftUI 0x8f1634 UIHostingViewBase.renderForPreferences(updateDisplayList:) + 168
17 SwiftUI 0x8f495c closure #1 in UIHostingViewBase.requestImmediateUpdate() + 72
18 SwiftUI 0xcc700 thunk for @escaping @callee_guaranteed () -> () + 36
19 libdispatch.dylib 0x2370 _dispatch_call_block_and_release + 32
20 libdispatch.dylib 0x40d0 _dispatch_client_callout + 20
21 libdispatch.dylib 0x129e0 _dispatch_main_queue_drain + 980
22 libdispatch.dylib 0x125fc _dispatch_main_queue_callback_4CF + 44
23 CoreFoundation 0x56204 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 16
24 CoreFoundation 0x53440 __CFRunLoopRun + 1996
25 CoreFoundation 0x52830 CFRunLoopRunSpecific + 588
26 GraphicsServices 0x11c4 GSEventRunModal + 164
27 UIKitCore 0x3d2eb0 -[UIApplication _run] + 816
28 UIKitCore 0x4815b4 UIApplicationMain + 340
29 (MyApp) 0x1a7e0 main + 8 (main.swift:8)
30 ??? 0x1bf97eec8 (Missing)
I'll describe my crash with an example, looking for some insights into the reason why this is happening.
@objc public protocol LauncherContainer {
var launcher: Launcher { get }
}
@objc public protocol Launcher: UIViewControllerTransitioningDelegate {
func initiateLaunch(url: URL, launchingHotInstance: Bool)
}
@objc final class LauncherContainer: NSObject, LauncherContainer, TabsContentCellTapHandler {
...
init(
...
) {
...
super.init()
}
...
//
// ContentCellTapHandler
//
public func tabContentCellItemDidTap(
tabId: String
) {
...
launcher.initiateNewTabNavigation(
tabId: tabId // Crash happens here
)
}
public class Launcher: NSObject, Launcher, FooterPillTapHandler {
public func initiateNewTabNavigation(tabId: String) {
...
}
}
public protocol TabsContentCellTapHandler: NSObject {
func tabContentCellItemDidTap(
tabId: String,
}
Hello,
i know this topic is here since ever, also in other forums, however this topic i face for a month and cant get pass it, I tried all other suggestions which didnt bring me anywhere.
so, project using cmake in order for Qt creator (so c++ base project with enabled swift), however once i run a cmake which generates *.xcodeproj for Xcode, i open it via xcode and can properly build and deploy to device.
however when I try to archive and sent to Testflight/AppStore, I get:
ITMS-90426: Invalid Swift Support
and when I try to followup guides to create it manualy, copying libs from:
$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
plese here note, that ALL guides indicate to use folder "swift", however there are no *.dylib files... they are only in "swift-5.0" folder
then I receive an error type:
ITMS-90429: Invalid Swift Support - The files libswiftMetal.dylib, libswiftHomeKit.dylib, libswiftsimd.dylib, libswiftCallKit.dylib, libswiftos.dylib, libswiftNetwork.dylib, libswiftMapKit.dylib, libswiftCoreLocation.dylib, libswiftAccelerate.dylib, libswiftCoreGraphics.dylib, libswiftSceneKit.dylib, libswiftCoreData.dylib, libswiftGameplayKit.dylib, libswiftUIKit.dylib, libswiftMetalKit.dylib, libswiftCore.dylib, libswiftFoundation.dylib, libswiftPhotos.dylib, libswiftModelIO.dylib, libswiftWatchKit.dylib, libswiftDarwin.dylib, libswiftARKit.dylib, libswiftAssetsLibrary.dylib, libswiftSpriteKit.dylib, libswiftNaturalLanguage.dylib, libswiftCoreAudio.dylib, libswiftIntents.dylib, libswiftQuartzCore.dylib, libswiftObjectiveC.dylib, libswiftDispatch.dylib, libswiftCoreFoundation.dylib, libswiftCoreMedia.dylib, libswiftVision.dylib, libswiftAVFoundation.dylib, libswiftContacts.dylib, libswiftGLKit.dylib, libswiftSwiftOnoneSupport.dylib, libswiftXCTest.dylib, libswiftMediaPlayer.dylib, libswiftCloudKit.dylib, libswiftCoreImage.dylib aren’t at the expected location /Payload/Filmtoro.app/Frameworks. Move the file to the expected location, rebuild your app using the current public (GM) version of Xcode, and resubmit it.
here please also note that actually *.xcarchive does not contain any "Payload" folder, the package contains only two folders "dSYMs" and "Production/Applications/myapp.app" (inside it I can find "Frameworks" folder...
this link was also very interested:
https://indiestack.com/2017/03/implicit-swift-dependencies/
tho id didnt help a bit :)
so what I would like to know, is what actually forces xcode to generate the SwiftSupport folder to the archive... the must be some direct setting inside *.xcodeproj/pbxproj which forces it... or dirrect setting in xcode/Build Settings which if not work I can submit an ticket to investigate.
I am sure after a month of trying everything, whatever tip you can point out I already tried, however Please lets try everything again to get bottom of this.
Many thanks for any tip
This is similar to this post https://developer.apple.com/forums/thread/700770 on using objc_copyClassList to obtain the available classes. When iterating the list, I try casting the result to an instance of a protocol and that works fine:
protocol DynamicCounter {
init(controlledByPlayer: Bool, game: Game)
}
class BaseCounter: NSObject, DynamicCounter {
}
static func withAllClasses<R>(
_ body: (UnsafeBufferPointer<AnyClass>) throws -> R
) rethrows -> R {
var count: UInt32 = 0
let classListPtr = objc_copyClassList(&count)
defer {
free(UnsafeMutableRawPointer(classListPtr))
}
let classListBuffer = UnsafeBufferPointer(
start: classListPtr, count: Int(count)
)
return try body(classListBuffer)
}
static func initialize() {
let monoClasses = withAllClasses { $0.compactMap { $0 as? DynamicCounter.Type } }
for cl in monoClasses {
cl.initialize()
}
}
The above code works fine if I use DynamicCounter.Type on the cast but crashes if try casting to BaseCounter.Type instead.
Is there a way to avoid the weird and non Swift classes?
I recently bought a new phone and update xcode version to the latest. An app that I have been developing and worked perfectly fine would not be runned. I kept getting errors similar to below. Is that anything wrong with my setting or something?
Class _TtC6SQLite6Backup is implemented in both /System/Library/PrivateFrameworks/LinkServices.framework/LinkServices (0x1f16db218) and /private/var/containers/Bundle/Application/E2xxxx2xxA-DF7B-xx-***-xxxxxxxx/xxxx.app/xxxxx.debug.dylib (0xxxxxx3d0). One of the two will be used. Which one is undefined.
I am developing SDK and swizzling viewDidAppear.
I have a customer who implements a custom TabBar Navigation where VC's are added to the hierarchy on the first load, and then, he changes the opacity to the currently displayed tab so the next time the user sees the tab - viewDidAppear isn't called, so my code isn't called.
I'm attaching a sample project which reproduces that.
Is there any way to trigger ViewDidAppear intentionally?
If yes, what can be the side effect of doing that?
Do I have any other alternative in this case?
@main
struct DemoCustomTabViewApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
TabBarRouterView()
}
}
}
import UIKit
// MARK: - TabBarItem (unchanged)
enum TabBarItem: Identifiable, CaseIterable {
case home, search, profile
var id: Self { self }
var title: String {
switch self {
case .home: return "Home"
case .search: return "Search"
case .profile: return "Profile"
}
}
var icon: String {
switch self {
case .home: return "house"
case .search: return "magnifyingglass"
case .profile: return "person"
}
}
}
// MARK: - NavigationControllerView
struct NavigationControllerView: UIViewControllerRepresentable {
var rootViewController: UIViewController
func makeUIViewController(context: Context) -> UINavigationController {
let navigationController = UINavigationController(rootViewController: rootViewController)
return navigationController
}
func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
}
// MARK: - TabBarRouterViewModel
class TabBarRouterViewModel: ObservableObject {
@Published var currentTab: TabBarItem = .home
@Published var cachedViews: [TabBarItem: AnyView] = [:]
let tabs: [TabBarItem] = TabBarItem.allCases
func switchTab(to tab: TabBarItem) {
currentTab = tab
}
func createView(for tab: TabBarItem) -> AnyView {
if let cachedView = cachedViews[tab] {
return cachedView
}
let rootViewController: UIViewController
switch tab {
case .home:
rootViewController = UIHostingController(rootView: Text("Home View"))
case .search:
rootViewController = UIHostingController(rootView: Text("Search View"))
case .profile:
rootViewController = UIHostingController(rootView: Text("Profile View"))
}
let navigationView = NavigationControllerView(rootViewController: rootViewController)
let anyView = AnyView(navigationView)
cachedViews[tab] = anyView
return anyView
}
}
// MARK: - CustomTabBarView (unchanged)
struct CustomTabBarView: View {
let tabs: [TabBarItem]
@Binding var selectedTab: TabBarItem
let onTap: (TabBarItem) -> Void
var body: some View {
HStack {
ForEach(tabs) { tab in
Spacer()
VStack {
Image(systemName: tab.icon)
.font(.system(size: 24))
Text(tab.title)
.font(.caption)
}
.foregroundColor(selectedTab == tab ? .blue : .gray)
.onTapGesture {
onTap(tab)
}
Spacer()
}
}
.frame(height: 60)
.background(Color.white)
.shadow(radius: 2)
}
}
// MARK: - TabBarRouterView
struct TabBarRouterView: View {
@StateObject private var viewModel = TabBarRouterViewModel()
var body: some View {
VStack(spacing: .zero) {
contentView
CustomTabBarView(
tabs: viewModel.tabs,
selectedTab: $viewModel.currentTab,
onTap: viewModel.switchTab
)
}
.edgesIgnoringSafeArea(.bottom)
}
private var contentView: some View {
ZStack {
ForEach(viewModel.tabs) { tab in
viewModel.createView(for: tab)
.opacity(viewModel.currentTab == tab ? 1.0 : 0.0)
}
}
}
}
Does anyone know if any Apple Open Source repository would contain the source code to NSStringFromSelector? TSAN has pointed out an issue in my code that stems from assuming that the value returned by NSStringFromSelector is immutable, and that the function itself is re-entrant. I’d like to check both those assumptions against the actual sources... assuming they haven't changed in macOS Sequoia to begin with.
I'm investigating an odd problem that surfaced with macOS Sequoia related to CoreGraphics (CGColorSpaceCreateWithICCData()).
I couldn't find a reliable way to track the lifetime (retain/releases) of a CGColorSpaceRef (any pointers appreciated) so I was hoping to use objc_setAssociatedObject() to attach an instance of my own class that would be deallocated when the "owning" CGColorSpaceRef is deallocated. In this way I could set a breakpoint on my own code, presumably invoked when the CGColorSpaceRef is itself going away.
While objc_setAssociatedObject() does seem to work, the results don't seem deterministic. Is it because objc_setAssociatedObject() simply won't work reliably with CF types?
I have existing code in production that links against the mach-o library, and uses the following code:
NSData *data = [NSData dataWithBytes: getsectiondata(&_mh_execute_header, "__TEXT", "__somePlist_plist", &len) length:len];
In order for this to compile with Sequoia Beta 4 and Xcode 16 beta 4, I have to replace _mh_execute_header with _mh_dylib_header.
If I don't, the compiler raises the following error:
ld: Undefined symbols:
__mh_execute_header, referenced from:
-[MyClass init] in MyClass.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Any idea why the linking behavior might have changed? Should I file a bug?
(I realize this is a C issue, not Objective-C - but didn't find a tag for that)
Thanks!
I think I found a bug in the Objective-C++ compiler, linker, or runtime. Here’s the scenario:
We have a macOS app written in Swift.
To control hardware from a 3rd party manufacturer, we use a couple SDKs provided by the manufacturer.
The SDKs use dynamically loaded libraries and the interface is defined in C++ headers.
To bridge between our Swift code and the C++ APIs we have a private Cocoapod that wraps the 3rd party interface with Objective-C++ classes.
The two SDKs each provide an interface for discovering attached devices using a callback class that the programmer provides. By accident we named both callback implementations DiscoveryCallback, but this was not a compiler error because neither class was publicly declared, and each was defined in the .mm file where it was used.
However, the problem we’re seeing is this:
We want to discover Videohub devices, so we register a new instance of DiscoveryCallback (defined in the same .mm file as this code) with the Videohub SDK.
A Videohub device is connected and the SDK calls a method on our callback.
Surprise! The callback we registered in step 1 was actually the one intended for Decklink devices, defined in a completely different .mm file.
This violates all sorts of assumptions and our app quickly crashes.
The funny thing is, the two implementations of DiscoveryCallback have completely different method names. The Videohub SDK is supposed to be calling NewVideohubDevice, yet somehow it successfully calls DeckLinkDeviceArrived on an instance of a class it shouldn’t even know about.
So the compiler has checked that our intended DiscoveryCallback matches the protocol that the SDK expects, but at runtime the compiled code instantiates a completely different implementation of DiscoveryCallback and somehow doesn’t immediately fail; we still call a method on it that doesn’t even share a name with the intended target. I imagine at this point the method names are long forgotten and are just pointers in a table.
I don’t know if this is a bug in the compiler, the Objective-C++ runtime, or if this is just “working as designed” undefined behavior that I should have avoided by not giving two private classes the same name. I know it’s possible to use a private API simply by redeclaring it in my own code, and this seems related to that, but I feel like the compiler or linker should have warned me that I had two implementations of the same class, or if that is not an error, then the runtime should have instantiated the class that was privately defined in the same source file where it was used.
Obviously I can’t share our entire project; I’d like to provide some sample code that replicates the issue, but I don’t have time to do that right now. I’m posting this to see if other developers have had a similar experience.
I have created an app for iOS using React Native. I've gotten the app to a point where it works on the iPhone simulator via the Expo App. It even works when creating a build of the app to distribute using TestFlight. Now, I want to add Google Ads into the app. However, I've learned that Google Ads won't work via an Expo build. Instead one has to create a development build to test the ads in the app and see how they look.
I've also finally been able to compile a successful development build using eas (expo application services). When I install the app on the simulator and try to open it however, the app crashes almost immediately and I don't know why. I have tried deciphering the symbolicated crash report, but I have not been able to figure out what could be causing the error. It looks like it has something to do with the user interface.
Below is the thread where the app crashes:
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x11324a14a __pthread_kill + 10
1 libsystem_pthread.dylib 0x1132abebd pthread_kill + 262
2 libsystem_c.dylib 0x7ff80016dd1c abort + 133
3 libc++abi.dylib 0x7ff8002c6d12 abort_message + 241
4 libc++abi.dylib 0x7ff8002b951a demangling_terminate_handler() + 266
5 libobjc.A.dylib 0x7ff800061fba _objc_terminate() + 96
6 libc++abi.dylib 0x7ff8002c616b std::__terminate(void (*)()) + 6
7 libc++abi.dylib 0x7ff8002c6126 std::terminate() + 54
8 libdispatch.dylib 0x7ff8001796ec _dispatch_client_callout + 28
9 libdispatch.dylib 0x7ff80017d1e2 _dispatch_block_invoke_direct + 508
10 FrontBoardServices 0x7ff807a8b3a7 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
11 FrontBoardServices 0x7ff807a8b281 -[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 188
12 FrontBoardServices 0x7ff807a8b3cf -[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 19
13 CoreFoundation 0x7ff800429ff3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
14 CoreFoundation 0x7ff800429f35 __CFRunLoopDoSource0 + 157
15 CoreFoundation 0x7ff800429732 __CFRunLoopDoSources0 + 215
16 CoreFoundation 0x7ff800423e67 __CFRunLoopRun + 919
17 CoreFoundation 0x7ff8004236ed CFRunLoopRunSpecific + 557
18 GraphicsServices 0x7ff8103ba08f GSEventRunModal + 137
19 UIKitCore 0x7ff805cdf6ee -[UIApplication _run] + 972
20 UIKitCore 0x7ff805ce416e UIApplicationMain + 123
21 LeftOff 0x10f870380 main + 96
22 dyld_sim 0x112d3a3e0 start_sim + 10
23 dyld 0x113d57366 start + 1942
I have been trying to solve this for some days now and could really use some help. I have tried changing versions of dependencies in my app too, with a focus on those that manage the UI. For example, I have changed packages such as react-native-ranimated, react-navigation/stack, react-native-gesture-handler, and react-native-screens to name a few. Nothing has worked so far. Please help.
if we define a property in the following way:
@property (atomic) NSString *latestObject;
Can we assume that the read write to that value is thread safe?
i.e the value will be correct.
Or it is better to write our own setter/getter with Locks?
I have a public swift function with the below declaration :
public func InternalMain (_ pNumOfArgs : Int32, _ pCmdlineArgs : UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>) -> Int32 {..}
I need this function as public because I need to invoke in from a different library. But the above declaration produces an error in my generated swift header i.e '-swift.h' file because 'UnsafeMutablePointer<UnsafeMutablePointer?>' type cannot be represented in the swift generated header.
Can someone help how do I get past this. This is a class independent function and I tried using the '@nonobj' to prevent this from getting in the generated header but it still gives an error.
In swift if using custom dateFormat like "dd-mm-yyyy" and device follows japanese calendar now get dateForm dateFormatter , expected "30-05-Reiwa6". but dateFormatter return string is "30=05-0006"
DatePicker always get timeFormat from device setting, but i need to show time in datePicker based on My app setting not device setting. any solution for this problem
I tried to set locale "us_POSIX" locale for 12 hour and "us_GB" for 24 hour format this way is work in gregorian calendar , but in japanese calendar not showing year properly like (picker showing " 6 " instead of " Reiwa 6 " )
I used a custom time format in the DateTimePicker, such as 'hh:mm a' for 12-hour format. Although the device's time format is set to 24-hour mode, my sample app displays time in 24-hour format like '23:10' instead of the desired 12-hour format like '11:10 PM'.
I've already set the locale for the 12-hour format. Has anyone else encountered this issue, and what could be the solution?
Hi. We have weird trouble related to the multi-threading.
Does anyone have ideas how to resolve or avoid?
Sample Code
// sample.hpp
class Sample {
public:
Sample();
~Sample();
void Init();
void Dealloc();
void OnEvent();
private:
std::mutex sample_mutex_;
int counter = 1;
}
// sample.cpp
#include "sample.hpp"
Sample::Sample() {}
Sample::~Sample() {}
void Sample::Init() {
std::async([]() {
std::this_thread::sleep_for(std::chrono::seconds(2));
this->OnEvent();
});
}
void Sample::Dealloc() {
std::lock_guard<std::mutex> lock(sample_mutex_);
counter = 0;
}
void Sample::OnEvent {
// called from another thread
std::lock_guard<std::mutex> lock(sample_mutex_);
counter += 1;
}
// obj_sample.h
@interface ObjSample : NSObject
- (id _Nonnull)init;
@property(nonatomic, readonly) std::shared_ptr<Sample> sample;
@end
// obj_sample.mm
@implementation ObjSample
- (id _Nonnull)init{
if (self = [super init]) {
_sample = std::make_shared<Sample>();
_sample->Init();
}
return self;
}
- (void)dealloc {
sample->Dealloc();
}
@end
What happens
the deadlock happens.
according to the debug navigator with the Xcode, we figured out 2 facts below.
OnEvent does not end although it looks completed.
void Sample::OnEvent {
// called from another thread
std::lock_guard<std::mutex> lock(sample_mutex_);
counter += 1;
} // <= Thread 35: stop here
Sample::Dealloc is run on the same thread of OnEvent.
// debug navigator
Thread 35
2 Sample::Dealloc <- this is weird.
3 Sample::OnEvent
We guess they causes the deadlock.
probability
less than 10%
Environment
MacOS: 14.3.1(Apple M1)
Xcode: 15.3
iOS Simulator: 17.0.1
Intermittent Failures Occur During macOS Build Execution on Bamboo. Below is an Extract from the Failure Logs.
Note: Please note that within our larger Bamboo build environment, several Xcode projects are constructed. Failures occur intermittently across various Xcode projects each time the Bamboo build is initiated. Therefore, these failures are not specific to any particular Xcode project. It's important to emphasize that the Xcode project mentioned, "myProject.xcodeproj," is used purely as a placeholder or example in this context.
which 'xcodebuild' VALID_ARCHS="x86_64 arm64" ARCHS="x86_64" -project “”myProject.xcodeproj"" -alltargets -configuration "Release" -UseModernBuildSystem=NO
build 08-Feb-2024 09:53:00 Command line invocation:
build 08-Feb-2024 09:53:00 /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild "VALID_ARCHS=x86_64 arm64" ARCHS=x86_64 -project myProject.xcodeproj -alltargets -configuration Release -UseModernBuildSystem=NO
build 08-Feb-2024 09:53:00
build 08-Feb-2024 09:53:00 User defaults from command line:
build 08-Feb-2024 09:53:00 IDEPackageSupportUseBuiltinSCM = YES
build 08-Feb-2024 09:53:00 UseModernBuildSystem = NO
build 08-Feb-2024 09:53:00
build 08-Feb-2024 09:53:00 Build settings from command line:
build 08-Feb-2024 09:53:00 ARCHS = x86_64
build 08-Feb-2024 09:53:00 VALID_ARCHS = x86_64 arm64
build 08-Feb-2024 09:53:00
error 08-Feb-2024 09:53:01 objc[39076]: thread is already initializing this class!
error 08-Feb-2024 09:53:01 make[6]: *** [compile] Abort trap: 6
I'm working on an FFI for working with ObjectiveC/Foundation/Metal. AFAIU, as many APIs create and autorelease objects, I need to ensure that an NSAutoreleasePool is active when calling into these APIs. So I've created a wrapper that basically mimics @autoreleasepool by creating and initializing an NSAutoreleasePool, running some code, and then draining the pool. So far so good; I'm using this functionality around most of my entry points into the ObjectiveC world.
There's two issues I don't understand though. The first is that NSAutoreleasePool initialization seems to require an active autorelease pool, which seems like a chicken-and-egg problem. Running with OBJC_DEBUG_MISSING_POOLS=YES and breaking on objc_autoreleaseNoPool, I see:
objc[30336]: MISSING POOLS: (0x1e2e89c40) Object 0x6000007e0050 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
(lldb) bt
objc_autoreleaseNoPool at /usr/lib/libobjc.A.dylib (unknown line)
_ZN19AutoreleasePoolPage17autoreleaseNoPageEP11objc_object at /usr/lib/libobjc.A.dylib (unknown line)
_ZN19AutoreleasePoolPage4pushEv at /usr/lib/libobjc.A.dylib (unknown line)
_CFAutoreleasePoolPush at /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (unknown line)
-[NSAutoreleasePool init] at /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (unknown line)
macro expansion at /Users/tim/Julia/pkg/ObjectiveC/src/syntax.jl:163 [inlined]
NSAutoreleasePool at /Users/tim/Julia/pkg/ObjectiveC/src/foundation.jl:427
The second, related problem is that some APIs that are called by Metal from a background thread I don't control:
(lldb) bt
* thread #11, queue = 'com.Metal.CompletionQueueDispatch', stop reason = breakpoint 1.1
* frame #0: 0x000000018c21b9e8 libobjc.A.dylib`objc_autoreleaseNoPool
frame #1: 0x000000018c1eb99c libobjc.A.dylib`AutoreleasePoolPage::autoreleaseNoPage(objc_object*) + 252
frame #2: 0x000000018c21c9ec libobjc.A.dylib`AutoreleasePoolPage::push() + 76
frame #3: 0x00000001aaef9694 IOGPU`-[IOGPUMetalBuffer dealloc] + 104
frame #4: 0x00000001f83554e4 AGXMetalG15X_B0`-[AGXBuffer dealloc] + 44
frame #5: 0x00000001f837eb98 AGXMetalG15X_B0`-[AGXG15XFamilyBuffer dealloc] + 76
frame #6: 0x000000019687c1c4 Metal`MTLResourceListChunkFreeEntries(MTLResourceListChunk*) + 64
frame #7: 0x000000019674e2b0 Metal`-[MTLResourceList releaseAllObjectsAndReset] + 72
frame #8: 0x00000001aaefbd10 IOGPU`IOGPUMetalCommandBufferStorageReset + 36
frame #9: 0x00000001aaefbcac IOGPU`IOGPUMetalCommandBufferStorageDealloc + 76
frame #10: 0x00000001aaefa130 IOGPU`-[IOGPUMetalCommandBuffer didCompleteWithStartTime:endTime:error:] + 240
frame #11: 0x000000019674dce4 Metal`-[_MTLCommandQueue commandBufferDidComplete:startTime:completionTime:error:] + 108
frame #12: 0x00000001aaf03b54 IOGPU`IOGPUNotificationQueueDispatchAvailableCompletionNotifications + 128
frame #13: 0x00000001aaf03c60 IOGPU`__IOGPUNotificationQueueSetDispatchQueue_block_invoke + 64
frame #14: 0x000000018c4049d0 libdispatch.dylib`_dispatch_client_callout4 + 20
frame #15: 0x000000018c420c5c libdispatch.dylib`_dispatch_mach_msg_invoke + 468
frame #16: 0x000000018c40bd28 libdispatch.dylib`_dispatch_lane_serial_drain + 368
frame #17: 0x000000018c421998 libdispatch.dylib`_dispatch_mach_invoke + 444
frame #18: 0x000000018c40bd28 libdispatch.dylib`_dispatch_lane_serial_drain + 368
frame #19: 0x000000018c40ca08 libdispatch.dylib`_dispatch_lane_invoke + 432
frame #20: 0x000000018c40bd28 libdispatch.dylib`_dispatch_lane_serial_drain + 368
frame #21: 0x000000018c40c9d4 libdispatch.dylib`_dispatch_lane_invoke + 380
frame #22: 0x000000018c41761c libdispatch.dylib`_dispatch_root_queue_drain_deferred_wlh + 288
frame #23: 0x000000018c416e90 libdispatch.dylib`_dispatch_workloop_worker_thread + 404
frame #24: 0x000000018c5b2114 libsystem_pthread.dylib`_pthread_wqthread + 288
(lldb) c
Process 26902 resuming
objc[26902]: MISSING POOLS: (0x1e2e89c40) Object 0x14c8a2400 of class AGXG15SDevice autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Again, I'm not sure how I'm supposed to run this under an autorelease pool.