#if !defined (HOST_WIN32)
/**
* fork_crash_safe:
*
* Version of \c fork that is safe to call from an async context such as a
* signal handler even if the process crashed inside libc.
*
* Returns 0 to the child process, >0 to the parent process or <0 on error.
*/
static pid_t
fork_crash_safe (void)
{
pid_t pid;
/*
* glibc fork acquires some locks, so if the crash happened inside malloc/free,
* it will deadlock. Call the syscall directly instead.
*/
#if defined(HOST_ANDROID)
/* SYS_fork is defined to be __NR_fork which is not defined in some ndk versions */
g_assert_not_reached ();
#elif !defined(HOST_DARWIN) && defined(SYS_fork)
pid = (pid_t) syscall (SYS_fork);
#elif HAVE_FORK
pid = (pid_t) fork ();
#else
g_assert_not_reached ();
#endif
return pid;
}
#endif
2条答案
按热度按时间w9apscun1#
这些sys_x()调用的意义是什么?
正如名称所示,这些是在内核模式下执行的实际系统调用。
您可以看到,当您从应用程序调用
fork(2)
或open(2)
时,您并不是直接调用原始系统调用;相反,您调用的是glibc的 Package 器,它知道如何调用实际的系统调用。这个间接步骤是必要的,因为系统调用是特定于体系结构的,所以细节隐藏在glibc中。我们可以在哪里使用这些调用?
首先,
sys_fork()
是Linux特有的;其他UNIX变体不需要(可能也不需要)实现sys_fork()
函数。内核中处理分叉的确切函数与系统相关。Linux有一个函数叫做sys_fork()
、sys_open()
等等。例如,在
fork(2)
的情况下,在Linux中,流程或多或少类似于:fork()
-> glibc wrapper -> raw syscall invocation -> transition to kernel mode -> syscall lookup ->sys_fork()
->do_fork()
。dbf7pr2w2#
下面是一个
sys_fork()
很有用的例子。net运行时尝试将调试器作为其崩溃处理程序的一部分来运行。Unix上的信号处理程序只能运行异步安全函数,否则会发生死锁。因此,Mono避免使用
fork()
,而是更直接地发出系统调用:https://github.com/mono/mono/blob/1da2d9803f4e8816a41a2d1aba65ed9011791b83/mono/mini/mini-posix.c#L1040