Posts

Post not yet marked as solved
0 Replies
91 Views
This one is sorta behaving similar to the FaceTime / AirDrop issue, but it does depend on order, which makes me wonder if it's a programming choice. Specifically, using FortiNet's VPN client, using IPSec, if I have a TPP installed and then try to connect it, it fails. If, however, I connect and then start the TPP, it succeeds, which at least makes it better than FaceTime and AirDrop. So my question here is... hm, not as well-articulated as I would like. I'm curious if a VPN can check to see if other VPNs are installed and configured, and if so say "nope." Hm, saying that more clearly: I think it's possible for a network extension to check the interface that a packet/flow is going to, and cause a failure of some sort if it's a VPN, correct? Does anyone do that? Or am I seeing lions in the waterhole weeds? I'm also curious if Apple's networking code has issues with multiple VPNs. (Although, I will note, our TPP works just fine with Tailscale, so it's not an inherent conflict. Also Cisco AnyConnect. So maybe it's just IPSec?) ETA: to make it clear, my test case involves using a ****** TPP, where handleNewUDPFlow and handleNewFlow both immediately return false, meaning that the system should behave as if it's not there, and yet... doesn't. I appreciate any comments/assistance/guffaws.
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
12 Replies
306 Views
Even when it is disabled (that is, our app says "don't do anything" and all it does is start logging things). On the mac, when I try to make an outgoing audio-only call (it's a mac mini with no camera), it seems to connect as far as the outside is concerned, but nothing happens -- I get a request on my other devices, with the wrong account, and the mac mini says it's failed while the ipad or iphone keep connected. I am logging everything I can think of in our extensions, and they don't seem to show anything of interest. And I can't figure out what to look for in the entirety of system logs. I do see Messages dropped during live streaming (use log show to see what they were)... but I'm not sure what to look for in the log show. If I try to make a call in, it results in what seems to be an iOS FaceTime bug -- the phone tells me to log into FaceTime. Even though I am logged in.
Posted
by kithrup.
Last updated
.
Post marked as solved
4 Replies
290 Views
I have this code in a network extension: private func pathForToken(token: audit_token_t) -> String? { var tokenCopy = token let bufferSize = UInt32(4096) let bytes = UnsafeMutablePointer<UInt8>.allocate(capacity: Int(bufferSize)) let length = proc_pidpath_audittoken(&tokenCopy, bytes, bufferSize) if length != 0 { return String(cString: bytes).lowercased() } return nil } bytes appears to be leaked -- the call stack is pathForToken(token:) to specialized static UnsafeMutablePointer.allocate(capacity:) Do I need to do something to ensure bytes is released, since it doesn't seem to be happening on its own?
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
6 Replies
371 Views
Two different crash patterns -- one an abort, the other complaining about a lock being corrupt or owning thread having exited. The first one is: Thread 1 Crashed:: Dispatch queue: com.apple.root.default-qos.overcommit 0 libsystem_platform.dylib 0x18fc10244 _os_unfair_lock_corruption_abort + 88 1 libsystem_platform.dylib 0x18fc0b788 _os_unfair_lock_lock_slow + 332 2 libobjc.A.dylib 0x18f820c90 objc_sync_enter + 20 3 com.kithrup.TPProvider 0x100d2eee0 closure #3 in TPProvider.startProxy(options:completionHandler:) + 340 4 com.kithrup.TPProvider 0x100d2d980 thunk for @escaping @callee_guaranteed () -> () + 28 5 libdispatch.dylib 0x18fa31910 _dispatch_client_callout + 20 6 libdispatch.dylib 0x18fa34dc8 _dispatch_continuation_pop + 600 7 libdispatch.dylib 0x18fa48be4 _dispatch_source_latch_and_call + 420 8 libdispatch.dylib 0x18fa477b4 _dispatch_source_invoke + 832 9 libdispatch.dylib 0x18fa431f4 _dispatch_root_queue_drain + 392 10 libdispatch.dylib 0x18fa43a04 _dispatch_worker_thread2 + 156 11 libsystem_pthread.dylib 0x18fbdb0d8 _pthread_wqthread + 228 12 libsystem_pthread.dylib 0x18fbd9e30 start_wqthread + 8 while the other one is: Application Specific Information: BUG IN CLIENT OF LIBPLATFORM: os_unfair_lock is corrupt, or owner thread exited without unlocking Abort Cause 198194 Thread 1 Crashed:: Dispatch queue: com.apple.root.default-qos.overcommit 0 libsystem_platform.dylib 0x18fc10220 _os_unfair_lock_corruption_abort + 52 1 libsystem_platform.dylib 0x18fc0b788 _os_unfair_lock_lock_slow + 332 2 libobjc.A.dylib 0x18f820c90 objc_sync_enter + 20 3 com.kithrup.TPProvider 0x104e86ee0 closure #3 in TPProvider.startProxy(options:completionHandler:) +340 4 com.kithrup.TPProvider 0x104e85980 thunk for @escaping @callee_guaranteed () -> () + 28 5 libdispatch.dylib 0x18fa31910 _dispatch_client_callout + 20 6 libdispatch.dylib 0x18fa34dc8 _dispatch_continuation_pop + 600 7 libdispatch.dylib 0x18fa48be4 _dispatch_source_latch_and_call + 420 8 libdispatch.dylib 0x18fa477b4 _dispatch_source_invoke + 832 9 libdispatch.dylib 0x18fa431f4 _dispatch_root_queue_drain + 392 10 libdispatch.dylib 0x18fa43a04 _dispatch_worker_thread2 + 156 11 libsystem_pthread.dylib 0x18fbdb0d8 _pthread_wqthread + 228 12 libsystem_pthread.dylib 0x18fbd9e30 start_wqthread + 8 Our TPProvider, whenever it uses a dispatch queue, uses a custom one, so these are presumably system queues and locks. My best guess would be some XPC command took too long? But that's just WAG. Any ideas about what is actually going on?
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
1 Replies
291 Views
We added a packet filter to our app, then found a way to not need it, so we want to be able to remove it on upgrades. But we don't want to install it if it's not already installed. Simple, right? The basic flow of the code is, on start-up, it does a propertiesRequestForExtensiion request. The method for the delegate goes through the various versions, ignoring any that are property.isEnabled == NO. When it comes to one that is enabled, it checks the version -- if it's the same version as the running app, it goes to deactivate it. If it's a different version, it goes to enable the current version (creating a activationRequestForExtensiion request). This should all be very simple. Except. At some point during this, the properties request gets a failure -- Domain=OSSystemExtensionErrorDomain Code=1. Ok, it seems there are lots of them laying around (I haven't rebooted in a while), and that method doesn't return once it finds one that is enabled. So maybe it doesn't like that. And then the activation request that was submitted also fails, also with the same error that doesn't explain anything. I thought, ok, maybe they don't like to stop on each other's toes, so let's create a serial dispatch queue, and have all of the system extension requests use that queue. That way, the activation request won't begin until the properties request has finished! Only I did that. And it did get a bit further -- the request method was invoked! Only then I still got messages about the properties and activation requests failing with the same unknown error. So then I looked at console. And sysextd is crashing, every time this happens. And then I dump all of the logs around that time, and look through them, and see... nothing. I had hoped to end this with a description of how I achieved victory, but instead... I'm going to have to reboot and see if that solves the mysterious crashing of sysextd.
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
0 Replies
257 Views
The profiles command shows them, but the Store file/directory is blocked off from access (which, I suppose, kinda makes sense). (We are in the process of getting customers to upgrade the profile, and if I can see whether our profile has an entry, then I can behave differently.)
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
12 Replies
601 Views
I asked a similar question last year, and got no responses. I've written a much simpler (no network extension!) case that seems to demonstrate what I'm confused about. Simple app with an XPC service. I have an ObjectiveC class TestObject which has an NSString* and an NSData* (which I never actually use). I have a protocol defined in Swift: @objc protocol XPCTestServiceProtocol { func logData(entry: TestObject) -> Void func logData(entry: TestObject, completion: ((String) -> Void)) } In the Switt XPC service, the code is: class XPCTestService: NSObject, XPCTestServiceProtocol { var totalBytes = 0 var lastName = "" @objc func logData(entry: TestObject) { totalBytes += (entry.data?.count ?? 0) } @objc func logData(entry: TestObject, completion: ((String) -> Void)) { totalBytes += (entry.data?.count ?? 0) completion("Finished") } I've got this code in the ObjC app: id<XPCTestServiceProtocol> proxy = [self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { self.stopRun = YES; NSLog(@"Proxy got error %@", error); }]; while (self.stopRun == NO) { @synchronized (self) { NSNumber *objNum = [NSNumber numberWithUnsignedLongLong:self.count++]; NSString *objName = [NSString stringWithFormat:@"Object %@", objNum]; TestObject __weak *toWeak = to; #if USE_COMPLETION [proxy logDataWithEntry:to completion:^(NSString *str) { to = nil; }]; #else [proxy logDataWithEntry:to]; #endif } } attached to a start button (and self.stopRun is set by a stop button, this is all super simple). So I run that, start the test, and things start going (122k calls/second it says). According to Activity Monitor, my app is using about 1gbyte after 20 seconds or so. However, if I run it under Instruments' Leaks template... Activity Monitor says it's used only about 60mbytes. (And at the end of the run, Instruments says it's used about 30mbytes.) Now... if I use the completion and a synchronous proxy, then even without Instruments, Activity Monitor says it's 60mbytes or so. Is the memory reported by Activity Monitor real? Or not real?
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
4 Replies
639 Views
Looking at the path name for reasons, and ran into a thing: one of my coworkers was not getting /Applications/Safari.app as expected, but instead got /System/Volumes/Preboot/Cryptexes/App/System/Applications/Safari.app. Which is annoying because I'm actually using spotlight to find the paths for applications, and that one doesn't show up. Has anyone run into this? And know why? (I figure I'll simply remove the prefix if it's there, and that should be fine, but I'm curious why it only seems to happen sometimes.)
Posted
by kithrup.
Last updated
.
Post marked as solved
1 Replies
286 Views
The code I have is if (filterManager.providerConfiguration == nil) { NEFilterProviderConfiguration *providerConfiguration = [[NEFilterProviderConfiguration alloc] init]; providerConfiguration.filterPackets = YES; providerConfiguration.filterPacketProviderBundleIdentifier = filterBundle.bundleIdentifier; filterManager.providerConfiguration = providerConfiguration; NSString *appName = [NSBundle mainBundle].infoDictionary[@"CFBundleName"]; if (appName != nil) { filterManager.localizedDescription = [NSString stringWithFormat:@"%@ (packet filter)", appName]; } } if (filterManager.enabled) { NSLog(@"Packet filter already enabled, not doing so again"); return; } filterManager.enabled = YES; It's claiming the filter is already enabled. But System Settings > Network shows it there, with a yellow dot. My best guess is that it's showing up as already enabled in the preferences, even though it... isn't? I also log a message in the filter's init, and I don't see that showing up. I've got sysdiagnose from it and a working system, and I'm going over soooooooo many log lines. I don't know what might be causing this, however.
Posted
by kithrup.
Last updated
.
Post marked as solved
4 Replies
473 Views
If there's another version of our app on the volume, it'll relocate the installed one there. This is particularly delightful, since nothing will work if it's not in /Applications. We use pkgbuild and productbuild to create the .pkg file.
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
4 Replies
362 Views
Is there a way to find out when the set of keychains changes? ie, when a keychain is added or removed? I searched here and grepped through the headers in Security.framework but nothing leaped out at me -- which could just mean I missed something, as happens frequently. (This is on macOS.)
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
6 Replies
563 Views
I have something that looks like: NavigationStack { List(self.items, id: \.self, selection: self.$selectedItems) { item in NavigationLink { ItemView(item: item) .environment(\.managedObjectContext, self.viewContext) } label: { LabelWithMenuView(object: item) { ptr in self.labelHandler(item: item, newName: ptr) } } } if self.editMode?.wrappedValue == .active { editButtons } else { TextField("Add Item", text: self.$newItem) .onSubmit { self.addItem() self.newItem = "" } .padding() } } #if os(iOS) .toolbar { EditButton() } .onChange(of: self.editMode?.wrappedValue) { old, new in print("editMode \(old) -> \(new)") } #endif With that layout, the edit button doesn't show up at all; if I put it as part of the List, it does show up, but the first click doesn't do anything; after that, it works, but the onChange handler doesn't show it getting changed, and the editButtons don't go away.
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
4 Replies
409 Views
I got tried of the compiler telling me that .onChange(of:) was deprecated, so I thought, find, I'll simply stub it out for the older versions. Only... I can't seem to do that? I can use @available(macOS 14, *) to build for that and later, but is there any way to do the opposite? (I'd hoped there was a #if available support, but there isn't.)
Posted
by kithrup.
Last updated
.
Post not yet marked as solved
1 Replies
466 Views
I've got a core data model, with a name, which I've cleverly called cdName. My view has: @Environment(\.managedObjectContext) private var viewContext @FetchRequest(sortDescriptors: [ SortDescriptor(\Item.cdName), ]) private var items: FetchedResults<Item> and then, later ForEach(self.items, id: \.self) { item in NavigationLink { ItemView(item: item) .environment(\.managedObjectContext, self.viewContext) } label: { LabelWithMenuView(label: item.cdName ?? "<no name>") { ptr in if let newName = ptr { let oldName = item.cdName! item.cdName = newName do { try self.viewContext.save() } catch { print("Could not save rename of \(oldName) to \(newName)") } } (LabelWithMenuView is a view that has an on-hover button which brings up a rename sheet and passes the new name off to the completion handler.) When I do this (macOS)... it does change the name in Core Data, but it doesn't update the view. If I quit&restart my app, it shows up with the new name. What am I doing wrong, please?
Posted
by kithrup.
Last updated
.