ptrace weirdness with 9.0-CURRENT

Kostik Belousov kostikbel at gmail.com
Tue Feb 8 23:49:58 UTC 2011


On Wed, Feb 09, 2011 at 12:42:15AM +0200, Ali Polatel wrote:
> Hello everyone,
> 
> I'm the developer of pinktrace - http://dev.exherbo.org/~alip/pinktrace/
> - a simple ptrace() wrapper library for FreeBSD and Linux. I have set up
> a FreeBSD-9.0-CURRENT VM today to test various new features recently
> added to ptrace(). This is about a behaviour difference between
> 8.1-RELEASE and 9.0-CURRENT which I've noticed through a unit test of
> pinktrace. I don't want to bother you with the internals of this library
> so I'll briefly explain the problem.
> 
> I've inserted the testcase I've used below. The aim is to trace a
> open(NULL, 0) call which should fail with EFAULT. Running this on two
> different VMs I get:
> 
> % uname -a
> FreeBSD  9.0-CURRENT FreeBSD 9.0-CURRENT #0: Wed Feb  9 05:02:31 EET 2011     root@:/usr/obj/usr/src/sys/GENERIC  amd64
> % sudo cat /root/world.txt
> --------------------------------------------------------------
> >>> World build completed on Wed Feb  9 00:23:30 EET 2011
> --------------------------------------------------------------
> % gcc -Wall ptrace-amd64-fbsd-return.c
> % ./a.out
> retval:0 error:0
> 
> $ uname -a
> FreeBSD  8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:36:49 UTC 2010     root at mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  amd64
> $ gcc -Wall ptrace-amd64-fbsd-return.c
> $ ./a.out
> retval:14 error:1
> $ 
> 
> Important note: I couldn't notice a problem with truss tracing a
> open(NULL, 0) call so I think this is a problem with my testcase.
> I'll be happy if you can shed some light on what I'm doing wrong here:
There is no issue with ptrace(2). Your test fails because, apparently,
rtld in HEAD calls setjmp(3) when resolving symbols, and setjmp(3)
calls sigprocmask(2). The end result is that you get SCX event for
sigprocmask, and not for your open(2).

The issue with sigprocmask call from setjmp shall be fixed, but this
is not an issue with ptrace(2).

> 
> #include <sys/types.h>
> #include <sys/ptrace.h>
> #include <sys/wait.h>
> 
> #include <machine/psl.h>
> #include <machine/reg.h>
> 
> #include <errno.h>
> #include <fcntl.h>
> #include <signal.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> 
> #undef NDEBUG
> #include <assert.h>
> 
> int
> main(void)
> {
> 	int status;
> 	pid_t pid;
> 
> 	if ((pid = fork()) < 0) {
> 		perror("fork");
> 		abort();
> 	}
> 	else if (!pid) { /* child */
> 		assert(!(ptrace(PT_TRACE_ME, 0, NULL, 0) < 0));
> 		kill(getpid(), SIGSTOP);
> 		open(NULL, 0);
> 		fprintf(stderr, "open: (errno:%d %s)\n", errno, strerror(errno));
> 		_exit(0);
> 	}
> 	else {
> 		assert(!(waitpid(pid, &status, 0) < 0));
> 		assert(WIFSTOPPED(status));
> 		assert(WSTOPSIG(status) == SIGSTOP);
> 
> 		assert(!(ptrace(PT_TO_SCX, pid, (caddr_t)1, 0) < 0));
> 		assert(!(waitpid(pid, &status, 0) < 0));
> 		assert(WIFSTOPPED(status));
> 		assert(WSTOPSIG(status) == SIGTRAP);
> 
> #if defined(PT_LWPINFO) && defined(PL_FLAG_SCX)
> 		struct ptrace_lwpinfo info;
> 		assert(!(ptrace(PT_LWPINFO, pid, (caddr_t)&info, sizeof(struct ptrace_lwpinfo)) < 0));
> 		assert(info.pl_flags & PL_FLAG_SCX);
> #endif
> 
> 		struct reg r;
> 		assert(!(ptrace(PT_GETREGS, pid, (caddr_t)&r, 0) < 0));
> 
> 		printf("retval:%ld error:%d\n", r.r_rax, !!(r.r_rflags & PSL_C));
> 
> 		ptrace(PT_CONTINUE, pid, (caddr_t)1, 0);
> 		waitpid(pid, &status, 0);
> 
> 		return 0;
> 	}
> }
> 
> -- 
> Regards,
> Ali Polatel


-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20110208/b8fb5770/attachment.pgp


More information about the freebsd-hackers mailing list