Two test cases

Denys Vlasenko dvlasenk at redhat.com
Mon Dec 8 15:42:23 UTC 2008


On Mon, 2008-12-08 at 16:05 +0100, Denys Vlasenko wrote:
> I built 2.6.28-rc7 + utrace and sigstep.c indeed fails.
> 
> Here is the shortened version of sigstep.c.
> Looks like when we PTRACE_SINGLESTEP after raise (SIGUSR2),
> the child is left to run freely.
> 
> (Sorry about GNU indent style... utrace-tests requires that)
> 
> Can you confirm that it also fails for you on 2.6.28-rc7 + utrace
> but works on vanilla 2.6.28-rc7?

Please also test simplified version of the second test,
see below.

It appears that PTRACE_SINGLESTEP is a culprit here too,
no need to play with signals as in previous test,
it happens without any signals.

It also does not require many single-steps or forks,
for me it happens on the very first iteration.
(I removed the part which makes lots of forks).
--
vda



#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>

static pid_t child;

static void
cleanup (void)
{
  if (child > 0)
    kill (child, SIGKILL);
  child = 0;
  while (waitpid (-1, NULL, __WALL) > 0)
    continue;
}

static void
handler_fail (int signo)
{
  cleanup ();
  signal (SIGABRT, SIG_DFL);
  assert (0);
}

#define NUM_SINGLESTEPS 1
//#define NUM_SINGLESTEPS 10000
//#define NUM_FORKS	1

int main(int argc, char **argv)
{
	int i, status;
	pid_t pid;

	setbuf (stdout, NULL);
	atexit (cleanup);
	signal (SIGABRT, handler_fail);
	signal (SIGINT, handler_fail);
	signal (SIGALRM, handler_fail);
	alarm (5);

	child = fork();
	assert (child >= 0);
	if (child == 0) {
		/* child process */
		/* endless loop for singlestepping */
		while (!(child & 1))
			child += 2;
		_exit(43); /* not reached */
	}

	errno = 0;
	ptrace(PTRACE_ATTACH, child, (void *)0, (void *)0);
	assert(!errno);
	pid = waitpid(child, &status, 0);
	assert (pid == child);
	assert (WIFSTOPPED (status));
	assert (WSTOPSIG (status) == SIGSTOP);

	for (i = 0; i < NUM_SINGLESTEPS; i++) {
		ptrace(PTRACE_SINGLESTEP, child, (void *)0, (void *)0);
		assert(!errno);
		/* Known bug in 2.6.28-rc7 + utrace patch:
		 * waitpit will block, child is running freely in an endless loop */
		pid = waitpid(child, &status, 0);
		assert (pid == child);
		assert (WIFSTOPPED (status));
		assert (WSTOPSIG (status) == SIGTRAP);
	}
	cleanup();
	return 0;
}





More information about the utrace-devel mailing list