Re: More waitpid issues with CLONE_DETACHED/CLONE_THREAD

From: Davide Libenzi
Date: Sun Feb 01 2004 - 21:43:22 EST


On Sun, 1 Feb 2004, Daniel Jacobowitz wrote:

> On Sun, Feb 01, 2004 at 01:41:48PM -0800, Linus Torvalds wrote:
> >
> >
> > On Sun, 1 Feb 2004, Daniel Jacobowitz wrote:
> > >
> > > Here you go. The bug turns out not to be related directly to
> > > CLONE_DETACHED. Compile testcase with -DNOTHREAD to use fork (well,
> > > clone, but without the fancy flags), without -DNOTHREAD to use
> > > CLONE_DETACHED | CLONE_THREAD.
> >
> > I don't think this bug has anything to do with anything else.
> >
> > This program seems to show that PTRACE_KILL simply doesn't work.
>
> > and the thing is, it looks like the signal handling changes have totally
> > made the child ignore the "exit_code" thing, unless I'm seriously
> > misreading something.
>
> That may be (though I don't think so) but it reproduces without
> PTRACE_KILL too. Try the attached, which just replaced PTRACE_KILL
> with PTRACE_CONT/tkill(pid, SIGKILL). Still get zombies. I haven't
> tried reproducing entirely without ptrace yet.

Here w/out ptrace works as advertised.



- Davide




/* -DBUG to kill the parent before the child -> hang. */
/* -DNOTHREAD to us fork instead of clone. */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <signal.h>
#include <sched.h>
#include <errno.h>
#include <sys/wait.h>


int stack_one[8192], stack_two[8192];
int fds1[2], fds2[2];


int thread_func_two()
{

fprintf(stdout, "Thread 2: ppid = %d\n", getppid());
while (1) {
sleep (1);
fprintf(stdout, "Thread 2: ppid = %d\n", getppid());
}
}

int thread_func_one()
{
int ret;

fprintf(stdout, "Thread 1\n");

read(fds1[0], &ret, sizeof(int));

fprintf(stdout, "Thread 1 cloning\n");

ret = clone (thread_func_two, stack_two + 8192,
#ifdef NOTHREAD
SIGCHLD,
#else
CLONE_DETACHED | CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_FS,
#endif
NULL);

fprintf(stdout, "child2 = %d\n", ret);

write(fds2[1], &ret, sizeof(int));

fprintf(stdout, "Thread 1 sleeping\n");
while (1)
sleep (1);
}

int main()
{
int ret, wstat, child, child2;

if (pipe(fds1) < 0 || pipe(fds2)) {
perror("pipe");
return 1;
}

child = fork();
if (child == 0)
return thread_func_one();

fprintf(stdout, "child = %d\n", child);

write(fds1[1], &child, sizeof(int));
read(fds2[0], &child2, sizeof(int));

fprintf(stdout, "parent got child2 = %d\n", child2);

#ifndef BUG
kill(child2, SIGKILL);
ret = waitpid (child2, &wstat, __WALL);
fprintf(stdout, "waitpid(%d) = %d (%s)\n", child2, ret, strerror(errno));
#endif

kill(child, SIGKILL);
ret = waitpid (child, &wstat, __WALL);
fprintf(stdout, "waitpid(%d) = %d (%s)\n", child, ret, strerror(errno));

#ifdef BUG
sleep(2);

kill(child2, SIGKILL);
ret = waitpid (child2, &wstat, __WALL);
fprintf(stdout, "waitpid(%d) = %d (%s)\n", child2, ret, strerror(errno));
#endif

return 0;
}



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/