Ping without CFSockets

All of our uses of CFSockets have started causing crashes in iOS 16. They seem to be deprecated so we are trying to transition over to using the Network framework and NWConnection to try to fix the crashes.

One of our uses of them is to ping a device on the local network to make sure it is there and online and provide a heartbeat status in logs as well as put the application into a disabled state if it is not available as it is critical to the functionality of the app. I know it is discouraged to disable any functionality based on the reachability of a resource but this is in an enterprise environment where the reachability of this device is mission critical.

I've seen other people ask about the ability to ping with the Network framework and the answers I've found have said that this is not possible and pointed people to the SimplePing sample code but it turns out our existing ping code is already using this technique and it is crashing just like our other CFSocket usages, inside CFSocketInvalidate with the error BUG IN CLIENT OF LIBPLATFORM: Trying to recursively lock an os_unfair_lock.

Is there any updated way to perform a ping without using the CFSocket APIs that now seem to be broken/unsupported on iOS 16?

They seem to be deprecated so we are trying to transition over to using the Network framework and NWConnection

Moving to Network framework is a good thing. CFSocket, despite the name, was never a good fit for networking.

Sadly, Network framework does not have a high-level ping API. If you’d like to see that added to the wish list, file an enhancement request along those lines. Please post your bug number, just for the record.

That means that you will have to write your own code for ping. When I wrote SimplePing, way back in the day, CFSocket was the best way to use a socket asynchronously. That’s not been the case for a while. If I were writing it again today, I’d use a Dispatch event source.

Having said that, CFSocket should still work and I’m surprised you’re seeing this:

it turns out our existing ping code is already using this technique and it is crashing … inside CFSocketInvalidate with the error BUG IN CLIENT OF LIBPLATFORM: Trying to recursively lock an os_unfair_lock.

Please post a crash report for that. See Posting a Crash Report for advice on how to do that.


Just as a data point I downloaded SimplePing and ran the MacTool target and it works just fine on my machine. The tool never calls CFSocketInvalidate though, so I then tweaked it to stop pinging after the fifth ping by adding this code to the end of -simplePing:didReceivePingResponsePacket:sequenceNumber::

if (sequenceNumber >= 4) {
[self.pinger stop];
self.pinger = nil;
[self.sendTimer invalidate];
self.sendTimer = nil;
}

I confirmed that does cause it to call CFSocketInvalidate and that doesn’t crash. This is on macOS 13.1. So, I’m not sure why you’re seeing crashers but AFAICT CFSocketInvalidate is fundamentally broken.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Okay, I submitted an enhancement request to provide a high-level ping API: FB11989640

AFAICT CFSocketInvalidate is fundamentally broken.

I'm guessing from context (since you are saying that it should work and did not crash for you) that you mean "is NOT fundamentally broken"?

The crash is not something that happens with every use of the API. I do not understand the rhyme or reason behind it. I have been able to reproduce it but not in any reliable or consistent way, I just run through the code that uses it over and over again and sometimes it will crash.

To give you a better picture of the crash, this is an enterprise kiosk application running in stores for customers to use and is running on ~5600 iPads, of which ~2000 are on iOS 16. We are seeing over 200 crashes per day from this same CFSocket stack trace inside CFSocketInvalidate. It is crashing ONLY on the iOS 16 iPads. There have been 0 instances of this crash on the other iPads that are mostly on iOS 15 with a few on iOS 14 and iOS 13. The crashes are split between our 3 different usages of CFSockets. The one that is the focus of this post is the SimplePing usage. We also use CFSockets to do socket communication with a card reader device and we are transitioning this use case to use NWConnection instead. The final usage is inside of GCDAsyncSocket inside a logging library which gets used for some logging to Splunk, we have not identified how we will replace that one yet. I only list these other usages in case their presence somehow informs the issue but I will restate that this code with all 3 of these usages does not crash prior to iOS 16 and we have been using them years.

I have attached a crash report from one of the crashes using SimplePing.

Incident Identifier: 3B952427-44F6-4E5B-97F3-18D3E07FB9F3
CrashReporter Key:   69b3ccbf383e4b4ba559bf22f34a3a7f99a22c96
Hardware Model:      iPad12,1
Process:             KioskQARC [1249]
Path:                /private/var/containers/Bundle/Application/C537080F-442E-472E-889F-38DC4EDF0147/KioskQARC.app/KioskQARC
Identifier:          com.fakename.kiosk-omni
Version:             7.20.0 (6)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.fakename.kiosk-omni [693]

Date/Time:           2023-02-13 08:44:14.0357 -0700
Launch Time:         2023-02-13 08:43:31.5710 -0700
OS Version:          iPhone OS 16.3 (20D47)
Release Type:        User
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001d52ec08c
Termination Reason: ****** 5 Trace/BPT trap: 5
Terminating Process: exc handler [1249]

Triggered by Thread:  0

Application Specific Information:
BUG IN CLIENT OF LIBPLATFORM: Trying to recursively lock an os_unfair_lock
Abort Cause 259


Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_platform.dylib      	       0x1d52ec08c _os_unfair_lock_recursive_abort + 36
1   libsystem_platform.dylib      	       0x1d52e6898 _os_unfair_lock_lock_slow + 280
2   CoreFoundation                	       0x187b41090 CFSocketInvalidate + 132
3   CFNetwork                     	       0x188d6c964 0x188c04000 + 1476964
4   CoreFoundation                	       0x187a86c20 CFArrayApplyFunction + 72
5   CFNetwork                     	       0x188d4a480 0x188c04000 + 1336448
6   CoreFoundation                	       0x187aee9e4 _CFRelease + 316
7   CoreFoundation                	       0x187b413c8 CFSocketInvalidate + 956
8   PlainPing                     	       0x1039eb4a0 -[SimplePing stopSocket] + 56
9   PlainPing                     	       0x1039eb4ec -[SimplePing stop] + 44
10  PlainPing                     	       0x1039ed0e4 SimplePingAdapter.stopPinging() + 92
11  PlainPing                     	       0x1039ed5e8 SimplePingAdapter.timeout() + 1008
12  PlainPing                     	       0x1039ed850 @objc SimplePingAdapter.timeout() + 36
13  Foundation                    	       0x181ed9308 __NSFireTimer + 96
14  CoreFoundation                	       0x187b3e32c __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 32
15  CoreFoundation                	       0x187afa9a8 __CFRunLoopDoTimer + 940
16  CoreFoundation                	       0x187a9e548 __CFRunLoopDoTimers + 288
17  CoreFoundation                	       0x187aebfa0 __CFRunLoopRun + 1896
18  CoreFoundation                	       0x187af0eb0 CFRunLoopRunSpecific + 612
19  GraphicsServices              	       0x1c1438368 GSEventRunModal + 164
20  UIKitCore                     	       0x189fe6668 -[UIApplication _run] + 888
21  UIKitCore                     	       0x189fe62cc UIApplicationMain + 340
22  KioskQARC                     	       0x1005fc364 main + 180
23  dyld                          	       0x1a63dc960 start + 2528

Thread 1:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 2:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 3:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 4 name:  com.apple.uikit.eventfetch-thread
Thread 4:
0   libsystem_kernel.dylib        	       0x1c4cdada8 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1c4ceda1c mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1c4cedc5c mach_msg_overwrite + 388
3   libsystem_kernel.dylib        	       0x1c4cdb2ec mach_msg + 24
4   CoreFoundation                	       0x187aeaac4 __CFRunLoopServiceMachPort + 160
5   CoreFoundation                	       0x187aebd08 __CFRunLoopRun + 1232
6   CoreFoundation                	       0x187af0eb0 CFRunLoopRunSpecific + 612
7   Foundation                    	       0x181e98054 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
8   Foundation                    	       0x181e97f3c -[NSRunLoop(NSRunLoop) runUntilDate:] + 64
9   UIKitCore                     	       0x18a11b6a4 -[UIEventFetcher threadMain] + 436
10  Foundation                    	       0x181eb1518 __NSThread__start__ + 716
11  libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
12  libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 5:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 6 name:   Dispatch queue: com.apple.root.default-qos
Thread 6:
0   libsystem_kernel.dylib        	       0x1c4ce07cc __connect + 8
1   CocoaAsyncSocket              	       0x102ecbabc __53-[GCDAsyncSocket connectWithAddress4:address6:error:]_block_invoke + 104
2   libdispatch.dylib             	       0x18f08f460 _dispatch_call_block_and_release + 32
3   libdispatch.dylib             	       0x18f090f88 _dispatch_client_callout + 20
4   libdispatch.dylib             	       0x18f094074 _dispatch_queue_override_invoke + 788
5   libdispatch.dylib             	       0x18f0a2a6c _dispatch_root_queue_drain + 396
6   libdispatch.dylib             	       0x18f0a3284 _dispatch_worker_thread2 + 164
7   libsystem_pthread.dylib       	       0x1d537cdbc _pthread_wqthread + 228
8   libsystem_pthread.dylib       	       0x1d537cb98 start_wqthread + 8

Thread 7 name:  com.google.firebase.crashlytics.MachExceptionServer
Thread 7:
0   libsystem_kernel.dylib        	       0x1c4cdada8 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1c4ceda1c mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1c4cedc5c mach_msg_overwrite + 388
3   libsystem_kernel.dylib        	       0x1c4cdb2ec mach_msg + 24
4   FirebaseCrashlytics           	       0x1032162bc FIRCLSMachExceptionReadMessage + 80
5   FirebaseCrashlytics           	       0x1032161f4 FIRCLSMachExceptionServer + 52
6   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
7   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 8:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x1010fb4b8 AdobeMarketingMobile::(anonymous namespace)::NativeNetworkService::ConnectUrl(std::__1::basic_string, std::__1::allocator > const&, AdobeMarketingMobile::HttpCommandType const&, std::__1::basic_string, std::__1::allocator > const&, std::__1::map, std::__1::allocator >, std::__1::basic_string, std::__1::allocator >, std::__1::less, std::__1::allocator > >, std::__1::allocator, std::__1::allocator > const, std::__1::basic_string, std::__1::allocator > > > > const&, std::__1::chrono::duration >, std::__1::chrono::duration >) + 504
5   KioskQARC                     	       0x1010c6038 AdobeMarketingMobile::AnalyticsHitDatabase::SendAnalyticsHitToServer(std::__1::basic_string, std::__1::allocator > const&, std::__1::basic_string, std::__1::allocator > const&) + 276
6   KioskQARC                     	       0x1010c71e8 AdobeMarketingMobile::AnalyticsHitProcessor::Process(std::__1::shared_ptr const&) + 568
7   KioskQARC                     	       0x1010c74bc AdobeMarketingMobile::HitProcessor::ProcessBase(std::__1::shared_ptr const&) + 120
8   KioskQARC                     	       0x10119ef68 std::__1::__function::__func, void ()>::operator()() + 80
9   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
10  KioskQARC                     	       0x10115fa54 AdobeMarketingMobile::(anonymous namespace)::ProxyTaskExecutor::ParentTask(std::__1::shared_ptr const&) + 476
11  KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
12  KioskQARC                     	       0x10115fa54 AdobeMarketingMobile::(anonymous namespace)::ProxyTaskExecutor::ParentTask(std::__1::shared_ptr const&) + 476
13  KioskQARC                     	       0x1010d3a28 std::__1::__function::__func, std::__1::function, std::__1::allocator >, AdobeMarketingMobile::SdkError&)>, std::__1::basic_string, std::__1::allocator > const&)::$_0, std::__1::allocator, std::__1::function, std::__1::allocator >, AdobeMarketingMobile::SdkError&)>, std::__1::basic_string, std::__1::allocator > const&)::$_0>, void ()>::operator()() + 44
14  KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
15  KioskQARC                     	       0x10116705c std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2::operator()() const::'lambda0'(), std::__1::allocator const&, std::__1::shared_ptr const&)::$_2::operator()() const::'lambda0'()>, void ()>::operator()() + 92
16  KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
17  KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
18  KioskQARC                     	       0x101166a64 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 896
19  KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
20  KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
21  KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
22  libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
23  libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 9:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x10116a154 std::__1::__function::__func, void ()>::operator()() + 412
4   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
5   KioskQARC                     	       0x10116705c std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2::operator()() const::'lambda0'(), std::__1::allocator const&, std::__1::shared_ptr const&)::$_2::operator()() const::'lambda0'()>, void ()>::operator()() + 92
6   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
7   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
8   KioskQARC                     	       0x101166a64 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 896
9   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
10  KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
11  KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
12  libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
13  libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 10:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x101166c54 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 1392
5   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
6   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
7   KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 11:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x101166c54 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 1392
5   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
6   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
7   KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 12:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x101166c54 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 1392
5   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
6   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
7   KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 13:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x101166c54 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 1392
5   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
6   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
7   KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 14:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x101166c54 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 1392
5   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
6   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
7   KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 15:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x101166c54 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 1392
5   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
6   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
7   KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 16:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x1010feef8 std::__1::cv_status std::__1::condition_variable::wait_until > >(std::__1::unique_lock&, std::__1::chrono::time_point > > const&) + 200
4   KioskQARC                     	       0x101166c54 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 1392
5   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
6   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
7   KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 17:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129b68 std::__1::condition_variable::__do_timed_wait(std::__1::unique_lock&, std::__1::chrono::time_point > >) + 100
3   KioskQARC                     	       0x10116a154 std::__1::__function::__func, void ()>::operator()() + 412
4   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
5   KioskQARC                     	       0x10116705c std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2::operator()() const::'lambda0'(), std::__1::allocator const&, std::__1::shared_ptr const&)::$_2::operator()() const::'lambda0'()>, void ()>::operator()() + 92
6   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
7   KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
8   KioskQARC                     	       0x101166a64 std::__1::__function::__func const&, std::__1::shared_ptr const&)::$_2, std::__1::allocator const&, std::__1::shared_ptr const&)::$_2>, void ()>::operator()() + 896
9   KioskQARC                     	       0x101163264 AdobeMarketingMobile::TryCatch(std::__1::function const&, std::__1::function const&) + 44
10  KioskQARC                     	       0x1011631b4 AdobeMarketingMobile::TrySwallow(std::__1::function const&) + 60
11  KioskQARC                     	       0x101166538 void* std::__1::__thread_proxy >, AdobeMarketingMobile::CreateWorkerThread(std::__1::shared_ptr const&)::$_1> >(void*) + 124
12  libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
13  libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 18 name:  ChameleonContext
Thread 18:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129acc std::__1::condition_variable::wait(std::__1::unique_lock&) + 28
3   AWSDK                         	       0x105827664 chameleon::app::EventLoop::run() + 712
4   AWSDK                         	       0x10581f8bc chameleon::app::ChameleonContext::run() + 48
5   AWSDK                         	       0x1057fec30 chameleon::app::ContextThread::run() + 3136
6   AWSDK                         	       0x105801ccc 0x104e10000 + 10427596
7   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
8   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 19 name:  ChameleonEventNotify
Thread 19:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   libc++.1.dylib                	       0x196129acc std::__1::condition_variable::wait(std::__1::unique_lock&) + 28
3   AWSDK                         	       0x1058279e4 chameleon::app::EventLoop::runNotify() + 576
4   AWSDK                         	       0x10582e448 0x104e10000 + 10609736
5   AWSDK                         	       0x10582eabc 0x104e10000 + 10611388
6   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
7   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 20 name:  com.apple.NSURLConnectionLoader
Thread 20:
0   libsystem_kernel.dylib        	       0x1c4cdada8 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1c4ceda1c mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1c4cedc5c mach_msg_overwrite + 388
3   libsystem_kernel.dylib        	       0x1c4cdb2ec mach_msg + 24
4   CoreFoundation                	       0x187aeaac4 __CFRunLoopServiceMachPort + 160
5   CoreFoundation                	       0x187aebd08 __CFRunLoopRun + 1232
6   CoreFoundation                	       0x187af0eb0 CFRunLoopRunSpecific + 612
7   CFNetwork                     	       0x188e5bff0 0x188c04000 + 2457584
8   Foundation                    	       0x181eb1518 __NSThread__start__ + 716
9   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
10  libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 21:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 22:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 23:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 24:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 25 name:  com.apple.CFSocket.private
Thread 25:
0   libsystem_kernel.dylib        	       0x1c4cdb90c __select + 8
1   CoreFoundation                	       0x187b3b694 __CFSocketManager + 636
2   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
3   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 26 name:  JavaScriptCore libpas scavenger
Thread 26:
0   libsystem_kernel.dylib        	       0x1c4cdb67c __psynch_cvwait + 8
1   libsystem_pthread.dylib       	       0x1d538406c _pthread_cond_wait + 1232
2   JavaScriptCore                	       0x19b23f114 scavenger_thread_main + 1364
3   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
4   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 27 name:  WebThread
Thread 27:
0   libsystem_kernel.dylib        	       0x1c4cdada8 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1c4ceda1c mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1c4cedc5c mach_msg_overwrite + 388
3   libsystem_kernel.dylib        	       0x1c4cdb2ec mach_msg + 24
4   CoreFoundation                	       0x187aeaac4 __CFRunLoopServiceMachPort + 160
5   CoreFoundation                	       0x187aebd08 __CFRunLoopRun + 1232
6   CoreFoundation                	       0x187af0eb0 CFRunLoopRunSpecific + 612
7   WebCore                       	       0x198967784 RunWebThread(void*) + 756
8   libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
9   libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8

Thread 28:
0   libsystem_pthread.dylib       	       0x1d537cb90 start_wqthread + 0

Thread 29 name:  GCDAsyncSocket-CFStream
Thread 29:
0   libsystem_kernel.dylib        	       0x1c4cdada8 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1c4ceda1c mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1c4cedc5c mach_msg_overwrite + 388
3   libsystem_kernel.dylib        	       0x1c4cdb2ec mach_msg + 24
4   CoreFoundation                	       0x187aeaac4 __CFRunLoopServiceMachPort + 160
5   CoreFoundation                	       0x187aebd08 __CFRunLoopRun + 1232
6   CoreFoundation                	       0x187af0eb0 CFRunLoopRunSpecific + 612
7   Foundation                    	       0x181e98054 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
8   CocoaAsyncSocket              	       0x102eda7cc +[GCDAsyncSocket cfstreamThread] + 404
9   Foundation                    	       0x181eb1518 __NSThread__start__ + 716
10  libsystem_pthread.dylib       	       0x1d537d6cc _pthread_start + 148
11  libsystem_pthread.dylib       	       0x1d537cba4 thread_start + 8


Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x0000000000000103   x1: 0x0000000000000000   x2: 0x0000000000000103   x3: 0x0000000188d6c940
    x4: 0x0000000000000000   x5: 0x0000000000000000   x6: 0x0000000000000000   x7: 0x0000000000000023
    x8: 0x0000000000000103   x9: 0x00000001ddc80760  x10: 0x0000000600003d8d  x11: 0x000000010a340c38
   x12: 0x0000000500003d8d  x13: 0x0000000000000000  x14: 0x01000001ddc8a691  x15: 0x00000001ddc8a690
   x16: 0x00000001d52e83b0  x17: 0x00000001ddc8b428  x18: 0x0000000000000000  x19: 0x0000000000000103
   x20: 0x00000001de5ed0f0  x21: 0x0000000001000002  x22: 0x0000000000000103  x23: 0x0000000000000000
   x24: 0x0000000000000000  x25: 0x0000000000000103  x26: 0x00000000141300c9  x27: 0x00000002801b8310
   x28: 0x0000000181ed92a8   fp: 0x000000016f81d060   lr: 0x00000001d52e6898
    sp: 0x000000016f81d020   pc: 0x00000001d52ec08c cpsr: 0x60000000
   far: 0x000000018af70188  esr: 0xf2000001 (Breakpoint) brk 1

Binary Images:
       0x1d52e6000 -        0x1d52ecff3 libsystem_platform.dylib arm64e  <669859c4444936399597479b5c013750> /usr/lib/system/libsystem_platform.dylib
       0x187a70000 -        0x187e55fff CoreFoundation arm64e  <42ccfc7bff323d258f01ccb2ad843a8b> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
       0x188c04000 -        0x188fcdfff CFNetwork arm64e  <7f3313c9143533338c82dc961429d0b3> /System/Library/Frameworks/CFNetwork.framework/CFNetwork
       0x1039e4000 -        0x1039f3fff PlainPing arm64  <6399e22c3b8f3132920d23ba0979d3e1> /private/var/containers/Bundle/Application/C537080F-442E-472E-889F-38DC4EDF0147/KioskQARC.app/Frameworks/PlainPing.framework/PlainPing
       0x181e56000 -        0x18279ffff Foundation arm64e   /System/Library/Frameworks/Foundation.framework/Foundation
       0x1c1437000 -        0x1c143ffff GraphicsServices arm64e  <85419099269b336d86b40d52d0ff6923> /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices
       0x189c45000 -        0x18b438fff UIKitCore arm64e   /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore
       0x1005e0000 -        0x10146ffff KioskQARC arm64   /private/var/containers/Bundle/Application/C537080F-442E-472E-889F-38DC4EDF0147/KioskQARC.app/KioskQARC
       0x1a63c7000 -        0x1a644a093 dyld arm64e  <4b042f280d1430eca1de3dbb10866ad7> /usr/lib/dyld
       0x1d537c000 -        0x1d5387fff libsystem_pthread.dylib arm64e  <45ac734e66493ee2a0963fd66441ab78> /usr/lib/system/libsystem_pthread.dylib
       0x1c4cda000 -        0x1c4d11feb libsystem_kernel.dylib arm64e   /usr/lib/system/libsystem_kernel.dylib
       0x102ea8000 -        0x102efffff CocoaAsyncSocket arm64  <3088e79fea4c3be1aa0e04f0a5ca9368> /private/var/containers/Bundle/Application/C537080F-442E-472E-889F-38DC4EDF0147/KioskQARC.app/Frameworks/CocoaAsyncSocket.framework/CocoaAsyncSocket
       0x18f08d000 -        0x18f0d3fff libdispatch.dylib arm64e   /usr/lib/system/libdispatch.dylib
       0x1031f4000 -        0x103247fff FirebaseCrashlytics arm64  <2ff6062ea3c63405bf6dddf3a91e9639> /private/var/containers/Bundle/Application/C537080F-442E-472E-889F-38DC4EDF0147/KioskQARC.app/Frameworks/FirebaseCrashlytics.framework/FirebaseCrashlytics
       0x19611d000 -        0x196183ff3 libc++.1.dylib arm64e   /usr/lib/libc++.1.dylib
       0x104e10000 -        0x105a53fff AWSDK arm64  <5174a8a8c0a5326b9d1e816d9e7c0d79> /private/var/containers/Bundle/Application/C537080F-442E-472E-889F-38DC4EDF0147/KioskQARC.app/Frameworks/AWSDK.framework/AWSDK
       0x19b148000 -        0x19c606fff JavaScriptCore arm64e  <79bfba811c1a3c85887ef90ce431c8ab> /System/Library/Frameworks/JavaScriptCore.framework/JavaScriptCore
       0x197daa000 -        0x19a457fff WebCore arm64e  <52da812407ee3fbe957395ed728b9d20> /System/Library/PrivateFrameworks/WebCore.framework/WebCore

EOF

Also submitted a feedback report for this CFSocket crash: FB11989660

Thanks for the bug reports.

It’s hard to say for sure what’s going on here but I suspect that some other CFSocket or CFSocketStream code in your app is triggering this. I have two suggestions for moving forward here:

  • You could open a DTS tech support incident and I can take a much more detailed look at why your ping code is crashing in this way.

  • You could move your ping code over to a Dispatch source, which will definitely avoid this crash [1].

I’d probably lean towards the second option because the less CFSocket code you have in your app the better, but either one is fine (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Although it might not fix all your crashes. If, as I suspect, the root cause of this issues lies in your other CFSocket or CFSocketStream code, this crash may just move to some other site.

Are there any resources you can point me to for implementing a ping using Dispatch source? All of the stuff I can find online still uses CFSocket and most of it just straight up uses your SimplePing code. I don't know where I would even start so we may end up needing to go the TSI route (thank you for the information about that).

If you look at the SimplePing source you’ll see that it uses BSD Sockets for almost everything. It only uses CFSocket for the run loop integration [1]. So the vast bulk of this code stays the same; you only need to use Dispatch to replace that run loop integration.

And for that you need a Dispatch read source. Pasted in below is a small snippet that shows how you might approach this.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] This was a deliberate design choice. CFSocket does some weird things under the covers and the only thing I trust it to do is run loop integration.


final class SocketMonitor {
init(fd: FileDescriptor, queue: DispatchQueue) throws {
self.queue = queue
self.state = .initialised(fd: try fd.duplicate())
}
deinit {
switch self.state {
case .initialised(fd: let fd): try! fd.close()
case .started(source: _): fatalError()
case .cancelled: break
}
}
let queue: DispatchQueue
private enum State {
case initialised(fd: FileDescriptor)
case started(source: DispatchSourceRead)
case cancelled
}
private var state: State
func start() {
dispatchPrecondition(condition: .onQueue(self.queue))
// Redundant start is not OK, nor is starting after a cancel.
guard case .initialised(let fd) = state else { fatalError() }
let source = DispatchSource.makeReadSource(fileDescriptor: fd.rawValue, queue: self.queue)
self.state = .started(source: source)
source.setEventHandler() {
do {
print("will read")
var buf = [UInt8](repeating: 0, count: 2048)
let bytesRead = try buf.withUnsafeMutableBytes { try fd.read(into: $0) }
print("did read, count: \(bytesRead)")
} catch {
print("did not read, error: \(error)")
}
}
source.setCancelHandler() {
try! fd.close()
}
source.activate()
}
func cancel() {
dispatchPrecondition(condition: .onQueue(self.queue))
// Redundant cancellation is OK.
guard case .started(source: let source) = self.state else { return }
source.cancel()
self.state = .cancelled
}
}

To follow up, we ended up focusing on moving our 2 non-ping CFSocket usages to the Network framework to get that rolled out before we started working on converting the ping code over to a dispatch source.

The interesting thing so far is that fixing those 2 seems to have fixed the ping crash as well. It has been about a week now with the fixes being out in prod and we haven't seen the ping crash once so far.

This leads me to believe that whatever broke it in iOS 16 only breaks it when there are multiple (concurrent?) usages of it throughout the app.

Ping without CFSockets
 
 
Q