Ability to tell the difference between normal and syscall traps

Ali Polatel alip at exherbo.org
Sun May 9 18:28:56 UTC 2010


Kostik Belousov yazmış:
> On Sun, May 09, 2010 at 08:33:03AM +0300, Ali Polatel wrote:
> > Kostik Belousov yazm??:
> > > On Sat, May 08, 2010 at 02:15:09PM +0300, Ali Polatel wrote:
> > > > Does FreeBSD's ptrace have a way to tell the difference between normal
> > > > traps and those caused by a system call?
> > > > 
> > > > On Linux? this is possible by passing PTRACE_O_TRACESYSGOOD option to the
> > > > ptrace request PTRACE_SETOPTIONS which makes the kernel set bit 7 in the
> > > > syscall number when delivering system call traps,
> > > > (i.e., deliver (SIGTRAP | 0x80)).
> > > > 
> > > > I'm not sure if this is possible on FreeBSD. PT_LWPINFO request looks
> > > > related but can't be sure.
> > > > 
> > > > ?: http://linux.die.net/man/2/ptrace
> > > 
> > > There is already procfs(5)-based interface to get a reason for stop.
> > > Look at the ioctl PIOCSTATUS. Yes, you have to mount procfs.
> > > 
> > > The interface can be lifted to ptrace(2), but I think using the capacity
> > > of procfs is not wrong there.
> > 
> > Hmm ok, I've been playing around with PIOCSTATUS but it doesn't seem to
> > work, there's not much documentation about it either so I figured I'll
> > just ask.
> > 
> > The code is here: http://alip.github.com/code/piocstatus.c
> > 
> > The traced child is stopped at the beginning of a system call. I await
> > that the PIOCSTATUS request sets ps.why to S_SCE but it's always zero.
> > Can you help me figure out what I'm doing wrong? :)
> 
> Apparently I missed the fact that S_PT_SCE and S_SCE are different
> flags. It seems you have to use procfs stop events (PIOCBIS) and
> procfs-based loop to get p_step set to 1.

So I can't use ptrace() together with ioctl() based tracing.
Fair enough...

I'm trying to write the ioctl() based equivalent of what I've started
but I can't figure out how to start tracing by forking a new child.

Here's how I do it on Linux:
fork()
 child: call kill(getpid(), SIGSTOP) and wait for the parent to resume.
 parent: wait for the child, set up tracing options and start tracing.

I can directly use execve() so the child will stop too but I'm writing a
library and for its unit tests I need to use the SIGSTOP method because
I won't do any exec'ing.

I tried to do the same with ioctl(), it works most of the time but it
hangs every now and then at PIOCWAIT. I'm inclined to think there's a
race condition but I couldn't figure out why.

The code is here: http://alip.github.com/code/piocstatus-2.c

Fwiw this is about a library called
pinktrace(http://dev.exherbo.org/~alip/pinktrace) I'm trying to write.
Its aim is to be a lightweight portable tracing library with multiple
backends (like procfs and ptrace etc.) I think this could prove useful
for many people who need to do tracing and doesn't want to bother with
platform specific details.

-- 
Regards,
Ali Polatel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20100509/bb6e6499/attachment.pgp


More information about the freebsd-hackers mailing list