Replacing syscall(_NR_fork) on linux with syscall(_NR_clone)

David Holmes david.holmes at oracle.com
Tue Apr 14 05:57:46 UTC 2015


On 11/04/2015 12:19 AM, Martin Buchholz wrote:
> At Google, we also had trouble with syscall(__NR_fork).  We switched to
> simply calling fork despite the ominous warnings and have had no trouble
> since.  We avoid calling clone - see my old failures with it in
> UNIXProcess_md.c.  Although if we follow the successful precedent of
> UNIXProcess_md.c we should call vfork instead, but we haven't yet had
> the need.

Thanks Martin. As per my reply to Thomas I think following the path 
you've already trod seems the simplest short-term approach.

David

> @@ -6012,8 +6689,15 @@
>     // separate process to execve. Make a direct syscall to fork process.
>     // On IA64 there's no fork syscall, we have to use fork() and hope for
>     // the best...
> -  pid_t pid = NOT_IA64(syscall(__NR_fork);)
> -              IA64_ONLY(fork();)
> +  // pid_t pid = NOT_IA64(syscall(__NR_fork);)
> +  //            IA64_ONLY(fork();)
> +
> +  // Google Specific: Changing the above code to use the fork glibc call in
> +  // NOT_IA64. This allows the successful execution of the fork in a
> case where
> +  // the previous syscall hung  and hence allows successful OOM exit.
> +  // We believe that fork() is now async-safe and suspect the above
> note about
> +  // pthread_atfork handlers and resetting the pthread library is outdated.
> +  pid_t pid = fork();
>     if (pid < 0) {
>       // fork failed
> @@ -6029,10 +6713,16 @@
>       // in the new process, so make a system call directly.
>       // IA64 should use normal execve() from glibc to match the glibc
> fork()
>       // above.
> -    NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
> -    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
> +    // NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
> +    // IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
> +
> +    // Google Specific: Based on fork case above changed this code to
> use execve
> +    // glibc call in NOT_IA64 case.
> +    execve("/bin/sh", (char* const*)argv, environ);
>       // execve failed
> +    tty->print_cr("execve of OnError command \"/bin/sh -c %s\" failed
> with errno %d: %s",
> +                  cmd, errno, strerror(errno));
>       _exit(-1);
>     } else  {
>
>
> On Fri, Apr 10, 2015 at 12:47 AM, David Holmes <david.holmes at oracle.com
> <mailto:david.holmes at oracle.com>> wrote:
>
>     In os::fork_and_exec we provide a per platform fork/exec
>     implementation for use by the OnError and OnOutOfMemory JVM options.
>
>     On linux this is implemented with direct syscalls to _NR_fork
>     (sys_fork) and _NR_execve.
>
>     We already encountered a problem on linux-sparc:
>
>     http://mail.openjdk.java.net/__pipermail/hotspot-runtime-dev/__2015-February/013811.html
>     <http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2015-February/013811.html>
>
>     due to a different register usage for the return value, which is so
>     far restricted to the 7u train but will need addressing in 8u and 9.
>
>     Further it seems that the fork syscall has actually been deprecated
>     for quite some time and we are now seeing kernels on some platforms
>     which are no longer providing any of the deprecated syscalls - we
>     simply get an error ENOSYS.
>
>     The fork() library was updated to use clone a long time ago, but as
>     I understand it we can't use the fork() library call because we
>     might be executing in a signal-handling context within the error
>     handler.
>
>     So I'm considering switching to use the clone syscall for all linux
>     systems.
>
>     Thoughts/comments?
>
>     David
>
>


More information about the hotspot-dev mailing list