@@ -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
@@ -564,16 +567,23 @@ static int jl_lock_profile_mach(int dlsymlock)
564567 // workaround for old keymgr bugs
565568 void * unused = NULL ;
566569 int keymgr_locked = _keymgr_get_and_lock_processwide_ptr_2 (KEYMGR_GCC3_DW2_OBJ_LIST , & unused ) == 0 ;
567- // workaround for new dlsym4 bugs (API and bugs introduced in macOS 12.1)
570+ // workaround for new dlsym4 bugs in the workaround for dlsym bugs: _dyld_atfork_prepare
571+ // acquires its locks in the wrong order, but fortunately we happen to able to guard it
572+ // with this call to force it to prevent that TSAN violation from causing a deadlock
573+ if (dlsymlock && _dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
574+ _dyld_dlopen_atfork_prepare ();
575+ // workaround for new dlsym4 bugs (API and bugs introduced circa macOS 12.1)
568576 if (dlsymlock && _dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
569577 _dyld_atfork_prepare ();
570578 return keymgr_locked ;
571579}
572580
573581static void jl_unlock_profile_mach (int dlsymlock , int keymgr_locked )
574582{
575- if (dlsymlock && _dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL ) \
576- _dyld_atfork_parent (); \
583+ if (dlsymlock && _dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
584+ _dyld_atfork_parent ();
585+ if (dlsymlock && _dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
586+ _dyld_dlopen_atfork_parent ();
577587 if (keymgr_locked )
578588 _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST );
579589 jl_unlock_profile ();
@@ -618,14 +628,19 @@ void *mach_profile_listener(void *arg)
618628 break ;
619629 }
620630
631+ if (_dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
632+ _dyld_dlopen_atfork_prepare ();
621633 if (_dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
622634 _dyld_atfork_prepare (); // briefly acquire the dlsym lock
623635 host_thread_state_t state ;
624636 int valid_thread = jl_thread_suspend_and_get_state2 (i , & state );
625637 unw_context_t * uc = (unw_context_t * )& state ;
626638 if (_dyld_atfork_prepare != NULL && _dyld_atfork_parent != NULL )
627639 _dyld_atfork_parent (); // quickly release the dlsym lock
628-
640+ if (_dyld_dlopen_atfork_prepare != NULL && _dyld_dlopen_atfork_parent != NULL )
641+ _dyld_dlopen_atfork_parent ();
642+ if (!valid_thread )
643+ continue ;
629644 if (running ) {
630645#ifdef LLVMLIBUNWIND
631646 /*
0 commit comments