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     
> 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:
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


Attachment: pgpF6KEnGyLRP.pgp
Description: PGP signature

Reply via email to