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