[iOS 16 Crash] Crash while getting mach port from CFMessagePortRef

I create a local CFMessagePortRef using CFMessagePortCreateLocal and then use CFMachPortGetPort() to try to get the mach port from it like below:

NSString *portIdentifier = [[groupName stringByAppendingString:@"."] stringByAppendingString:sdkId];

NSString *portName = [[portIdentifier stringByAppendingString:@"."] stringByAppendingString:@"mach.port"];

CFMessagePortContext context = {0,(__bridge void *)self,nil,nil,nil};

self.sendPort = CFMessagePortCreateLocal(kCFAllocatorDefault, (__bridge CFStringRef)portName, &callback, &context, false); CFMachPortGetPort(ms->_port);

It works till iOS 15 but crashes on iOS 16. Can anyone help? I have defined below definition of __CFMessagePort:

struct __CFMessagePort {

    CFRuntimeBase _base;

    CFLock_t _lock;

    CFStringRef _name;

    CFMachPortRef _port;        /* immutable; invalidated */

    CFMutableDictionaryRef _replies;

    int32_t _convCounter;

    int32_t _perPID;            /* zero if not per-pid, else pid */

    CFMachPortRef _replyPort;        /* only used by remote port; immutable once created; invalidated */

    CFRunLoopSourceRef _source;        /* only used by local port; immutable once created; invalidated */

    dispatch_source_t _dispatchSource;  /* only used by local port; invalidated */

    dispatch_queue_t _dispatchQ;    /* only used by local port */

    CFMessagePortInvalidationCallBack _icallout;

    CFMessagePortCallBack _callout;    /* only used by local port; immutable */

    CFMessagePortCallBackEx _calloutEx;    /* only used by local port; immutable */

    CFMessagePortContext _context;    /* not part of remote port; immutable; invalidated */

};

What are you doing with CFMessagePort on iOS? I’m struggling to think of any situation where that’s a good option given iOS’s limitations on IPC.

Regardless, please post a full Apple crash report for this. See Posting a Crash Report for advice on how to do that.

Share and Enjoy

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

Thanks Eskimo for your comment. I am using CFMessagePort as IPC mechanism to share an IOSurface between broadcast extension and the main iOS app. I create CFMessagePort communication channel and get the underlying mach port with CFMachPortGetPort. And then transport ioSurface mach port created using IOSurfaceCreateMachPort from broadcast extension to the main app with mach_msg_send. In the main app I get IOSurface back with IOSurfaceLookupFromMachPort. Now that ioSurface is shared between the main app and broadcast extension our main app can get the frames from IOSurface and encode and upload the frames to the server. We are doing this because we have to use vp8 software encoding and we can't do it in extension's 50mb memory limit. There are other reasons as well for why we can't just upload from the extension itself. This works fine till iOS 15. But crashes on iOS 16 at the point where we get the mach port from CFMessagePort with mach_port_t machPort = CFMachPortGetPort(ms->_port);

I have attached the crash report below.

Incident Identifier: C83F40B2-9B93-42F4-AD0E-8AABD2930533
CrashReporter Key:   29b13a94190858f339ba90d4dc7be6eaf2401029
Hardware Model:      iPhone12,1
Process:             iOS16Bug [16095]
Path:                /private/var/containers/Bundle/Application/FE2289B1-AB74-4DC2-A35A-E49C407735D0/iOS16Bug.app/iOS16Bug
Identifier:          com.pawan.iOS16BugMachPort
Version:             1.0 (1)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.pawan.iOS16BugMachPort [12801]

Date/Time:           2022-09-21 13:09:31.3180 +0400
Launch Time:         2022-09-21 13:09:31.2006 +0400
OS Version:          iPhone OS 16.0 (20A362)
Release Type:        User
Baseband Version:    4.00.00
Report Version:      104

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

Triggered by Thread:  0

Kernel Triage:
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage
VM - pmap_enter retried due to resource shortage


Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   CoreFoundation                	       0x194237730 CFMachPortGetPort + 152
1   iOS16Bug                      	       0x102a7898c -[PortCommunication initWithGroupName:sdkId:] + 468
2   iOS16Bug                      	       0x102a7898c -[PortCommunication initWithGroupName:sdkId:] + 468
3   iOS16Bug                      	       0x102a7a308 @nonobjc PortCommunication.init(groupName:sdkId:) + 80
4   iOS16Bug                      	       0x102a79b70 PortCommunication.__allocating_init(groupName:sdkId:) + 68
5   iOS16Bug                      	       0x102a79644 closure #2 in ContentView.body.getter + 120
6   SwiftUI                       	       0x197bcf288 0x197ae1000 + 975496
7   SwiftUI                       	       0x197b1dcf8 0x197ae1000 + 249080
8   SwiftUI                       	       0x197bcf288 0x197ae1000 + 975496
9   SwiftUI                       	       0x197afd2d8 0x197ae1000 + 115416
10  SwiftUI                       	       0x197ba5898 0x197ae1000 + 805016
11  SwiftUI                       	       0x197b105c4 0x197ae1000 + 193988
12  SwiftUI                       	       0x197b14430 0x197ae1000 + 209968
13  UIKitCore                     	       0x19631ecec -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1980
14  QuartzCore                    	       0x1957fb4e8 CA::Layer::layout_if_needed(CA::Transaction*) + 500
15  QuartzCore                    	       0x19580eb9c CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 148
16  QuartzCore                    	       0x195820098 CA::Context::commit_transaction(CA::Transaction*, double, double*) + 456
17  QuartzCore                    	       0x1958573c4 CA::Transaction::commit() + 652
18  UIKitCore                     	       0x1967ae31c __34-[UIApplication _firstCommitBlock]_block_invoke_2 + 36
19  CoreFoundation                	       0x1941cf924 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 28
20  CoreFoundation                	       0x1942380ac __CFRunLoopDoBlocks + 368
21  CoreFoundation                	       0x194207ecc __CFRunLoopRun + 856
22  CoreFoundation                	       0x19420d1e4 CFRunLoopRunSpecific + 612
23  GraphicsServices              	       0x1cd02d368 GSEventRunModal + 164
24  UIKitCore                     	       0x1966bcd88 -[UIApplication _run] + 888
25  UIKitCore                     	       0x1966bc9ec UIApplicationMain + 340
26  SwiftUI                       	       0x197cbbce8 0x197ae1000 + 1944808
27  SwiftUI                       	       0x197c18c24 0x197ae1000 + 1276964
28  SwiftUI                       	       0x197c01b44 0x197ae1000 + 1182532
29  iOS16Bug                      	       0x102a7ae54 static iOS16BugApp.$main() + 40
30  iOS16Bug                      	       0x102a7aefc main + 12
31  dyld                          	       0x1b2531948 start + 2504

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

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

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

Thread 4:
0   libsystem_pthread.dylib       	       0x1e0ab4b90 start_wqthread + 0

Thread 5 name:  com.apple.uikit.eventfetch-thread
Thread 5:
0   libsystem_kernel.dylib        	       0x1d0877b48 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	       0x1d088a008 mach_msg2_internal + 80
2   libsystem_kernel.dylib        	       0x1d088a248 mach_msg_overwrite + 388
3   libsystem_kernel.dylib        	       0x1d087808c mach_msg + 24
4   CoreFoundation                	       0x194206e00 __CFRunLoopServiceMachPort + 160
5   CoreFoundation                	       0x194208044 __CFRunLoopRun + 1232
6   CoreFoundation                	       0x19420d1e4 CFRunLoopRunSpecific + 612
7   Foundation                    	       0x18e61d818 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212
8   Foundation                    	       0x18e61d700 -[NSRunLoop(NSRunLoop) runUntilDate:] + 64
9   UIKitCore                     	       0x1967f188c -[UIEventFetcher threadMain] + 436
10  Foundation                    	       0x18e636ce8 __NSThread__start__ + 716
11  libsystem_pthread.dylib       	       0x1e0ab56cc _pthread_start + 148
12  libsystem_pthread.dylib       	       0x1e0ab4ba4 thread_start + 8

Thread 6 name:   Dispatch queue: com.apple.root.utility-qos
Thread 6:
0   libswiftCore.dylib            	       0x18e4642a0 swift::Demangle::__runtime::Demangler::demangleType(__swift::__runtime::llvm::StringRef, std::__1::function) + 288
1   libswiftCore.dylib            	       0x18e4642a0 swift::Demangle::__runtime::Demangler::demangleType(__swift::__runtime::llvm::StringRef, std::__1::function) + 288
2   libswiftCore.dylib            	       0x18e4464d4 swift_getTypeByMangledNameImpl(swift::MetadataRequest, __swift::__runtime::llvm::StringRef, void const* const*, std::__1::function const* (unsigned int, unsigned int)>, std::__1::function const* (swift::TargetMetadata const*, unsigned int)>) + 512
3   libswiftCore.dylib            	       0x18e441c58 swift_getTypeByMangledName + 832
4   libswiftCore.dylib            	       0x18e441f68 swift_getTypeByMangledNameInContext + 164
5   AttributeGraph                	       0x1b6b57a8c AG::swift::metadata::mangled_type_name_ref(char const*, bool, AG::swift::metadata::ref_kind*) const + 212
6   AttributeGraph                	       0x1b6b587fc AG::swift::metadata_visitor::visit_field(AG::swift::metadata const*, AG::swift::field_record const&, unsigned long) + 72
7   AttributeGraph                	       0x1b6b570e8 AG::swift::metadata::visit(AG::swift::metadata_visitor&) const + 1016
8   AttributeGraph                	       0x1b6b558e4 AG::LayoutDescriptor::Builder::visit_element(AG::swift::metadata const*, AG::swift::metadata::ref_kind, unsigned long) + 440
9   AttributeGraph                	       0x1b6b58834 AG::swift::metadata_visitor::visit_field(AG::swift::metadata const*, AG::swift::field_record const&, unsigned long) + 128
10  AttributeGraph                	       0x1b6b570e8 AG::swift::metadata::visit(AG::swift::metadata_visitor&) const + 1016
11  AttributeGraph                	       0x1b6b558e4 AG::LayoutDescriptor::Builder::visit_element(AG::swift::metadata const*, AG::swift::metadata::ref_kind, unsigned long) + 440
12  AttributeGraph                	       0x1b6b58834 AG::swift::metadata_visitor::visit_field(AG::swift::metadata const*, AG::swift::field_record const&, unsigned long) + 128
13  AttributeGraph                	       0x1b6b570e8 AG::swift::metadata::visit(AG::swift::metadata_visitor&) const + 1016
14  AttributeGraph                	       0x1b6b558e4 AG::LayoutDescriptor::Builder::visit_element(AG::swift::metadata const*, AG::swift::metadata::ref_kind, unsigned long) + 440
15  AttributeGraph                	       0x1b6b58834 AG::swift::metadata_visitor::visit_field(AG::swift::metadata const*, AG::swift::field_record const&, unsigned long) + 128
16  AttributeGraph                	       0x1b6b570e8 AG::swift::metadata::visit(AG::swift::metadata_visitor&) const + 1016
17  AttributeGraph                	       0x1b6b5755c AG::LayoutDescriptor::make_layout(AG::swift::metadata const*, AGComparisonMode, AG::LayoutDescriptor::HeapMode) + 600
18  AttributeGraph                	       0x1b6b58908 AG::(anonymous namespace)::LayoutCache::drain_queue(void*) + 152
19  libdispatch.dylib             	       0x19b611fdc _dispatch_client_callout + 20
20  libdispatch.dylib             	       0x19b623b8c _dispatch_root_queue_drain + 684
21  libdispatch.dylib             	       0x19b624284 _dispatch_worker_thread2 + 164
22  libsystem_pthread.dylib       	       0x1e0ab4dbc _pthread_wqthread + 228
23  libsystem_pthread.dylib       	       0x1e0ab4b98 start_wqthread + 8

Thread 7:
0   libsystem_pthread.dylib       	       0x1e0ab4b90 start_wqthread + 0


Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x0000000102a78798   x1: 0x00000001907de018   x2: 0x0000000000000103   x3: 0x0000000000000000
    x4: 0x00000001ea368c10   x5: 0x0000000000000000   x6: 0x0000000000000000   x7: 0x0000000000000403
    x8: 0xf900000000000007   x9: 0xf9000fe0d10083ff  x10: 0x007ffffffffffff8  x11: 0x0003000282638f00
   x12: 0x0000000000000000  x13: 0x0000000282638ef0  x14: 0x0100000102a80139  x15: 0x0000000102a80138
   x16: 0x00000fe0d10083f8  x17: 0x00000060d10083f8  x18: 0x0000000000000000  x19: 0x0000000102a78798
   x20: 0x00000001ea37a000  x21: 0x0000000283d0b9e8  x22: 0x0000000000000001  x23: 0x00000001982b5300
   x24: 0x0000000000000002  x25: 0x00000002833309a0  x26: 0x00000001ea441000  x27: 0x0000000283d0b9c0
   x28: 0x00000001eac58780   fp: 0x000000016d387580   lr: 0x214a088102a7898c
    sp: 0x000000016d387570   pc: 0x0000000194237730 cpsr: 0x20000000
   far: 0x00000001eac6a880  esr: 0xf200c472 (Breakpoint) pointer authentication trap DA

Binary Images:
       0x19418c000 -        0x194570fff CoreFoundation arm64e  <42c5c91704473995b50fde4d132c2435> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
       0x102a74000 -        0x102a7bfff iOS16Bug arm64  <2200850b40f03b188541b530eaa8eefd> /private/var/containers/Bundle/Application/FE2289B1-AB74-4DC2-A35A-E49C407735D0/iOS16Bug.app/iOS16Bug
       0x197ae1000 -        0x199329fff SwiftUI arm64e  <122e646e6b173561975fc414c8dae3d3> /System/Library/Frameworks/SwiftUI.framework/SwiftUI
       0x19631a000 -        0x197ae0fff UIKitCore arm64e  <7b942fa4cb7633759972f58c14492fb4> /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore
       0x1957f1000 -        0x195b49fff QuartzCore arm64e   /System/Library/Frameworks/QuartzCore.framework/QuartzCore
       0x1cd02c000 -        0x1cd034fff GraphicsServices arm64e  <03732ba5113235b4b09d8dd49807d246> /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices
       0x1b251c000 -        0x1b259ee4f dyld arm64e  <341bbf646034357e8aa6e1e4b988e03c> /usr/lib/dyld
       0x1e0ab4000 -        0x1e0abffff libsystem_pthread.dylib arm64e   /usr/lib/system/libsystem_pthread.dylib
       0x1d0877000 -        0x1d08adffb libsystem_kernel.dylib arm64e   /usr/lib/system/libsystem_kernel.dylib
       0x18e5dc000 -        0x18ef26fff Foundation arm64e   /System/Library/Frameworks/Foundation.framework/Foundation
       0x18e041000 -        0x18e5a9fff libswiftCore.dylib arm64e   /usr/lib/swift/libswiftCore.dylib
       0x1b6b4e000 -        0x1b6b90fff AttributeGraph arm64e   /System/Library/PrivateFrameworks/AttributeGraph.framework/AttributeGraph
       0x19b60e000 -        0x19b654fff libdispatch.dylib arm64e   /usr/lib/system/libdispatch.dylib

EOF

I am also attaching a minimal sample app files to reproduce the crash:

//
//  PortCommunication.h
//  iOS16Bug
//
//  Created by Pawan Dixit on 14/09/2022.
//

#import 

NS_ASSUME_NONNULL_BEGIN

@interface PortCommunication : NSObject

-(instancetype)initWithGroupName:(NSString *)groupName sdkId:(NSString *)sdkId;

@end

NS_ASSUME_NONNULL_END

//
//  PortCommunication.m
//  iOS16Bug
//
//  Created by Pawan Dixit on 14/09/2022.
//

#import "PortCommunication.h"

typedef pthread_mutex_t CFLock_t;

typedef struct __CFRuntimeBase {
    uintptr_t _cfisa;
    uint8_t _cfinfo[4];
#if __LP64__
    uint32_t _rc;
#endif
} CFRuntimeBase;

typedef CFDataRef (*CFMessagePortCallBackEx)(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info, void *trailer, uintptr_t);

struct __CFMessagePort {
    CFRuntimeBase _base;
    CFLock_t _lock;
    CFStringRef _name;
    CFMachPortRef _port;        /* immutable; invalidated */
    CFMutableDictionaryRef _replies;
    int32_t _convCounter;
    int32_t _perPID;            /* zero if not per-pid, else pid */
    CFMachPortRef _replyPort;        /* only used by remote port; immutable once created; invalidated */
    CFRunLoopSourceRef _source;        /* only used by local port; immutable once created; invalidated */
    dispatch_source_t _dispatchSource;  /* only used by local port; invalidated */
    dispatch_queue_t _dispatchQ;    /* only used by local port */
    CFMessagePortInvalidationCallBack _icallout;
    CFMessagePortCallBack _callout;    /* only used by local port; immutable */
    CFMessagePortCallBackEx _calloutEx;    /* only used by local port; immutable */
    CFMessagePortContext _context;    /* not part of remote port; immutable; invalidated */
};

@interface PortCommunication () {
    dispatch_queue_t machServerQueue;
}
@property(nonatomic, assign) CFMessagePortRef sendPort;
@end

CFDataRef callback(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info)
{
    return NULL;
}

@implementation PortCommunication

-(instancetype)initWithGroupName:(NSString *)groupName sdkId:(NSString *)sdkId {
    self = [super init];
    if (nil != self) {
        
        NSString *portIdentifier = [[groupName stringByAppendingString:@"."] stringByAppendingString:sdkId];
        NSString *portName = [[portIdentifier stringByAppendingString:@"."] stringByAppendingString:@"screen.mach.port"];
        
        CFMessagePortContext context = {0,(__bridge void *)self,nil,nil,nil};
        self.sendPort = CFMessagePortCreateLocal(kCFAllocatorDefault, (__bridge CFStringRef)portName, &callback, &context, false);
        
        machServerQueue = dispatch_queue_create("machServerQueue", DISPATCH_QUEUE_SERIAL);
        CFMessagePortSetDispatchQueue(self.sendPort, machServerQueue);
        
        CFMessagePortRef ms = self.sendPort;
        mach_port_t machPort = CFMachPortGetPort(ms->_port);
    }
    return self;
}


@end

Crash is reproducible just by calling:

let portCommunication = PortCommunication(groupName: "group.ios.mach.port.bug", sdkId: "adsf") where group.ios.mach.port.bug is the app group

Hoping you could help us out. I have also filed a feedback FB11366868 for the same.

If the above is not possible going forward from iOS 16, is there a way to share an IOSurface across main app and the extension? (I know it's possible on Mac with XPC, but not sure if XPC can work iOS yet)

I am using CFMessagePort as IPC mechanism to share an IOSurface between broadcast extension and the main iOS app.

You should open a DTS tech support incident about this. This approach sounds very brittle to me; honestly, I’m surprised it ever worked.

In the very limited situations where we want to support IPC on iOS, we go out of our way to make it easy (for example, the NSFileProviderServiceSource stuff). I’m not super familiar with broadcast extensions, so I don’t know if there’s an equivalent mechanism in that space. A TSI will put you in touch with one of DTS’s graphics specialists, who can give you a definitive answer about whether there’s a supported way to do this.


Oh, wow, I only kinda skimmed your first post and misunderstood why you were posting the struct __CFMessagePort. Looking back at your code I see this:

CFMachPortGetPort(ms->_port);

So, my reading of this is:

  • There’s no API to get a CFMachPort from a CFMessagePort.

  • So you’ve declared your own __CFMessagePort structure.

  • And then use that to get the _port member.

Is that right?

If so, that’s totally unsupported and, yeah, doing stuff like this sets you up for binary compatibility problems in the future.

Share and Enjoy

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

how to send correctly IOSurface from Broadcast upload extension?

[iOS 16 Crash] Crash while getting mach port from CFMessagePortRef
 
 
Q