Two test cases
Denys Vlasenko
dvlasenk at redhat.com
Mon Dec 8 15:05:07 UTC 2008
On Mon, 2008-12-08 at 14:22 +0100, Denys Vlasenko wrote:
> On Mon, 2008-12-08 at 10:40 +0800, Wenji Huang wrote:
> > Denys Vlasenko wrote:
> > > On Fri, 2008-12-05 at 11:10 +0800, Wenji Huang wrote:
> > >> There are two test cases I collected/updated those work fine
> > >> on mainline 2.6.28-rc7. But fail on 2.6.28-rc7+latest utrace patch.
>
> sigstep.c has "This testcase is part of GDB, the GNU debugger."
> comment. And gdb indeed has sigstep.c file. But it does not
> seem to have much in common with your sigstep.c.
>
> multi-step-same-time.c does not seem to be from GDB.
>
> Therefore they are not an established, known-to-work testcases
> (at least I can't find where they come from), they are just some
> C programs which work on vanilla kernel and fail on utrace.
>
> This means that they need to pass through a review before
> we can assume the problem is in utrace and not in the tests.
>
> And this means that you need to explain unclear moments,
> and tweak parts of tests where they do not seem to be doing
> the right thing(s), or are simply superfluous.
>
> At least that's how I understand the situation.
> Do you see it the same? I'm asking because you did not provide
> a tweaked (shortened?) version of sigstep.c in your reply,
> which I sort-of-expected.
> Do you want someone else to do it?
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?
--
vda
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <linux/ptrace.h>
#include <errno.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
static void
handler (int sig)
{
raise (SIGUSR2);
sig += 42; /* ensure there are some instructions prior to exit */
_exit (sig); /* not reached */
}
/* If nothing strange happens, just return 0.
* Known bugs exit with 1.
* New bugs are likely to trip asserts.
*/
int
main (int argc, char **argv)
{
pid_t pid, child;
int status;
long l;
child = fork ();
assert (child >= 0);
if (child == 0)
{
signal (SIGUSR1, handler);
l = ptrace (PTRACE_TRACEME, 0, (char *) 0, (char *) 0);
assert (l == 0);
raise (SIGSTOP);
_exit (43); /* not reached */
}
pid = waitpid (child, &status, 0);
assert (pid == child);
assert (WIFSTOPPED (status));
assert (WSTOPSIG (status) == SIGSTOP);
/* Inject SIGUSR1, unpause */
l = ptrace (PTRACE_CONT, child, (char *) 0, (char *) SIGUSR1);
assert (l == 0);
/* Expect to catch SIGUSR2 thrown from the SIGUSR1 handler */
pid = waitpid (child, &status, 0);
assert (pid == child);
assert (WIFSTOPPED (status));
assert (WSTOPSIG (status) == SIGUSR2);
/* Step one instruction after raise(SIGUSR2) in handler */
/* (do NOT reinject SIGUSR2) */
l = ptrace (PTRACE_SINGLESTEP, child, (char *) 0, (char *) 0);
assert (l == 0);
/* Expect SIGTRAP */
pid = waitpid (child, &status, 0);
assert (pid == child);
/* Known bug in 2.6.28-rc7 + utrace patch:
* child's signal handler was left to run freely, and exited */
if (WIFEXITED (status))
{
assert (WEXITSTATUS (status) == (SIGUSR1 + 42));
return 1;
}
assert (WIFSTOPPED (status));
assert (WSTOPSIG (status) == SIGTRAP);
kill (child, SIGKILL);
return 0;
}
More information about the utrace-devel
mailing list