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 r...@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: #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
pgpONSeO5ohHN.pgp
Description: PGP signature