minimum is to create an os_log once in the parent, then, after fork, use an existing os_log instance or create a new one. Here's my reproduction sample. It looks like an OS bug, So what is the workaround till its solved and releases.
It is working as expected in macOS version < 14.
#include <os/log.h>
#include <stdio.h>
#include <errno.h>
#define USE_SWIFT_LOGGER 0 // set to 1 to use Logger() instead of os_log()
#define USE_SHARED_LOG 0 // set to 1 to use a shared os_log instance instead of allocating one for each os_log() call
#if USE_SWIFT_LOGGER
// log messages using Swift's Logger class instead of calling os_log_... directly
#include "forktest-Swift.h"
#define LOG(msg) log_using_logger([NSString stringWithUTF8String:msg])
const char * logMethod = "Swift's Logger";
#elif USE_SHARED_LOG
// use a shared os_log instance for all log messages
static os_log_t log = os_log_create("com.ivanti.forktest", "foo");
#define LOG(msg) os_log_debug(log, msg)
const char * logMethod = "shared log";
#else
// create a new os_log instance for each log message
#define LOG(msg) os_log_debug(os_log_create("com.ivanti.forktest", "foo"), msg)
const char * logMethod = "new log instance for each message";
#endif
static void forkTest()
{
int pid = fork();
if (pid < 0)
{
fprintf(stderr, "fork failed: %s\n", strerror(errno));
exit(1);
}
else if (pid == 0)
{
printf("in child process...\n");
LOG("in child process...");
printf("child process done\n");
}
else
{
printf("child process pid: %d\n", pid);
}
}
int main(int arc, const char ** argv)
{
printf("Log method: %s\n", logMethod);
LOG("entering main...");
forkTest();
LOG("leaving main...");
return 0;
}