ptrace weirdness with 9.0-CURRENT

Ali Polatel alip at exherbo.org
Tue Feb 8 22:57:10 UTC 2011


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:

#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: 197 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20110208/b4cbcc47/attachment.pgp


More information about the freebsd-hackers mailing list