mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Initialize Objective-C classes before fork() for macOS 13
Since macOS 13, CFString family API used in `rb_str_append_normalized_ospath` may internally use Objective-C classes (`NSTaggedPointerString` and `NSPlaceholderMutableString`) for small strings. On the other hand, Objective-C classes should not be used for the first time in a `fork()`'ed but not `exec()`'ed process. Violations for this rule can result deadlock during class initialization, so Objective-C runtime conservatively crashes on such cases by default. Therefore, we need to use CFString API to initialize Objective-C classes used internally *before* `fork()`. For more details, see https://bugs.ruby-lang.org/issues/18912
This commit is contained in:
parent
d89f8a0467
commit
e3cc1a6cae
Notes:
git
2022-09-26 12:04:02 +09:00
1 changed files with 44 additions and 0 deletions
44
file.c
44
file.c
|
@ -268,6 +268,46 @@ rb_str_encode_ospath(VALUE path)
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
# define NORMALIZE_UTF8PATH 1
|
# define NORMALIZE_UTF8PATH 1
|
||||||
|
|
||||||
|
# ifdef HAVE_WORKING_FORK
|
||||||
|
static void
|
||||||
|
rb_CFString_class_initialize_before_fork(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Since macOS 13, CFString family API used in
|
||||||
|
* rb_str_append_normalized_ospath may internally use Objective-C classes
|
||||||
|
* (NSTaggedPointerString and NSPlaceholderMutableString) for small strings.
|
||||||
|
*
|
||||||
|
* On the other hand, Objective-C classes should not be used for the first
|
||||||
|
* time in a fork()'ed but not exec()'ed process. Violations for this rule
|
||||||
|
* can result deadlock during class initialization, so Objective-C runtime
|
||||||
|
* conservatively crashes on such cases by default.
|
||||||
|
*
|
||||||
|
* Therefore, we need to use CFString API to initialize Objective-C classes
|
||||||
|
* used internally *before* fork().
|
||||||
|
*
|
||||||
|
* For future changes, please note that this initialization process cannot
|
||||||
|
* be done in ctor because NSTaggedPointerString in CoreFoundation is enabled
|
||||||
|
* after CFStringInitializeTaggedStrings(), which is called during loading
|
||||||
|
* Objective-C runtime after ctor.
|
||||||
|
* For more details, see https://bugs.ruby-lang.org/issues/18912
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Enough small but non-empty ASCII string to fit in NSTaggedPointerString. */
|
||||||
|
const char small_str[] = "/";
|
||||||
|
long len = sizeof(small_str) - 1;
|
||||||
|
|
||||||
|
const CFAllocatorRef alloc = kCFAllocatorDefault;
|
||||||
|
CFStringRef s = CFStringCreateWithBytesNoCopy(alloc,
|
||||||
|
(const UInt8 *)small_str,
|
||||||
|
len, kCFStringEncodingUTF8,
|
||||||
|
FALSE, kCFAllocatorNull);
|
||||||
|
CFMutableStringRef m = CFStringCreateMutableCopy(alloc, len, s);
|
||||||
|
CFRelease(m);
|
||||||
|
CFRelease(s);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_str_append_normalized_ospath(VALUE str, const char *ptr, long len)
|
rb_str_append_normalized_ospath(VALUE str, const char *ptr, long len)
|
||||||
{
|
{
|
||||||
|
@ -7317,6 +7357,10 @@ const char ruby_null_device[] =
|
||||||
void
|
void
|
||||||
Init_File(void)
|
Init_File(void)
|
||||||
{
|
{
|
||||||
|
#if defined(__APPLE__) && defined(HAVE_WORKING_FORK)
|
||||||
|
rb_CFString_class_initialize_before_fork();
|
||||||
|
#endif
|
||||||
|
|
||||||
VALUE separator;
|
VALUE separator;
|
||||||
|
|
||||||
rb_mFileTest = rb_define_module("FileTest");
|
rb_mFileTest = rb_define_module("FileTest");
|
||||||
|
|
Loading…
Reference in a new issue