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