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