public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* CLONE_VM: parent terminates silently when child segfaults
@ 2010-01-27 20:48 Frank Heckenbach
  2010-02-04  8:01 ` Américo Wang
  0 siblings, 1 reply; 3+ messages in thread
From: Frank Heckenbach @ 2010-01-27 20:48 UTC (permalink / raw)
  To: linux-kernel

When a process cloned with CLONE_VM is killed by SIGSEGV, the parent
process is terminated silently. I don't know if this is known or
intended behaviour, but I didn't find anything about it.

The test program below demonstrates the problem. It forks a process
which in turn clones another process which kills itself with
SIGSEGV.

When I remove the CLONE_VM flag, the program runs as expected:

  fork_pid = ...
  clone_pid = ...
  (1 second delay)
  cloned process status = 11
  forked process status = 0

However, with CLONE_VM I get:

  fork_pid = ...
  clone_pid = ...
  (1 second delay)
  forked process status = 0

i.e., no output from the first forked process after its waitpid(),
and no error indication in its status as seen by the main process.

Note: The fork() before clone() is not essential to cause this
behaviour, just to see its effects (in the 2nd waitpid()). You can
see the same by calling the program without fork from the shell and
looking at $?. I just put in fork to make sure it's not a shell
problem or something.

The problem only occurs with signals such as SIGSEGV or SIGILL, not
with SIGINT, SIGUSR1, etc. Since CLONE_VM and SIGSEGV both have to
do with the shared memory space, I'd understand if the parent
process was also killed by SIGSEGV or so. But having it return with
status 0 seems strange -- how is one supposed to detect a SIGSEGV in
the child? The parent can't do it when it's terminated, and the
parent's parent only sees it terminate with 0.

BTW, maybe not relevant, but if I run the program (with CLONE_VM)
under "strace -f", I see the following message which might indicate
that also strace thinks something's wrong here:

  PANIC: attached pid <fork_pid> exited

System information:

Linux odh 2.6.25-2-686 #1 SMP Sat Jun 28 13:44:14 UTC 2008 i686 GNU/Linux
glibc 2.3.6.ds1-13
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
strace -- version 4.5.14

(i.e., Debian etch, with updated kernel from etch-backports)

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sched.h>
#include <wait.h>

int foo (void *dummy)
{
  sleep (1);
  kill (getpid (), SIGSEGV);
  while (1)
    pause ();
}

int main ()
{
  int fork_pid = fork ();
  if (fork_pid == 0)
    {
      static char stack[0x4000];
      int clone_pid = clone (foo, stack + 0x2000, SIGCHLD | CLONE_VM, NULL);
      printf ("clone_pid = %i\n", clone_pid);
      int s;
      waitpid (clone_pid, &s, 0);
      printf ("cloned process status = %i\n", s);
    }
  else if (fork_pid > 0)
    {
      printf ("fork_pid = %i\n", fork_pid);
      int s;
      waitpid (fork_pid, &s, 0);
      printf ("forked process status = %i\n", s);
    }
  return 0;
}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: CLONE_VM: parent terminates silently when child segfaults
  2010-01-27 20:48 CLONE_VM: parent terminates silently when child segfaults Frank Heckenbach
@ 2010-02-04  8:01 ` Américo Wang
  2010-02-04 10:50   ` Oleg Nesterov
  0 siblings, 1 reply; 3+ messages in thread
From: Américo Wang @ 2010-02-04  8:01 UTC (permalink / raw)
  To: Frank Heckenbach; +Cc: linux-kernel, oleg

On Thu, Jan 28, 2010 at 4:48 AM, Frank Heckenbach
<f.heckenbach@fh-soft.de> wrote:
> When a process cloned with CLONE_VM is killed by SIGSEGV, the parent
> process is terminated silently. I don't know if this is known or
> intended behaviour, but I didn't find anything about it.
>
> The test program below demonstrates the problem. It forks a process
> which in turn clones another process which kills itself with
> SIGSEGV.
>
> When I remove the CLONE_VM flag, the program runs as expected:
>
>  fork_pid = ...
>  clone_pid = ...
>  (1 second delay)
>  cloned process status = 11
>  forked process status = 0
>
> However, with CLONE_VM I get:
>
>  fork_pid = ...
>  clone_pid = ...
>  (1 second delay)
>  forked process status = 0
>
> i.e., no output from the first forked process after its waitpid(),
> and no error indication in its status as seen by the main process.
>
> Note: The fork() before clone() is not essential to cause this
> behaviour, just to see its effects (in the 2nd waitpid()). You can
> see the same by calling the program without fork from the shell and
> looking at $?. I just put in fork to make sure it's not a shell
> problem or something.
>
> The problem only occurs with signals such as SIGSEGV or SIGILL, not
> with SIGINT, SIGUSR1, etc. Since CLONE_VM and SIGSEGV both have to
> do with the shared memory space, I'd understand if the parent
> process was also killed by SIGSEGV or so. But having it return with
> status 0 seems strange -- how is one supposed to detect a SIGSEGV in
> the child? The parent can't do it when it's terminated, and the
> parent's parent only sees it terminate with 0.

I think this behavior is somewhat expected.

Becase SIGSEGV and SIGILL are coredump signals, when you use CLONE_VM,
child process will share the memory space with its parent, what would
you expect the parent behaves when its child coredumping their shared memory
space?

Also, you may want to check CLONE_THREAD too, it also provides a chance
of leaving the status of child unavailable.

Cc'ing signal experts...

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: CLONE_VM: parent terminates silently when child segfaults
  2010-02-04  8:01 ` Américo Wang
@ 2010-02-04 10:50   ` Oleg Nesterov
  0 siblings, 0 replies; 3+ messages in thread
From: Oleg Nesterov @ 2010-02-04 10:50 UTC (permalink / raw)
  To: Américo Wang; +Cc: Frank Heckenbach, linux-kernel

On 02/04, Américo Wang wrote:
>
> On Thu, Jan 28, 2010 at 4:48 AM, Frank Heckenbach
> <f.heckenbach@fh-soft.de> wrote:
> > When a process cloned with CLONE_VM is killed by SIGSEGV, the parent
> > process is terminated silently.
>
> Becase SIGSEGV and SIGILL are coredump signals, when you use CLONE_VM,
> child process will share the memory space with its parent, what would
> you expect the parent behaves when its child coredumping their shared memory
> space?

Yes, exactly. The coredump signals kill/dump all threads which share
this ->mm, this is intentional.

As for status = 0 I agree, this looks strange. In fact I already
suggested the change below a long ago, but I don't remember why it
was declined (or probably it was unnoticed).

The patch below doesn't add 0x80 to ->group_exit_code in case we
really dumped the core, but at least the coredumping signal is
visible to do_wait/etc.

Oleg.

--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1550,6 +1550,7 @@ static int zap_process(struct task_struc
 	int nr = 0;
 
 	start->signal->flags = SIGNAL_GROUP_EXIT;
+	start->signal->group_exit_code = exit_code;
 	start->signal->group_stop_count = 0;
 
 	t = start;
@@ -1574,7 +1575,6 @@ static inline int zap_threads(struct tas
 	spin_lock_irq(&tsk->sighand->siglock);
 	if (!signal_group_exit(tsk->signal)) {
 		mm->core_state = core_state;
-		tsk->signal->group_exit_code = exit_code;
 		nr = zap_process(tsk);
 	}
 	spin_unlock_irq(&tsk->sighand->siglock);


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-02-04 10:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-27 20:48 CLONE_VM: parent terminates silently when child segfaults Frank Heckenbach
2010-02-04  8:01 ` Américo Wang
2010-02-04 10:50   ` Oleg Nesterov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox