#include #include #include #include int fork_and_return(int value, bool use_vfork) { pid_t pid = use_vfork ? vfork() : fork(); if (pid == -1) return -1; if (pid == 0) { // child _exit(value); } // parent int status; waitpid(pid, &status, 0); return WEXITSTATUS(status); } int fork_and_return_trap(int value) { pid_t pid = fork(); if (pid == -1) return -1; if (pid == 0) { // child returning from the JITed function wrapper will hit a trap // instruction and terminate with SIGTRAP. return value; } // parent int status; waitpid(pid, &status, 0); if (WIFSIGNALED(status) && WTERMSIG(status) == SIGTRAP) { return 1; // Success: child terminated with SIGTRAP } return 0; // Failure } // Mutex-based synchronization for concurrent fork test. // The main thread holds the mutex, starts a helper thread that waits // on the mutex then forks, and the expression releases the mutex and // waits to reacquire it - forcing the fork to happen on a different // thread while the expression is running. static pthread_mutex_t g_fork_mutex = PTHREAD_MUTEX_INITIALIZER; static pid_t g_child_pid = -1; static void *concurrent_fork_thread(void *arg) { // Wait until the expression releases the mutex. pthread_mutex_lock(&g_fork_mutex); g_child_pid = fork(); if (g_child_pid == 0) { // child _exit(42); } // parent - release mutex so expression can reacquire. pthread_mutex_unlock(&g_fork_mutex); return nullptr; } // Called as an expression while another thread forks. // The caller must hold g_fork_mutex before evaluating this expression. int expr_with_concurrent_fork() { pthread_t t; pthread_create(&t, nullptr, concurrent_fork_thread, nullptr); // Release mutex - lets the helper thread proceed to fork. pthread_mutex_unlock(&g_fork_mutex); // Wait for the helper thread to finish (it forks and unlocks). pthread_join(t, nullptr); // Reacquire mutex to synchronize. pthread_mutex_lock(&g_fork_mutex); // Return the child PID so the test can verify fork happened. return (int)g_child_pid; } int main() { pthread_mutex_lock(&g_fork_mutex); int x = 42; return 0; // break here }