Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 May 2010 13:35:00 +0300
From:      Ali Polatel <alip@exherbo.org>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: Ability to tell the difference between normal and syscall traps
Message-ID:  <20100511103500.GH8186@harikalardiyari>
In-Reply-To: <20100510170947.GP83316@deviant.kiev.zoral.com.ua>
References:  <20100508111509.GB8186@harikalardiyari> <20100508123626.GC83316@deviant.kiev.zoral.com.ua> <20100509053303.GD8186@harikalardiyari> <20100509135807.GH83316@deviant.kiev.zoral.com.ua> <20100509182851.GE8186@harikalardiyari> <20100509214359.GJ83316@deviant.kiev.zoral.com.ua> <20100510164847.GF8186@harikalardiyari> <20100510170947.GP83316@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help

--w2JjAQZceEVGylhD
Content-Type: text/plain; charset=iso-8859-9
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Kostik Belousov yazm=FD=FE:
> On Mon, May 10, 2010 at 07:48:47PM +0300, Ali Polatel wrote:
> > Kostik Belousov yazm??:
> > > On Sun, May 09, 2010 at 09:28:51PM +0300, Ali Polatel wrote:
> > > > 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 bet=
ween normal
> > > > > > > > traps and those caused by a system call?
> > > > > > > >=20
> > > > > > > > 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)).
> > > > > > > >=20
> > > > > > > > I'm not sure if this is possible on FreeBSD. PT_LWPINFO req=
uest looks
> > > > > > > > related but can't be sure.
> > > > > > > >=20
> > > > > > > > ?: http://linux.die.net/man/2/ptrace
> > > > > > >=20
> > > > > > > There is already procfs(5)-based interface to get a reason fo=
r stop.
> > > > > > > Look at the ioctl PIOCSTATUS. Yes, you have to mount procfs.
> > > > > > >=20
> > > > > > > The interface can be lifted to ptrace(2), but I think using t=
he capacity
> > > > > > > of procfs is not wrong there.
> > > > > >=20
> > > > > > 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 figur=
ed I'll
> > > > > > just ask.
> > > > > >=20
> > > > > > The code is here: http://alip.github.com/code/piocstatus.c
> > > > > >=20
> > > > > > 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 alway=
s zero.
> > > > > > Can you help me figure out what I'm doing wrong? :)
> > > > >=20
> > > > > 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.
> > > >=20
> > > > So I can't use ptrace() together with ioctl() based tracing.
> > > > Fair enough...
> > > >=20
> > > > I'm trying to write the ioctl() based equivalent of what I've start=
ed
> > > > but I can't figure out how to start tracing by forking a new child.
> > > >=20
> > > > Here's how I do it on Linux:
> > > > fork()
> > > >  child: call kill(getpid(), SIGSTOP) and wait for the parent to res=
ume.
> > > >  parent: wait for the child, set up tracing options and start traci=
ng.
> > > >=20
> > > > I can directly use execve() so the child will stop too but I'm writ=
ing a
> > > > library and for its unit tests I need to use the SIGSTOP method bec=
ause
> > > > I won't do any exec'ing.
> > > >=20
> > > > 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.
> > > >=20
> > > > The code is here: http://alip.github.com/code/piocstatus-2.c
> > > >=20
> > > > Fwiw this is about a library called
> > > > pinktrace(http://dev.exherbo.org/~alip/pinktrace) I'm trying to wri=
te.
> > > > Its aim is to be a lightweight portable tracing library with multip=
le
> > > > backends (like procfs and ptrace etc.) I think this could prove use=
ful
> > > > for many people who need to do tracing and doesn't want to bother w=
ith
> > > > platform specific details.
> > >=20
> > > I see. You could try this patch. It requires HEAD or recent RELENG_8
> > > to be applicable. I added PL_EVENT_SCE/SCX to PT_LWPINFO for i386 and
> > > amd64. Please note that I did not tested it, only booted the kernel to
> > > make sure that it does not break too ugly.
> > >=20
> > > diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
> > > index f3dba94..f97f875 100644
> > <snip the nice patch>
> >=20
> > Looks great, I could only test it basically but it seems to work fine.
> > If this is merged, truss can make use of this too.
> >=20
> > Another question is how hard is it to implement PL_EVENT_EXEC?
> > This could be useful for truss as it updates the execution type of the
> > process after successful execve() calls afaict.
>=20
> Is this needed ? The question is not rhetorical, I am trying to
> understand what prevents use of PT_TO_SCE and checking the syscall
> number ? You would screen for SYS_execve or SYS_fexecve and
> reset the debugger state on SIGTRAP that is supplied to the debugger
> before first instruction of new image is executed.
>=20

Not really needed, just cleaner imo. As system call numbers may be
different for different execution types and you need to look it up from
a table using a string as argument which is slow.

> Can you, please, extract and provide me with the code you used to test
> the PL_EVENT_SCE/SCX patch ?

Sure, the code is below. It doesn't work though (Sorry to tell you it
was working fine in my first post, too much vodka makes me see things
differently as it seems). The PT_LWPINFO request returns
PL_EVENT_SIGNAL in both cases.

<code>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>

#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

int
main(void)
{
	int status;
	pid_t pid;
	struct ptrace_lwpinfo lwpinfo;

	if ((pid =3D fork()) < 0) {
		perror("fork");
		return 1;
	}
	else if (!pid) { /* child */
		if (ptrace(PT_TRACE_ME, 0, NULL, 0) < 0) {
			perror("PT_TRACE_ME");
			_exit(1);
		}
		kill(getpid(), SIGSTOP);
		getpid();
	}
	else { /* parent */
		waitpid(pid, &status, 0);
		assert(WIFSTOPPED(status));
		assert(WSTOPSIG(status) =3D=3D SIGSTOP);

		if (ptrace(PT_TO_SCE, pid, (caddr_t)1, 0) < 0) {
			perror("PT_TO_SCE");
			ptrace(PT_KILL, pid, NULL, 0);
			return 2;
		}

		waitpid(pid, &status, 0);
		assert(WIFSTOPPED(status));
		assert(WSTOPSIG(status) =3D=3D SIGTRAP);

		if (ptrace(PT_LWPINFO, pid, (caddr_t)&lwpinfo, sizeof lwpinfo) < 0) {
			perror("PT_LWPINFO");
			ptrace(PT_KILL, pid, NULL, 0);
			return 3;
		}
		printf("event =3D %d\n", lwpinfo.pl_event);
		assert(lwpinfo.pl_event =3D=3D PL_EVENT_SCE);

		if (ptrace(PT_TO_SCX, pid, (caddr_t)1, 0) < 0) {
			perror("PT_TO_SCX");
			ptrace(PT_KILL, pid, NULL, 0);
			return 2;
		}

		waitpid(pid, &status, 0);
		assert(WIFSTOPPED(status));
		assert(WSTOPSIG(status) =3D=3D SIGTRAP);

		if (ptrace(PT_LWPINFO, pid, (caddr_t)&lwpinfo, sizeof lwpinfo) < 0) {
			perror("PT_LWPINFO");
			ptrace(PT_KILL, pid, NULL, 0);
			return 3;
		}
		printf("event =3D %d\n", lwpinfo.pl_event);
		assert(lwpinfo.pl_event =3D=3D PL_EVENT_SCX);

		ptrace(PT_CONTINUE, pid, (caddr_t)1, 0);
		return 0;
	}
}

--=20
Regards,
Ali Polatel

--w2JjAQZceEVGylhD
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)

iEYEABECAAYFAkvpMtQACgkQQU4yORhF8iBX+QCeIva6aIHa4Ne/x3h0XQDodTy+
IckAnjAcWdsZaDJ1BmiGrg3V5JMo9hpW
=RhTe
-----END PGP SIGNATURE-----

--w2JjAQZceEVGylhD--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100511103500.GH8186>