linux-um archives
 help / color / mirror / Atom feed
From: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
To: Blaisorblade <blaisorblade_spam@yahoo.it>
Cc: user-mode-linux-devel@lists.sourceforge.net,
	"Jeff Dike" <jdike@addtoit.com>,
	"Roland Kaeser" <roli8200@yahoo.de>,
	"Nuno Silva" <nuno.silva@vgertech.com>,
	"Antoine Martin" <antoine@nagafix.co.uk>,
	"Sven Köhler" <skoehler@upb.de>,
	"Dennis Muhlestein" <devel@muhlesteins.com>
Subject: [uml-devel] Re: Stop at startup on 2.6 NPTL hosts
Date: Tue, 09 Nov 2004 17:42:45 +0100	[thread overview]
Message-ID: <4190F385.1000802@fujitsu-siemens.com> (raw)
In-Reply-To: <200411021952.09095.blaisorblade_spam@yahoo.it>

[-- Attachment #1: Type: text/plain, Size: 2318 bytes --]

Blaisorblade wrote:
> On Friday 29 October 2004 11:26, Roland Kaeser wrote:
> This is executed by a clone() child. What happens is that, with NPTL, both the 
> father and the son have the same pid, so the SIGSTOP is routed to the wrong 
> thread. However, this is not expected: having the same pid should be reserved 
> to when clone is called with CLONE_THREAD in the flags. I've verified that 
> this is not happening in this case, even with strace (to make sure glibc is 
> not playing any dirty tricks). But for some reasons, the kernel is behaving 
> as if this happened.
Sorry, I have to oppose. The threads don't have the same pid! Only the getpid()-
call to the lib returns the pid of the father.

I wrote a small test program (attached). Please compile it with:

    gcc -static -o test_getpid_static test_getpid.c        and
    gcc -o test_getpid_nptl test_getpid.c

Using the two programs, you can see the following:
1) having linked my test with -static, each "getpid()" in the test results in a
    syscall (try "strace test_getpid_static")
2) linking without -static (I assume, this means using NPTL), only the first
    getpid() does a syscall, I guess, the further calls deliver a pid-value
    buffered in the lib! (try "strace test_getpid_static")
The test here requests and prints out its pid twice, then it exits. But strace will
show you two getpid()-calls only in case of the _static program.

3) the pid-history seen in 1 and 2 is used even for a child created with "clone()",
    regardless which clone-flags are used! Try "test_getpid_static clone" and
    "test_getpid_nptl clone" to see, what happens.
    After printing its pid twice, the program now creates a child via "clone()". The
    child requests its *real* pid via a "by-hand-syscall". Than it stops itself and
    is ptraced by the father, which prints out a message, if the child does a *real*
    getpid()-syscall.
    Note: If you remove the two getpid()-calls at the beginning of main(), the
    child will work correctly even with NPTL, since there isn't yet a buffered pid ...

Summary: I guess, the behavior of NPTL is a bug. Do you agree? To which list should
a bugreport be mailed?
To work around, we could use the by-hand-syscall for os_getpid(). I didn't test it,
but I'm quite shure, that it fixes the problem.

Bodo

[-- Attachment #2: test_getpid.c --]
[-- Type: text/plain, Size: 2066 bytes --]

#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <asm/ptrace.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <errno.h>

char childstack[ 8*1024];


int my_getpid()
{
	long res;
	__asm__ volatile ("	int $0x80\n\t"
				: "=a" (res)
				: "0" (__NR_getpid));
	return res;
}


int
child_fn( void * unused)
{
	pid_t me = my_getpid();

	printf("Child: my PID via 'int $0x80' is %d\n", me);

	ptrace(PTRACE_TRACEME, 0, 0, 0);
	kill( me, SIGSTOP);

	printf("Child: my PID via 'getpid()' is %d\n", getpid());

	return 0;
}


int
main( int argc, char ** argv)
{
	int ret, status, suppress=0;
	pid_t child;

	printf("Parent: my PID is %d\n", getpid());
	printf("Parent: my PID is %d\n", getpid());

	if ( argc < 2 || strcmp( argv[1], "clone") )
		return 0;

	child = clone( child_fn, childstack+8*1024-4, SIGCHLD, NULL);

	if ( child < 0 ) {
		perror("clone");
		exit(1);
	}
	printf("Parent: childs PID is %d\n", child);

	do {
		ret = waitpid(child, &status, WUNTRACED);
		if(ret < 0) {
			perror("waitpid()");
			exit(1);
		}
	} while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));

	if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) {
		printf("Parent: waitpid(): expected SIGSTOP, got status = %d\n", status);
		return 1;
	}

	while (1) {
		if ( ptrace( PTRACE_SYSCALL, child, (void *)0, 0) < 0 ) {
			perror("ptrace( PTRACE_SYSCALL, child, 0, 0)");
			exit(1);
		}
		ret = waitpid( child, &status, 0);
		if ( ret != child ) {
			perror("waitpid");
			return 1;
		}
		if ( WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP ) {
			errno = 0;
			ret = ptrace( PTRACE_PEEKUSER, child, (void *)(ORIG_EAX*4), NULL);
			if ( errno ) {
				perror("ptrace( PTRACE_PEEKUSER, child, ORIG_EAX, NULL)");
				return 1;
			}
			if ( ret == __NR_getpid ) {
				if ( (suppress ^= 1) )
					printf("Parent: Child does a getpid() syscall!\n");
			}
		}
		else {
			printf("Parent: Child's status is %x: exiting\n", status);
			return (status != 0);
		}
	}
}

  parent reply	other threads:[~2004-11-09 16:48 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-29  9:26 [uml-devel] UML Kernel 2.6.7 Nothing happens Roland Kaeser
2004-11-02 18:52 ` Stop at startup on 2.6 NPTL hosts (was: Re: [uml-devel] UML Kernel 2.6.7 Nothing happens) Blaisorblade
2004-11-02 23:43   ` [uml-devel] Re: Stop at startup on 2.6 NPTL hosts Sven Köhler
2004-11-03  3:04   ` Nuno Silva
2004-11-03  8:32     ` Gerd Knorr
2004-11-03 15:59       ` Blaisorblade
2004-11-03 20:10         ` Gerd Knorr
2004-11-03 22:17           ` Blaisorblade
2004-11-04  8:40       ` Nuno Silva
2004-11-09 16:42   ` Bodo Stroesser [this message]
2004-11-09 17:29     ` Adam Heath
2004-11-09 17:32       ` Bodo Stroesser
2004-11-09 18:23         ` Bodo Stroesser
2004-11-09 19:11     ` Blaisorblade
2004-11-10  8:36       ` stian
2004-11-10  9:07         ` Geert Uytterhoeven
2004-11-10 12:15           ` Bodo Stroesser
2004-11-10 12:47             ` Geert Uytterhoeven
2004-11-10 14:32               ` Blaisorblade
2004-11-10 14:44             ` Sven Köhler
2004-11-10 21:19           ` Henrik Nordstrom
2004-11-15 17:17             ` Blaisorblade
2004-11-10 17:16         ` Blaisorblade

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4190F385.1000802@fujitsu-siemens.com \
    --to=bstroesser@fujitsu-siemens.com \
    --cc=antoine@nagafix.co.uk \
    --cc=blaisorblade_spam@yahoo.it \
    --cc=devel@muhlesteins.com \
    --cc=jdike@addtoit.com \
    --cc=nuno.silva@vgertech.com \
    --cc=roli8200@yahoo.de \
    --cc=skoehler@upb.de \
    --cc=user-mode-linux-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox