odd utrace testing results on s390x
Oleg Nesterov
oleg at redhat.com
Tue Dec 22 16:22:22 UTC 2009
On 12/22, Oleg Nesterov wrote:
>
> On 12/22, caiqian at redhat.com wrote:
> >
> > and a different syscall number when syscall-from-clone failed.
>
> This is not clear to me, will take a look.
Should I say I know nothing about s390 and can't read its asm?
First of all, I think syscall-from-clone is wrong on s390 and
needs a fix,
#elif defined __s390__
# define REGISTER_CALLNO offsetof (struct user_regs_struct, orig_gpr2)
# define REGISTER_RETVAL offsetof (struct user_regs_struct, gprs[2])
This doesn't look right. I did a simple test-case (below), and
with or without utrace it prints
syscall=1234 ret=6 <----- __NR_close
syscall=1234 ret=-9 <----- -EBADF, this is correct
Apparently, 1234 is the argument for close(1234).
So: it is not clear to me how to get "callno" on SYSCALL_EXIT,
and I don't know whether it is OK or not that syscall-from-clone
sees different ->orig_gpr2 after return from fork() on s390
-unexpected syscall 0x5ee9 <---- without utrace
+unexpected syscall 0 <---- with utrace
syscall_get_nr() returns regs->svcnr, but there is no "svcnr" in
user_regs_struct on s390.
Still investigating...
Oleg.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <stddef.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <assert.h>
#include <sys/user.h>
#include <asm/ptrace.h>
#ifdef __s390__
#define REGISTER_CALLNO offsetof(struct user_regs_struct, orig_gpr2)
#define REGISTER_RETVAL offsetof(struct user_regs_struct, gprs[2])
#else
#define REGISTER_CALLNO offsetof(struct user_regs_struct, orig_rax)
#define REGISTER_RETVAL offsetof(struct user_regs_struct, rax)
#endif
int main(void)
{
int pid, status, i;
long scn, ret;
pid = fork();
if (!pid) {
assert(ptrace(PTRACE_TRACEME, 0, 0, 0) == 0);
kill(getpid(), SIGUSR1);
close(1234);
return 0x66;
}
assert(pid == wait(&status));
assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGUSR1);
assert(ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) == 0);
for (i = 0; i < 2; ++i) {
ptrace(PTRACE_SYSCALL, pid, 0,0);
assert(pid == wait(&status));
assert(status == 0x857f);
scn = ptrace(PTRACE_PEEKUSER, pid, REGISTER_CALLNO, NULL);
ret = ptrace(PTRACE_PEEKUSER, pid, REGISTER_RETVAL, NULL);
printf("syscall=%ld ret=%ld\n", scn, ret);
}
kill(pid, SIGKILL);
return 0;
}
More information about the utrace-devel
mailing list