@@ -36,6 +36,9 @@ extern int _keymgr_set_lockmode_processwide_ptr(unsigned int key, unsigned int m
3636extern void _dyld_atfork_prepare (void ) __attribute__((weak_import ));
3737extern void _dyld_atfork_parent (void ) __attribute__((weak_import ));
3838//extern void _dyld_fork_child(void) __attribute__((weak_import));
39+ extern void _dyld_dlopen_atfork_prepare (void ) __attribute__((weak_import ));
40+ extern void _dyld_dlopen_atfork_parent (void ) __attribute__((weak_import ));
41+ //extern void _dyld_dlopen_atfork_child(void) __attribute__((weak_import));
3942
4043static void attach_exception_port (thread_port_t thread , int segv_only );
4144
@@ -568,16 +571,23 @@ static int jl_lock_profile_mach(int dlsymlock)
568571 // workaround for old keymgr bugs
569572 void * unused = NULL ;
570573 int keymgr_locked = _keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_DW2_OBJ_LIST , & unused ) == 0 ;
571- // workaround for new dlsym4 bugs (API and bugs introduced in macOS 12.1)
574+ // workaround for new dlsym4 bugs in the workaround for dlsym bugs: _dyld_atfork_prepare
575+ // acquires its locks in the wrong order, but fortunately we happen to able to guard it
576+ // with this call to force it to prevent that TSAN violation from causing a deadlock
577+ if (dlsymlock && _dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
578+ _dyld_dlopen_atfork_prepare ();
579+ // workaround for new dlsym4 bugs (API and bugs introduced circa macOS 12.1)
572580 if (dlsymlock && _dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
573581 _dyld_atfork_prepare ();
574582 return keymgr_locked ;
575583}
576584
577585static void jl_unlock_profile_mach (int dlsymlock , int keymgr_locked )
578586{
579- if (dlsymlock && _dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL ) \
580- _dyld_atfork_parent (); \
587+ if (dlsymlock && _dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
588+ _dyld_atfork_parent ();
589+ if (dlsymlock && _dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
590+ _dyld_dlopen_atfork_parent ();
581591 if (keymgr_locked )
582592 _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST );
583593 jl_unlock_profile ();
@@ -622,14 +632,19 @@ void *mach_profile_listener(void *arg)
622632 break ;
623633 }
624634
635+ if (_dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
636+ _dyld_dlopen_atfork_prepare ();
625637 if (_dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
626638 _dyld_atfork_prepare (); // briefly acquire the dlsym lock
627639 host_thread_state_t state ;
628640 int valid_thread = jl_thread_suspend_and_get_state2 (i , & state );
629641 unw_context_t * uc = (unw_context_t * )& state ;
630642 if (_dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
631643 _dyld_atfork_parent (); // quickly release the dlsym lock
632-
644+ if (_dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
645+ _dyld_dlopen_atfork_parent ();
646+ if (!valid_thread )
647+ continue ;
633648 if (running ) {
634649#ifdef LLVMLIBUNWIND
635650 /*
0 commit comments