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

Attachment: pgpONSeO5ohHN.pgp
Description: PGP signature

Reply via email to