[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Forced crash under macOS 14 due to internal threading
From: |
Bruno Haible |
Subject: |
Re: Forced crash under macOS 14 due to internal threading |
Date: |
Fri, 03 May 2024 15:44:03 +0200 |
Hi,
> Running the following:
>
> ```
> #include <libintl.h>
> #include <stdlib.h>
> #include <unistd.h>
>
> int main() {
> unsetenv("LANG");
>
> setlocale(LC_ALL, "");
>
> if (fork() == 0) {
> gettext("test");
> }
> }
> ```
>
> under macos14, crashes with the following error:
>
> ```
> objc[16942]: +[__SwiftNativeNSStringBase initialize] may have been in
> progress in another thread when fork() was called.
> objc[16942]: +[__SwiftNativeNSStringBase initialize] may have been in
> progress in another thread when fork() was called. We cannot safely call it
> or ignore it in the fork() child process. Crashing instead. Set a breakpoint
> on objc_initializeAfterForkError to debug.
> ```
>
> The call to `setlocale` spawns threads (via `dispatch_apply`) with the
> following backtrace:
>
> ```
> * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
> * frame #0: 0x0000000182c5602c libdispatch.dylib`dispatch_apply
> frame #1: 0x0000000183000af0
> CoreFoundation`__103-[CFPrefsSearchListSource
> synchronouslySendSystemMessage:andUserMessage:andDirectMessage:replyHandler:]_block_invoke.52
> + 132
> frame #2: 0x0000000182e86cbc
> CoreFoundation`CFPREFERENCES_IS_WAITING_FOR_SYSTEM_AND_USER_CFPREFSDS + 100
> frame #3: 0x0000000182fffce0 CoreFoundation`-[CFPrefsSearchListSource
> synchronouslySendSystemMessage:andUserMessage:andDirectMessage:replyHandler:]
> + 232
> frame #4: 0x0000000182e84f68 CoreFoundation`-[CFPrefsSearchListSource
> alreadylocked_generationCountFromListOfSources:count:] + 232
> frame #5: 0x0000000182e84c70 CoreFoundation`-[CFPrefsSearchListSource
> alreadylocked_getDictionary:] + 492
> frame #6: 0x0000000182e847dc CoreFoundation`-[CFPrefsSearchListSource
> alreadylocked_copyValueForKey:] + 172
> frame #7: 0x0000000182e84710 CoreFoundation`-[CFPrefsSource
> copyValueForKey:] + 52
> frame #8: 0x0000000182e846c4 CoreFoundation`__76-[_CFXPreferences
> copyAppValueForKey:identifier:container:configurationURL:]_block_invoke + 32
> frame #9: 0x0000000182e7dd00
> CoreFoundation`__108-[_CFXPreferences(SearchListAdditions)
> withSearchListForIdentifier:container:cloudConfigurationURL:perform:]_block_invoke
> + 376
> frame #10: 0x00000001830013a0 CoreFoundation`-[_CFXPreferences
> withSearchListForIdentifier:container:cloudConfigurationURL:perform:] + 384
> frame #11: 0x0000000182e7d5d8 CoreFoundation`-[_CFXPreferences
> copyAppValueForKey:identifier:container:configurationURL:] + 156
> frame #12: 0x0000000182e7d500
> CoreFoundation`_CFPreferencesCopyAppValueWithContainerAndConfiguration + 112
> frame #13: 0x00000001004827e4
> libintl.8.dylib`_libintl_locale_name_default + 72
> frame #14: 0x0000000100481990 libintl.8.dylib`libintl_setlocale + 164
> frame #15: 0x0000000100003f38 main`main + 52
> frame #16: 0x0000000182a6a0e0 dyld`start + 2360
> ```
>
> and the call to `gettext` triggers this crash (via
> `performForkChildInitialize`) with the following backtrace:
>
> ```
> * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
> * frame #0: 0x0000000182a382c4 libobjc.A.dylib`objc_initializeAfterForkError
> frame #1: 0x0000000182a38448
> libobjc.A.dylib`performForkChildInitialize(objc_class*, objc_class*) + 376
> frame #2: 0x0000000182a1eba4 libobjc.A.dylib`initializeNonMetaClass + 572
> frame #3: 0x0000000182a1ea04 libobjc.A.dylib`initializeNonMetaClass + 156
> frame #4: 0x0000000182a1ea04 libobjc.A.dylib`initializeNonMetaClass + 156
> frame #5: 0x0000000182a3bbfc
> libobjc.A.dylib`initializeAndMaybeRelock(objc_class*, objc_object*,
> locker_mixin<lockdebug::lock_mixin<objc_lock_base_t>>&, bool) + 164
> frame #6: 0x0000000182a1e5c4 libobjc.A.dylib`lookUpImpOrForward + 892
> frame #7: 0x0000000182a1df64 libobjc.A.dylib`_objc_msgSend_uncached + 68
> frame #8: 0x0000000192dfbbc8 libswiftCore.dylib`type metadata accessor
> for Swift.__StringStorage + 24
> frame #9: 0x0000000192b85f24
> libswiftCore.dylib`Swift.String._bridgeToObjectiveCImpl() -> Swift.AnyObject
> + 152
> frame #10: 0x0000000184409f80 Foundation`function signature
> specialization <Arg[1] = Dead> of
> Foundation.LocaleCache.preferredLanguages(forCurrentUser: Swift.Bool) ->
> Swift.Array<Swift.String> + 76
> frame #11: 0x00000001844ec9c4 Foundation`@objc static
> __C.NSLocale._preferredLanguagesForCurrentUser(Swift.Bool) ->
> Swift.Array<Swift.String> + 44
> frame #12: 0x0000000182ece0b4
> CoreFoundation`CFLocaleCopyPreferredLanguages + 28
> frame #13: 0x0000000100a553dc
> libintl.8.dylib`_libintl_language_preferences_default + 68
> frame #14: 0x0000000100a53d40 libintl.8.dylib`libintl_dcigettext + 812
> frame #15: 0x00000001005d7f10 main`main + 120
> frame #16: 0x0000000182a6a0e0 dyld`start + 2360
> ```
>
> This is the case with `gettext` 0.22.5, 0.21.1 and 0.20.2; 0.19.8.1 does not
> exhibit this behaviour as it doesn't call `CFLocaleCopyPreferredLanguages`.
Thanks for the report. Both CFLocaleCopyPreferredLanguages and
CFPreferencesCopyAppValue are documented API from Apple [1][2],
with no hints regarding multithreading. I have no idea how to
influence the behaviour of these functions w.r.t. multithreading.
Can you report the issue to Apple, after having replaced the call
to setlocale with a call to
char namebuf[256];
CFTypeRef value =
CFPreferencesCopyAppValue (CFSTR ("AppleLocale"),
kCFPreferencesCurrentApplication);
and the call to gettext with a call to
CFArrayRef prefArray = CFLocaleCopyPreferredLanguages ();
?
Other than that, a workaround can be:
- In applications use fork+exec, use posix_spawn and posix_spawnp.
- In applications that fork without exec, move the initializations
past the fork(), so that at the moment of the fork(), the application
is still single-threaded.
Bruno
[1]
https://developer.apple.com/documentation/corefoundation/1542887-cflocalecopypreferredlanguages?language=objc
[2]
https://developer.apple.com/documentation/corefoundation/1515497-cfpreferencescopyappvalue?language=objc