3333static void * FIRCLSMachExceptionServer (void * argument );
3434static bool FIRCLSMachExceptionThreadStart (FIRCLSMachExceptionReadContext * context );
3535static bool FIRCLSMachExceptionReadMessage (FIRCLSMachExceptionReadContext * context ,
36- MachExceptionProtectedMessage * message );
36+ MachExceptionMessage * message );
3737static kern_return_t FIRCLSMachExceptionDispatchMessage (FIRCLSMachExceptionReadContext * context ,
38- MachExceptionProtectedMessage * message );
38+ MachExceptionMessage * message );
3939static bool FIRCLSMachExceptionReply (FIRCLSMachExceptionReadContext * context ,
40- MachExceptionProtectedMessage * message ,
40+ MachExceptionMessage * message ,
4141 kern_return_t result );
4242static bool FIRCLSMachExceptionRegister (FIRCLSMachExceptionReadContext * context );
4343static bool FIRCLSMachExceptionUnregister (FIRCLSMachExceptionOriginalPorts * originalPorts ,
44- exception_mask_t mask );
44+ exception_mask_t mask ,
45+ exception_behavior_t behavior );
4546static bool FIRCLSMachExceptionRecord (FIRCLSMachExceptionReadContext * context ,
46- MachExceptionProtectedMessage * message );
47- static void FIRCLSCrashedThreadLookup (MachExceptionProtectedMessage * message , thread_t * crashedThread );
47+ MachExceptionMessage * message );
48+ static void FIRCLSCrashedThreadLookup (MachExceptionMessage * message , thread_t * crashedThread );
4849#pragma mark - Initialization
4950void FIRCLSMachExceptionInit (FIRCLSMachExceptionReadContext * context ) {
5051 if (!FIRCLSUnlinkIfExists (context -> path )) {
@@ -58,7 +59,7 @@ void FIRCLSMachExceptionInit(FIRCLSMachExceptionReadContext* context) {
5859
5960 if (!FIRCLSMachExceptionThreadStart (context )) {
6061 FIRCLSSDKLog ("Unable to start thread\n" );
61- FIRCLSMachExceptionUnregister (& context -> originalPorts , context -> mask );
62+ FIRCLSMachExceptionUnregister (& context -> originalPorts , context -> mask , context -> behavior );
6263 }
6364}
6465
@@ -166,7 +167,7 @@ static void* FIRCLSMachExceptionServer(void* argument) {
166167 pthread_setname_np ("com.google.firebase.crashlytics.MachExceptionServer" );
167168
168169 while (1 ) {
169- MachExceptionProtectedMessage message ;
170+ MachExceptionMessage message ;
170171
171172 // read the exception message
172173 if (!FIRCLSMachExceptionReadMessage (context , & message )) {
@@ -188,12 +189,12 @@ static void* FIRCLSMachExceptionServer(void* argument) {
188189}
189190
190191static bool FIRCLSMachExceptionReadMessage (FIRCLSMachExceptionReadContext * context ,
191- MachExceptionProtectedMessage * message ) {
192+ MachExceptionMessage * message ) {
192193 mach_msg_return_t r ;
193194
194- memset (message , 0 , sizeof (MachExceptionProtectedMessage ));
195+ memset (message , 0 , sizeof (MachExceptionMessage ));
195196
196- r = mach_msg (& message -> head , MACH_RCV_MSG | MACH_RCV_LARGE , 0 , sizeof (MachExceptionProtectedMessage ),
197+ r = mach_msg (& message -> head , MACH_RCV_MSG | MACH_RCV_LARGE , 0 , sizeof (MachExceptionMessage ),
197198 context -> port , MACH_MSG_TIMEOUT_NONE , MACH_PORT_NULL );
198199 if (r != MACH_MSG_SUCCESS ) {
199200 FIRCLSSDKLog ("Error receiving mach_msg (%d)\n" , r );
@@ -206,25 +207,30 @@ static bool FIRCLSMachExceptionReadMessage(FIRCLSMachExceptionReadContext* conte
206207}
207208
208209static kern_return_t FIRCLSMachExceptionDispatchMessage (FIRCLSMachExceptionReadContext * context ,
209- MachExceptionProtectedMessage * message ) {
210+ MachExceptionMessage * message ) {
210211 FIRCLSSDKLog ("Mach exception: 0x%x, count: %d, code: 0x%llx 0x%llx\n" , message -> exception ,
211212 message -> codeCnt , message -> codeCnt > 0 ? message -> code [0 ] : -1 ,
212213 message -> codeCnt > 1 ? message -> code [1 ] : -1 );
213214
214215 // This will happen if a child process raises an exception, as the exception ports are
215216 // inherited.
216217 mach_port_t actual_port ;
217- kern_return_t kr ;
218- task_id_token_t token = message -> task_id .name ;
219- kr = task_identity_token_get_task_port (token , TASK_FLAVOR_CONTROL , & actual_port );
218+ kern_return_t kr = KERN_SUCCESS ;
219+ if (context -> behavior == EXCEPTION_DEFAULT ){
220+ actual_port = message -> payload .default_payload .task .name ;
221+ } else {
222+ // EXCEPTION_IDENTITY_PROTECTED
223+ task_id_token_t token = message -> payload .protected_payload .task_id_token .name ;
224+ kr = task_identity_token_get_task_port (token , TASK_FLAVOR_CONTROL , & actual_port );
225+ }
220226
221227 if (kr || actual_port != mach_task_self ()) {
222228 FIRCLSSDKLog ("Mach exception task mis-match, returning failure\n" );
223229 return KERN_FAILURE ;
224230 }
225231
226232 FIRCLSSDKLog ("Unregistering handler\n" );
227- if (!FIRCLSMachExceptionUnregister (& context -> originalPorts , context -> mask )) {
233+ if (!FIRCLSMachExceptionUnregister (& context -> originalPorts , context -> mask , context -> behavior )) {
228234 FIRCLSSDKLog ("Failed to unregister\n" );
229235 return KERN_FAILURE ;
230236 }
@@ -245,7 +251,7 @@ static kern_return_t FIRCLSMachExceptionDispatchMessage(FIRCLSMachExceptionReadC
245251}
246252
247253static bool FIRCLSMachExceptionReply (FIRCLSMachExceptionReadContext * context ,
248- MachExceptionProtectedMessage * message ,
254+ MachExceptionMessage * message ,
249255 kern_return_t result ) {
250256 MachExceptionReply reply ;
251257 mach_msg_return_t r ;
@@ -301,7 +307,7 @@ static bool FIRCLSMachExceptionRegister(FIRCLSMachExceptionReadContext* context)
301307
302308 // ORing with MACH_EXCEPTION_CODES will produce 64-bit exception data
303309 kr = task_swap_exception_ports (task , context -> mask , context -> port ,
304- EXCEPTION_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES , THREAD_STATE_NONE ,
310+ context -> behavior | MACH_EXCEPTION_CODES , THREAD_STATE_NONE ,
305311 context -> originalPorts .masks , & context -> originalPorts .count ,
306312 context -> originalPorts .ports , context -> originalPorts .behaviors ,
307313 context -> originalPorts .flavors );
@@ -320,7 +326,8 @@ static bool FIRCLSMachExceptionRegister(FIRCLSMachExceptionReadContext* context)
320326}
321327
322328static bool FIRCLSMachExceptionUnregister (FIRCLSMachExceptionOriginalPorts * originalPorts ,
323- exception_mask_t mask ) {
329+ exception_mask_t mask ,
330+ exception_behavior_t behavior ) {
324331 kern_return_t kr ;
325332
326333 // Re-register all the old ports.
@@ -338,7 +345,7 @@ static bool FIRCLSMachExceptionUnregister(FIRCLSMachExceptionOriginalPorts* orig
338345
339346 // Finally, mark any masks we registered for that do not have an original port as unused.
340347 kr = task_set_exception_ports (mach_task_self (), mask , MACH_PORT_NULL ,
341- EXCEPTION_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES , THREAD_STATE_NONE );
348+ behavior | MACH_EXCEPTION_CODES , THREAD_STATE_NONE );
342349 if (kr != KERN_SUCCESS ) {
343350 FIRCLSSDKLog ("unable to unset unregistered mask: 0x%x" , mask );
344351 return false;
@@ -477,7 +484,7 @@ void FIRCLSMachExceptionNameLookup(exception_type_t number,
477484}
478485
479486static bool FIRCLSMachExceptionRecord (FIRCLSMachExceptionReadContext * context ,
480- MachExceptionProtectedMessage * message ) {
487+ MachExceptionMessage * message ) {
481488 if (!context || !message ) {
482489 return false;
483490 }
@@ -526,7 +533,12 @@ static bool FIRCLSMachExceptionRecord(FIRCLSMachExceptionReadContext* context,
526533 FIRCLSFileWriteSectionEnd (& file );
527534
528535 thread_t crashedThread ;
529- FIRCLSCrashedThreadLookup (message , & crashedThread );
536+ if (context -> behavior == EXCEPTION_DEFAULT ) {
537+ crashedThread = message -> payload .default_payload .thread .name ;
538+ } else {
539+ // EXCEPTION_IDENTITY_PROTECTED
540+ FIRCLSCrashedThreadLookup (message , & crashedThread );
541+ }
530542 FIRCLSSDKLog ("Crashed threads: %d\n" , crashedThread );
531543 FIRCLSHandler (& file , crashedThread , NULL , true);
532544
@@ -535,12 +547,12 @@ static bool FIRCLSMachExceptionRecord(FIRCLSMachExceptionReadContext* context,
535547 return true;
536548}
537549
538- static void FIRCLSCrashedThreadLookup (MachExceptionProtectedMessage * message , thread_t * crashedThread ) {
550+ static void FIRCLSCrashedThreadLookup (MachExceptionMessage * message , thread_t * crashedThread ) {
539551 thread_act_array_t threadList ;
540552 mach_msg_type_number_t threadCount ;
541553
542554 // last 64 bits include thread id info
543- MachExceptionProtectedThreadInfo protected_thread_info = * (MachExceptionProtectedThreadInfo * ) & message -> thread_id ;
555+ MachExceptionProtectedThreadInfo protected_thread_info = * (MachExceptionProtectedThreadInfo * ) & message -> payload . protected_payload . thread_id ;
544556 kern_return_t kr = task_threads (mach_task_self (), & threadList , & threadCount );
545557
546558 if (kr != KERN_SUCCESS ) {
0 commit comments