3333static void * FIRCLSMachExceptionServer (void * argument );
3434static bool FIRCLSMachExceptionThreadStart (FIRCLSMachExceptionReadContext * context );
3535static bool FIRCLSMachExceptionReadMessage (FIRCLSMachExceptionReadContext * context ,
36- MachExceptionProtectedMessage * message );
36+ union MachExceptionMessage * message );
3737static kern_return_t FIRCLSMachExceptionDispatchMessage (FIRCLSMachExceptionReadContext * context ,
38- MachExceptionProtectedMessage * message );
38+ union MachExceptionMessage * message );
3939static bool FIRCLSMachExceptionReply (FIRCLSMachExceptionReadContext * context ,
40- MachExceptionProtectedMessage * message ,
40+ union 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+ union MachExceptionMessage * message );
48+ static void FIRCLSCrashedThreadLookup (union 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+ union MachExceptionMessage message ;
170171
171172 // read the exception message
172173 if (!FIRCLSMachExceptionReadMessage (context , & message )) {
@@ -187,14 +188,17 @@ static void* FIRCLSMachExceptionServer(void* argument) {
187188 return NULL ;
188189}
189190
191+ // need to chaneg here
190192static bool FIRCLSMachExceptionReadMessage (FIRCLSMachExceptionReadContext * context ,
191- MachExceptionProtectedMessage * message ) {
193+ union MachExceptionMessage * message ) {
192194 mach_msg_return_t r ;
193195
194- memset (message , 0 , sizeof (MachExceptionProtectedMessage ));
196+ memset (message , 0 , sizeof (union MachExceptionMessage ));
195197
196- r = mach_msg (& message -> head , MACH_RCV_MSG | MACH_RCV_LARGE , 0 , sizeof (MachExceptionProtectedMessage ),
198+ // no need if condition here since head structure for union MachExceptionMessage is the same.
199+ r = mach_msg (& message -> default_message .head , MACH_RCV_MSG | MACH_RCV_LARGE , 0 , sizeof (union MachExceptionMessage ),
197200 context -> port , MACH_MSG_TIMEOUT_NONE , MACH_PORT_NULL );
201+
198202 if (r != MACH_MSG_SUCCESS ) {
199203 FIRCLSSDKLog ("Error receiving mach_msg (%d)\n" , r );
200204 return false;
@@ -205,34 +209,42 @@ static bool FIRCLSMachExceptionReadMessage(FIRCLSMachExceptionReadContext* conte
205209 return true;
206210}
207211
212+ // need to change here
208213static kern_return_t FIRCLSMachExceptionDispatchMessage (FIRCLSMachExceptionReadContext * context ,
209- MachExceptionProtectedMessage * message ) {
210- FIRCLSSDKLog ("Mach exception: 0x%x, count: %d, code: 0x%llx 0x%llx\n" , message -> exception ,
211- message -> codeCnt , message -> codeCnt > 0 ? message -> code [0 ] : -1 ,
212- message -> codeCnt > 1 ? message -> code [1 ] : -1 );
213-
214- // This will happen if a child process raises an exception, as the exception ports are
215- // inherited.
216- mach_port_t actual_port ;
214+ union MachExceptionMessage * message ) {
217215 kern_return_t kr ;
218- task_id_token_t token = message -> task_id_token_t .name ;
219- kr = task_identity_token_get_task_port (token , TASK_FLAVOR_CONTROL , & actual_port );
216+
217+ if (context -> behavior == EXCEPTION_DEFAULT ) {
218+ if (message -> default_message .task .name != mach_task_self ()) {
219+ FIRCLSSDKLog ("Mach exception task mis-match, returning failure\n" );
220+ return KERN_FAILURE ;
221+ }
222+ } else {
223+ FIRCLSSDKLog ("Mach exception: 0x%x, count: %d, code: 0x%llx 0x%llx\n" , message -> protected_message .exception ,
224+ message -> protected_message .codeCnt , message -> protected_message .codeCnt > 0 ? message -> protected_message .code [0 ] : -1 ,
225+ message -> protected_message .codeCnt > 1 ? message -> protected_message .code [1 ] : -1 );
220226
221- if (kr != KERN_SUCCESS ) {
222- FIRCLSSDKLog ("Could not find task from task id token. returning failure\n" );
223- return KERN_FAILURE ;
224- }
227+ // This will happen if a child process raises an exception, as the exception ports are
228+ // inherited.
229+ mach_port_t actual_port ;
230+ task_id_token_t token = message -> protected_message .task_id_token_t .name ;
231+ kr = task_identity_token_get_task_port (token , TASK_FLAVOR_CONTROL , & actual_port );
225232
226- const bool is_mismatch = (actual_port != mach_task_self ());
227- mach_port_deallocate (mach_task_self (), actual_port );
233+ if (kr != KERN_SUCCESS ) {
234+ FIRCLSSDKLog ("Could not find task from task id token. returning failure\n" );
235+ return KERN_FAILURE ;
236+ }
237+ const bool is_mismatch = (actual_port != mach_task_self ());
238+ mach_port_deallocate (mach_task_self (), actual_port );
228239
229- if (is_mismatch ) {
230- FIRCLSSDKLog ("Mach exception task mis-match, returning failure\n" );
231- return KERN_FAILURE ;
240+ if (is_mismatch ) {
241+ FIRCLSSDKLog ("Mach exception task mis-match, returning failure\n" );
242+ return KERN_FAILURE ;
243+ }
232244 }
233245
234246 FIRCLSSDKLog ("Unregistering handler\n" );
235- if (!FIRCLSMachExceptionUnregister (& context -> originalPorts , context -> mask )) {
247+ if (!FIRCLSMachExceptionUnregister (& context -> originalPorts , context -> mask , context -> behavior )) {
236248 FIRCLSSDKLog ("Failed to unregister\n" );
237249 return KERN_FAILURE ;
238250 }
@@ -253,17 +265,17 @@ static kern_return_t FIRCLSMachExceptionDispatchMessage(FIRCLSMachExceptionReadC
253265}
254266
255267static bool FIRCLSMachExceptionReply (FIRCLSMachExceptionReadContext * context ,
256- MachExceptionProtectedMessage * message ,
268+ union MachExceptionMessage * message ,
257269 kern_return_t result ) {
258270 MachExceptionReply reply ;
259271 mach_msg_return_t r ;
260272
261273 // prepare the reply
262- reply .head .msgh_bits = MACH_MSGH_BITS (MACH_MSGH_BITS_REMOTE (message -> head .msgh_bits ), 0 );
263- reply .head .msgh_remote_port = message -> head .msgh_remote_port ;
274+ reply .head .msgh_bits = MACH_MSGH_BITS (MACH_MSGH_BITS_REMOTE (message -> default_message . head .msgh_bits ), 0 );
275+ reply .head .msgh_remote_port = message -> default_message . head .msgh_remote_port ;
264276 reply .head .msgh_size = (mach_msg_size_t )sizeof (MachExceptionReply );
265277 reply .head .msgh_local_port = MACH_PORT_NULL ;
266- reply .head .msgh_id = message -> head .msgh_id + 100 ;
278+ reply .head .msgh_id = message -> default_message . head .msgh_id + 100 ;
267279
268280 reply .NDR = NDR_record ;
269281
@@ -309,7 +321,7 @@ static bool FIRCLSMachExceptionRegister(FIRCLSMachExceptionReadContext* context)
309321
310322 // ORing with MACH_EXCEPTION_CODES will produce 64-bit exception data
311323 kr = task_swap_exception_ports (task , context -> mask , context -> port ,
312- EXCEPTION_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES , THREAD_STATE_NONE ,
324+ context -> behavior | MACH_EXCEPTION_CODES , THREAD_STATE_NONE ,
313325 context -> originalPorts .masks , & context -> originalPorts .count ,
314326 context -> originalPorts .ports , context -> originalPorts .behaviors ,
315327 context -> originalPorts .flavors );
@@ -328,7 +340,8 @@ static bool FIRCLSMachExceptionRegister(FIRCLSMachExceptionReadContext* context)
328340}
329341
330342static bool FIRCLSMachExceptionUnregister (FIRCLSMachExceptionOriginalPorts * originalPorts ,
331- exception_mask_t mask ) {
343+ exception_mask_t mask ,
344+ exception_behavior_t behavior ) {
332345 kern_return_t kr ;
333346
334347 // Re-register all the old ports.
@@ -346,7 +359,7 @@ static bool FIRCLSMachExceptionUnregister(FIRCLSMachExceptionOriginalPorts* orig
346359
347360 // Finally, mark any masks we registered for that do not have an original port as unused.
348361 kr = task_set_exception_ports (mach_task_self (), mask , MACH_PORT_NULL ,
349- EXCEPTION_IDENTITY_PROTECTED | MACH_EXCEPTION_CODES , THREAD_STATE_NONE );
362+ behavior | MACH_EXCEPTION_CODES , THREAD_STATE_NONE );
350363 if (kr != KERN_SUCCESS ) {
351364 FIRCLSSDKLog ("unable to unset unregistered mask: 0x%x" , mask );
352365 return false;
@@ -485,7 +498,7 @@ void FIRCLSMachExceptionNameLookup(exception_type_t number,
485498}
486499
487500static bool FIRCLSMachExceptionRecord (FIRCLSMachExceptionReadContext * context ,
488- MachExceptionProtectedMessage * message ) {
501+ union MachExceptionMessage * message ) {
489502 if (!context || !message ) {
490503 return false;
491504 }
@@ -507,21 +520,36 @@ static bool FIRCLSMachExceptionRecord(FIRCLSMachExceptionReadContext* context,
507520
508521 FIRCLSFileWriteHashStart (& file );
509522
510- FIRCLSFileWriteHashEntryUint64 (& file , "exception" , message -> exception );
523+ if (context -> behavior == EXCEPTION_DEFAULT ) {
524+ FIRCLSFileWriteHashEntryUint64 (& file , "exception" , message -> default_message .exception );
525+ } else {
526+ FIRCLSFileWriteHashEntryUint64 (& file , "exception" , message -> protected_message .exception );
527+ }
511528
512529 // record the codes
513530 FIRCLSFileWriteHashKey (& file , "codes" );
514531 FIRCLSFileWriteArrayStart (& file );
515- for (mach_msg_type_number_t i = 0 ; i < message -> codeCnt ; ++ i ) {
516- FIRCLSFileWriteArrayEntryUint64 (& file , message -> code [i ]);
532+ if (context -> behavior == EXCEPTION_DEFAULT ) {
533+ for (mach_msg_type_number_t i = 0 ; i < message -> default_message .codeCnt ; ++ i ) {
534+ FIRCLSFileWriteArrayEntryUint64 (& file , message -> default_message .code [i ]);
535+ }
536+ } else {
537+ for (mach_msg_type_number_t i = 0 ; i < message -> protected_message .codeCnt ; ++ i ) {
538+ FIRCLSFileWriteArrayEntryUint64 (& file , message -> protected_message .code [i ]);
539+ }
517540 }
518541 FIRCLSFileWriteArrayEnd (& file );
519542
520543 const char * name = NULL ;
521544 const char * codeName = NULL ;
522545
523- FIRCLSMachExceptionNameLookup (message -> exception , message -> codeCnt > 0 ? message -> code [0 ] : 0 ,
524- & name , & codeName );
546+ if (context -> behavior == EXCEPTION_DEFAULT ) {
547+ FIRCLSMachExceptionNameLookup (message -> default_message .exception , message -> default_message .codeCnt > 0 ? message -> default_message .code [0 ] : 0 ,
548+ & name , & codeName );
549+ } else {
550+ FIRCLSMachExceptionNameLookup (message -> protected_message .exception , message -> protected_message .codeCnt > 0 ? message -> protected_message .code [0 ] : 0 ,
551+ & name , & codeName );
552+ }
525553
526554 FIRCLSFileWriteHashEntryString (& file , "name" , name );
527555 FIRCLSFileWriteHashEntryString (& file , "code_name" , codeName );
@@ -545,7 +573,7 @@ static bool FIRCLSMachExceptionRecord(FIRCLSMachExceptionReadContext* context,
545573 return true;
546574}
547575
548- static void FIRCLSCrashedThreadLookup (MachExceptionProtectedMessage * message , thread_t * crashedThread ) {
576+ static void FIRCLSCrashedThreadLookup (union MachExceptionMessage * message , thread_t * crashedThread ) {
549577 thread_act_array_t threadList ;
550578 mach_msg_type_number_t threadCount ;
551579
@@ -564,7 +592,7 @@ static void FIRCLSCrashedThreadLookup(MachExceptionProtectedMessage* message, th
564592
565593 if (kr == KERN_SUCCESS ) {
566594 FIRCLSSDKLog ("Thread %d: Thread port: %d, thread id: %llx\n" , i , threadList [i ], identifierInfo .thread_id );
567- if (message -> thread_id == identifierInfo .thread_id ) {
595+ if (message -> protected_message . thread_id == identifierInfo .thread_id ) {
568596 FIRCLSSDKLog ("Find crashed thread: %d\n" , threadList [i ]);
569597 * crashedThread = threadList [i ];
570598 break ;
0 commit comments