On 12/22, Oleg Nesterov wrote: > > On 12/22, caiq...@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; }