Processes & Concurrency

RSS for tag

Discover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.

Concurrency Documentation

Post

Replies

Boosts

Views

Activity

Capturing NSXPCConnectionCodeSigningRequirementFailure in XPC service
I’m working on a launch daemon. I’m in the process of adding setCodeSigningRequirement to both sides of the connection, starting with the XPC service. I’ve already made it so that the service calls setCodeSigningRequirement on a new connection passed to the listener method of NSXPCListenerDelegate. It works and the connection does get invalidated. The launch daemon logs stdout and stderr to a file already. So I figured that if a connection gets invalidated because of a code signing failure, it’d be nice to NSLog this to make it easier for users to debug what’s going on, without forcing them to use Console.app. The docs for setCodeSigningRequirement include an example of how to capture this error on the client side, when the client calls that method. What I cannot figure out is how to capture this error on the side of the XPC service. I could use setInvalidationHandler, but the problem with it is that a connection can be invalidated for a myriad of reasons and the handler doesn’t know what happened. Is there perhaps an equivalent of remoteObjectProxyWithErrorHandler but for the service side of the connection?
4
0
561
Jul ’24
Using cooperative cancellation in `expirationHandler` of `beginBackgroundTask(...)`
Let's say I have a Task that I want to extend into the background with beginBackgroundTask(expirationHandler:). Furthermore, I'd like to leverage cooperative cancelation of subtasks when responding to the expiration handler. Unfortunately, the expirationHandler: closure parameter is not async, so I'm unable to do something like: actor MyTaskManagerOne { var backgroundID = UIBackgroundTaskIdentifier.invalid func start() { Task { let doTheWorkTask = Task { await self.doTheWork() } backgroundID = await UIApplication.shared.beginBackgroundTask { doTheWorkTask.cancel() // next line: compile error, since not an async context await doTheWorkTask.value // ensure work finishes up // next line: generates MainActor compilation warnings despite docs allowing it UIApplication.shared.endBackgroundTask(self.backgroundID) } await doTheWorkTask.value } } func doTheWork() async {} } So instead, I think I have to do something like this. It, however, generates runtime warnings, since I'm not directly calling endBackgroundTask(_:) at the end of the expirationHandler: actor MyTaskManagerTwo { var backgroundID = UIBackgroundTaskIdentifier.invalid func start() { Task { let doTheWorkTask = Task { await self.doTheWork() } backgroundID = await UIApplication.shared.beginBackgroundTask { doTheWorkTask.cancel() // 1. not calling endBackgroundTask here generates runtime warnings } await doTheWorkTask.value // 2. even though endBackgroundTask gets called // here (as long as my cooperative cancellation // implementations abort quickly in `doTheWork()`) await UIApplication.shared.endBackgroundTask(self.backgroundID) } } func doTheWork() async {} } As best I can tell, the MyTaskManagerTwo actor works and does not cause a watchdog termination (as long as cancellation is sufficiently fast). It is, however, producing the following runtime warning: Background task still not ended after expiration handlers were called: <_UIBackgroundTaskInfo: 0x302753840>: taskID = 2, taskName = Called by libswift_Concurrency.dylib, from <redacted>, creationTime = 9674 (elapsed = 28). This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(_:) to avoid this. Is the runtime warning ok to ignore in this case?
3
0
528
Jul ’24
iOS dosen't call didActivateAudioSession
PLATFORM AND VERSION iOS Development environment: Xcode 15.0, macOS 14.4.1, Objective-C Run-time configuration: iOS 17.2.1, DESCRIPTION OF PROBLEM I am developing an application that uses NetworkExtension (VoIP local push function). But iOS sometimes doesn't call didActivateAudioSession after following sequence. Would you tell me why iOS doesn't call didActivateAudioSession ? (I said "sometimes", but once it occurs, it will occur repeatedly) myApp --- CXStartCallAction --->iOS myApp <-- performStartCallAction callback --- iOS myApp --- AVAudioSession setCategory: AVAudioSessionCategoryPlayAndRecord --->iOS myApp --- AVAudioSession setMode: AVAudioSessionModeVoiceChat --->iOS myApp <-- didActivateAudioSession callback ----iOS I suspect that myApp cannot acquire an AVAudioSession if another app is already using AVAudioSession. [QUESTION1] Is my guess correct? Should I consider another cause? [QUESTION2] If my guess is correct, how can I prove if another app is already using an AVAudioSession? This issue is based on a customer complaint, but the customer said they don't use any other apps. Best Regards,
5
0
797
Jun ’24
Assertion failure during deinit due to... DispatchSourceTimer?
I have var idleScanTimer = DispatchSource.makeTimerSource() as a class ivar. When the object is started, I have self.idleScanTimer.schedule(deadline: .now(), repeating: Double(5.0*60)) (and it sets an event handler, that checks some times.) When the object is stopped, it calls self.idleScanTimer.cancel(). At some point, the object containing it is deallocated, and ... sometimes, I think, not always, it crashes: Crashed Thread: 61 Dispatch queue: NEFlow queue [...] Application Specific Information: BUG IN CLIENT OF LIBDISPATCH: Release of an inactive object [...] Thread 61 Crashed:: Dispatch queue: NEFlow queue 0 libdispatch.dylib 0x7ff81c1232cd _dispatch_queue_xref_dispose.cold.2 + 24 1 libdispatch.dylib 0x7ff81c0f84f6 _dispatch_queue_xref_dispose + 55 2 libdispatch.dylib 0x7ff81c0f2dec -[OS_dispatch_source _xref_dispose] + 17 3 com.kithrup.simpleprovider 0x101df5fa7 MyClass.deinit + 87 4 com.kithrup.simpleprovider 0x101dfbdbb MyClass.__deallocating_deinit + 11 5 libswiftCore.dylib 0x7ff829a63460 _swift_release_dealloc + 16 6 com.kithrup.simpleprovider 0x101e122f4 0x101de7000 + 176884 7 libswiftCore.dylib 0x7ff829a63460 _swift_release_dealloc + 16 8 libsystem_blocks.dylib 0x7ff81bfdc654 _Block_release + 130 9 libsystem_blocks.dylib 0x7ff81bfdc654 _Block_release + 130 10 libdispatch.dylib 0x7ff81c0f3317 _dispatch_client_callout + 8 11 libdispatch.dylib 0x7ff81c0f9317 _dispatch_lane_serial_drain + 672 12 libdispatch.dylib 0x7ff81c0f9dfd _dispatch_lane_invoke + 366 13 libdispatch.dylib 0x7ff81c103eee _dispatch_workloop_worker_thread + 753 14 libsystem_pthread.dylib 0x7ff81c2a7fd0 _pthread_wqthread + 326 15 libsystem_pthread.dylib 0x7ff81c2a6f57 start_wqthread + 15 I tried changing it to an optional and having the deinit call .cancel() and set it to nil, but it still crashes. I can't figure out how to get it deallocated in a small, standalone test program.
4
0
735
Jul ’24
How often should getTimeline be called in widgetkit?
Hi, I am implementing a widget where I make some network calls. I have set the timelineprovider to update on end, and I have about an hour of widgetkit entries going for each timeline. I notice that the getTimeline function is called an arbitrary amount of times, usually between 2-5 when my widget fetches new entries for the widget. I was under the impression that it should only call the getTimeline function once, and use the entires for all of my widgets (I 3 widgets in total, two for the lock screen and one for home screen). Am I missing something when it comes to understanding the basic lifecycle? Anyone else having these issues? I am using XCode 15.3 and developing for iOS 17.
1
0
562
Jun ’24
Accessing SafariServices from Sandboxed LaunchAgent
I'm attempting to reload a Safari Content Blocker from within a sandboxed command-line tool configured as a LaunchAgent. However, when I use SFContentBlockerManager to reload the content blocker, I encounter the error SFErrorDomain Code=1: Unavailable error. Is it possible to reload a content blocker from a LaunchAgent? If so, how can it be done? // // main.swift // BlockerUpdater // // Created by Sebastian Livoni on 30/06/2024. // import Foundation import SafariServices // Function to reload content blocker asynchronously func reloadContentBlocker() async { NSLog("Hello, World!") do { try await SFContentBlockerManager.reloadContentBlocker(withIdentifier: "me.livoni.blocker.dns") NSLog("Reload complete") } catch { NSLog("Failed to reload content blocker: \(error.localizedDescription)") } } // Main entry point for async code @main struct BlockerUpdater { static func main() async { await reloadContentBlocker() } }
2
0
511
Jul ’24
Background process for email encryption
Hello! My startup is developing a Desktop application for Windows and macOS for encrypting email in local networks. Email encryption in sending applications is planned to be carried out using the S/MIME protocol. The private key is stored on the user's smartphone (we have a requirement from our customers), and at certain moments we simulate the work of a smart card over the WebSocket protocol. In addition, there are policies requiring constant connection of a smart card. However, unlike Android, the user must manually launch the application each time to sign a letter. Is it possible to make sure that the WebSocket connection does not interrupt in the background? We received many negative reviews from iOS users because of this. Or help us please, what protocol can be used for background emulation of smart card operations?
1
0
396
Jun ’24
macOS应用,沙盒化之后无法启动脚本
我添加了相应服务的xx.plist,并在shell脚本中使用launchctl load -w "$HOME/Library/LaunchAgents/com.xx.xx.plist" launchctl start com.xx.xx.local 启动,脚本名称为local,当我给app加上沙盒功能之后,我使用 let installerPath = bundle.path(forResource: "local.sh", ofType: nil) let task = Process.launchedProcess(launchPath: "/bin/bash", arguments: [installerPath!]) task.waitUntilExit()运行结果,我得到这样 的结果:Load failed: 5: Input/output error Try running launchctl bootstrap as root for richer errors. Unload failed: 5: Input/output error Try running launchctl bootout as root for richer errors. Not privileged to start service.,可以帮助我吗? 我该进行什么操作,才能让我的app正常运行?
0
0
448
Jun ’24
GUI + XPC Service App Architecture Performance
Let's image that someone wants to use a background service to keep track of FSEvents activity, at the file level (a firehose, some might say). I choose this example, to indicate the volume and rate of data transmission in question. I'm not creating a front-end for FSEvents data, but my background service may generate data at a similar pace. The service runs off of user defined document/s that specify the FSEvent background filtering to be applied. Those that match get stored into a database. But filters can match on almost all the data being emitted by FSEvents. The user decides to check on the service's activity and database writes by launching a GUI that sends requests to the background service using XPC. So the GUI can request historic data from a database, but also get a real-time view of what FS events the service is busy filtering. So it's a client-server approach, that's concerned with monitoring an event stream over XPC. I understand XPC is a request/response mechanism, and I might look into using a reverse connection here, but my main concern is one of performance. Is XPC capable of coping with such a high volume of data transmision? Could it cope with 1000s of rows of table data updates per second sent to a GUI frontend? I know there are streaming protocol options that involve a TCP connection, but I really want to stay away from opening sockets.
7
0
637
Jun ’24
BGTaskScheduler on Mac Silicon not scheduling
When I register & schedule a Background Task on an iPad, it runs properly. Running the exact same code on an M1 MacBook Pro, though, never schedules the task. There's no error, just a failure to schedule. After scheduling and calling getPendingTaskRequests, on the iPad you can see that it has a pending task, but not on the Mac. Why would this be? BGTaskScheduler.shared.register(forTaskWithIdentifier: taskIdentifier, using: nil) { [self] task in print("task to run") } do { try BGTaskScheduler.shared.submit(request) BGTaskScheduler.shared.getPendingTaskRequests { [self] tasks in print(tasks.count) //Prints 1 on iPad, prints 0 on Mac } } catch { //Code never comes here. print(error) }
1
0
516
Jun ’24
Open Safari from iOS application
Cannot bring the Safari browser to the foreground from an iOS application while other applications can be opened the same way. STEPS TO REPRODUCE After executing the following code, the browser is not opened: if let url = URL(string: "com-apple-mobilesafari-tab://"), UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url, options: [: ], completionHandler: nil) }
1
0
400
Jun ’24
Crash objc_retain_x0
Attaching several crash traces: 2024-02-29_22-48-33.6864_-0600-3f948243e21b4c68d77a38d9cf1cecfdfe2c1565.crash 2024-03-04_15-00-02.9335_-0600-75000cd5acd63ba1434f2ffb3648b97259dddb88.crash 2024-03-05_08-55-47.2097_-0500-f682b25663107ad46f091d65f402f2be31f3f3c6.crash 2024-03-11_08-09-00.4057_-0400-e37d1a635d51afbb67ac38b42dd79c1718a408e8.crash 2024-03-15_16-20-22.6446_-0600-d4ebccf455e8305038ca564a39a5661a1dce6231.crash The final code: - (NSObject*)objectAtIndex:(NSUInteger)index { if (index < self.count) { return [self.embeddedArray objectAtIndex:index]; } else { [PNDErrorReporting reportError:PNDErrorReasonTypeSafeCollectionCrashPrevented message:@"Error msg"]; return nil; } } We subclass NSMutableArray to prevent potential crashes. but we encounter a new crash in our sdk for one of the clients. Also we noticed the stack trace skipped one of the frames (stack calls) in the crash report, in which cases the stack trace wont be identical to the actual code (beside inline)?
8
0
765
Jun ’24
Best Practice for Scheduling EASession Input and Output Streams
My company builds an application using the External Accessory framework to communicate with our hardware. We have followed the documentation and example here and use the stream delegate pattern for scheduling the handling of the EASession's InputStream and OutputStream: https://developer.apple.com/library/archive/featuredarticles/ExternalAccessoryPT/Articles/Connecting.html Our application works, however we have had some issues that cause us to doubt our implementation of the Stream handling for our EASession. All the examples I can find for how to set up this RunLoop based implementation for managing and using the streams associated with the EASession seem to use RunLoop.current to schedule the InputStream and OutputStream. What is not clear to me is what thread the processing of these streams is actually getting scheduled upon. We have occasionally observed our app "freezing" when our connected accessory disconnects, which makes me worry that we have our Stream processing on the main thread of the application. We want these streams to be processed on a background thread and never cause problems locking up our main thread or UI. How exactly do we achieve this? If we are indeed supposed to only use RunLoop.current, how can we make sure we're opening the EASession and scheduling its streams on a non-main thread? On what thread will we receive EAAccessoryDidConnect and EAAccessoryDidDisconnect notifications? Is it safe to schedule streams using RunLoop.current from that thread? What about when the app returns from the background, how are we meant to reconnect to an accessory that the iOS device is already connected to? Hopefully someone here can help guide us and shed some light on how to achieve our desired behavior here.
12
0
951
May ’24
SIGABRT Signal 6 Abort trap
I got crash report for my mobile application private var _timedEvents: SynchronizedBarrier<[String: TimeInterval]> private var timedEvents: [String: TimeInterval] { get { _timedEvents.value } set { _timedEvents.value { $0 = newValue } } } func time(event: String) { let startTime = Date.now.timeIntervalSince1970 trackingQueue.async { [weak self, startTime, event] in guard let self else { return } var timedEvents = self.timedEvents timedEvents[event] = startTime self.timedEvents = timedEvents } } From the report, the crash is happening at _timedEvents.value { $0 = newValue } struct ReadWriteLock { private let concurentQueue: DispatchQueue init(label: String, qos: DispatchQoS = .utility) { let queue = DispatchQueue(label: label, qos: qos, attributes: .concurrent) self.init(queue: queue) } init(queue: DispatchQueue) { self.concurentQueue = queue } func read<T>(closure: () -> T) -> T { concurentQueue.sync { closure() } } func write<T>(closure: () throws -> T) rethrows -> T { try concurentQueue.sync(flags: .barrier) { try closure() } } } struct SynchronizedBarrier<Value> { private let lock: ReadWriteLock private var _value: Value init(_ value: Value, lock: ReadWriteLock = ReadWriteLock(queue: DispatchQueue(label: "com.example.SynchronizedBarrier", attributes: .concurrent))) { self.lock = lock self._value = value } var value: Value { lock.read { _value } } mutating func value<T>(execute task: (inout Value) throws -> T) rethrows -> T { try lock.write { try task(&_value) } } } What could be the reason for the crash? I have attached the crash report. Masked.crash
4
0
747
Jun ’24
NSarray crashes with different exceptions from the same place
It seems that that all the crashes are coming from the same place BUT the error is slightly different. Attaching the code that responsible for the crash: static NSString * const kDelimiter = @"#$@"; + (PNDArray *)getObjectsFromData:(NSData *)data { NSString *dataStr = [[NSString alloc] initWithData:data encoding:encoding]; dataStr = [dataStr stringByReplacingOccurrencesOfString:@"\\u0000" withString:@""]; NSArray *components = [dataStr componentsSeparatedByString:kDelimiter]; NSMutableArray *result = [NSMutableArray array]; for (NSString *jsonStr in components) { if (jsonStr != nil && jsonStr.length != 0 && ![jsonStr hasPrefix:kBatchUUID]) { [result addObject:jsonStr]; } } return [PNDArray arrayWithArray:result]; } 2024-04-16_17-15-34.1922_-0600-dfa2faecf702f23e3f6558bea986de4f62851761.crash 2024-04-24_04-56-53.4664_-0500-6b125d3d03b7e497b6be339c2abb52f29658824b.crash 2024-04-25_11-13-53.1326_-0700-bfe370be3eae8d65f465eac714905dd3d13aa665.crash 2024-05-03_11-47-36.6085_-0500-2793587e7ed1c02b0e4334bbc3aa0bd7f7a0cf3d.crash 2024-05-05_10-49-40.5969_-0700-4d86636b0877fceb8c0cdb9586ee16dfb0a9c934.crash
15
0
1k
May ’24
Crashes after exceeding limit of 150 wakeups per second over 300 seconds
my macOS process is crashing when i keep my mac sleep for about 1 hour. Under Crash Reports, Console app shows two type of file. .diag type .ips type ips file doesn't shows exact line of crash as you can see below sample. Thread 67 Crashed: 0 libsystem_kernel.dylib 0x19a4aea60 __pthread_kill + 8 1 libsystem_pthread.dylib 0x19a4e6c20 pthread_kill + 288 2 libsystem_c.dylib 0x19a3f3a30 abort + 180 3 libsystem_malloc.dylib 0x19a303dc4 malloc_vreport + 896 4 libsystem_malloc.dylib 0x19a307430 malloc_report + 64 5 libsystem_malloc.dylib 0x19a321494 find_zone_and_free + 528 6 Firewall.so 0x103c8a744 TunnelSendQueue::ResumeSend() + 460 resource.diag file sgowing warning about exceeding limit of 150 wakeups per second over 300 seconds. attached here. reasource_consumptions_W36RNW09G.wakeups_resource_diag.txt is this something macOS stopping app because of some resource consumptions?
2
0
773
Jun ’24