Hi,

When I tried the latest utrace patch to 2.6.25-rc6, found there is one regression about waitid. It passed in upstream kernel, but hang in utrace-patched kernel. The test case was old one and carried in previous kernel test. Roland once fixed the problem in http://kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.23.8.

It seems the second wait makes the kernel enter into infinite loop.

Regards,
Wenji


#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>

#include <linux/ptrace.h>

#include <errno.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define WAITOPTS WEXITED | WSTOPPED | WCONTINUED

#define SYSASSERT(_expr)					\
	if ((_expr) < 0) {					\
		fprintf (stderr, "assertion error: %s: %s\n",	\
			 #_expr, strerror (errno));		\
		abort ();					\
	}

void
print_siginfo (siginfo_t *info)
{
	printf ("  si_pid: %d\n", info->si_pid);
	printf ("  si_uid: %d\n", info->si_uid);
	printf ("  si_signo: %d\n", info->si_signo);
	printf ("  si_status: %d (%d %d)\n", info->si_status,
		info->si_status & 0x7f, info->si_status >> 8);
	if ((info->si_status >> 8) == 1)
		printf ("    PTRACE_EVENT_FORK\n");
	if ((info->si_status >> 8) == 4)
		printf ("    PTRACE_EVENT_EXEC\n");
	switch (info->si_code) {
	case CLD_EXITED:
		printf ("  si_code: CLD_EXITED\n");
		break;
	case CLD_KILLED:
		printf ("  si_code: CLD_KILLED\n");
		break;
	case CLD_STOPPED:
		printf ("  si_code: CLD_STOPPED\n");
		break;
	case CLD_CONTINUED:
		printf ("  si_code: CLD_CONTINUED\n");
		break;
	case CLD_DUMPED:
		printf ("  si_code: CLD_DUMPED\n");
		break;
	case CLD_TRAPPED:
		printf ("  si_code: CLD_TRAPPED\n");
		break;
	default:
		printf ("  si_code: %d\n", info->si_code);
	}
}


int
main (int   argc,
      char *argv[])
{
	pid_t     pid;
	siginfo_t info;

	pid = fork ();
	assert (pid >= 0);

	if (pid == 0) {
		printf ("child %d\n", getpid ());
		fflush (stdout);

		SYSASSERT (ptrace (PTRACE_TRACEME, 0, NULL, NULL));

		printf ("ptrace_traceme set\n");
		fflush (stdout);

		raise (SIGSTOP);

		printf ("child exited\n");
		fflush (stdout);
		exit (0);
	}

	printf ("wait for process to stop\n");
	SYSASSERT (waitid (P_PID, pid, &info, WAITOPTS | WNOWAIT));
	print_siginfo (&info);
	fflush (stdout);

	SYSASSERT (waitid (P_PID, pid, &info, WAITOPTS));

	printf ("set ptrace options\n");
	fflush (stdout);

	SYSASSERT (ptrace (PTRACE_SETOPTIONS, pid, NULL,
			   PTRACE_O_TRACESYSGOOD));
	SYSASSERT (ptrace (PTRACE_CONT, pid, NULL, SIGCONT));

	printf ("wait for process to exit\n");
	SYSASSERT (waitid (P_PID, pid, &info, WAITOPTS));
	print_siginfo (&info);
	fflush (stdout);

	return 0;
}

Reply via email to