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

Martin Buchholz martinrb at google.com
Fri Apr 10 14:19:02 UTC 2015


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.

@@ -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>
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
>
> 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