Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Apr 2006 10:52:51 -0500
From:      Dan Nelson <dnelson@allantgroup.com>
To:        Jonas Wolz <jonas.wolz@freenet.de>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: truss problems
Message-ID:  <20060411155250.GB4297@dan.emsphone.com>
In-Reply-To: <200604111521.15572.jonas.wolz@freenet.de>
References:  <200604101145.26621.jonas.wolz@freenet.de> <200604111521.15572.jonas.wolz@freenet.de>

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

--r5Pyd7+fXNt84Ff3
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

In the last episode (Apr 11), Jonas Wolz said:
> Am Montag, 10. April 2006 11:45 schrieb Jonas Wolz:
> > Other applications I tested (xedit, bash) seem to work fine.
> 
> I've made some more tests and it seems to me that the "fork
> following" feature (-f switch) of truss obviously is buggy. Even the
> following simple shell script sometimes (in about a third of the
> tests) provokes the bug:

> -- begin test.sh
> #!/bin/sh
> /bin/echo Test
> /bin/echo Test
> -- end test.sh
> 
> If I call "truss -f sh test.sh" I get errors when execve() is called
> to start /bin/echo, for example: (56179 is the first /bin/echo
> (started without error), 56178 is /bin/sh)

I think this is because truss immediately tries to attach to the child
process after the fork, and if it isn't completely set up, things like
ioctl(PIOCWAIT) and opening /proc/*/mem will fail.  Try the attached
patch (for 5.*, but should apply to newer versions).

-- 
	Dan Nelson
	dnelson@allantgroup.com

--r5Pyd7+fXNt84Ff3
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="truss.diff"

Index: setup.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/truss/setup.c,v
retrieving revision 1.19.2.1
diff -u -r1.19.2.1 setup.c
--- setup.c	26 May 2005 21:26:00 -0000	1.19.2.1
+++ setup.c	27 Jan 2006 23:19:43 -0000
@@ -71,6 +71,7 @@
 	int fd;
 	int pid;
 	int flags;
+	int loop;
 
 	pid = fork();
 	if (pid == -1) {
@@ -108,15 +109,33 @@
 	}
 
 	sprintf(buf, "/proc/%d/mem", pid);
-	if ((fd = open(buf, O_RDWR)) == -1)
-		err(5, "cannot open %s", buf);
-	if (ioctl(fd, PIOCWAIT, &pfs) == -1)
-		err(6, "PIOCWAIT");
-	if (pfs.why == S_EXIT) {
-		warnx("process exited before exec'ing");
-		ioctl(fd, PIOCCONT, 0);
-		wait(0);
-		exit(7);
+
+	/* try 6 times to trace our child, waiting 1/2 second each time */
+	for (loop=6 ;; loop--)
+	{
+		if (loop != 6)
+			usleep(500000);
+		if ((fd = open(buf, O_RDWR)) == -1)
+		{
+			if (loop > 0)
+				continue;
+			else
+				err(5, "cannot open1 %s", buf);
+		}
+		if (ioctl(fd, PIOCWAIT, &pfs) == -1)
+		{
+			if (loop >= 0)
+				continue;
+			else
+				err(6, "PIOCWAIT");
+		}
+		if (pfs.why == S_EXIT) {
+			warnx("process exited before exec'ing");
+			ioctl(fd, PIOCCONT, 0);
+			wait(0);
+			exit(7);
+		} else
+			break;
 	}
 	close(fd);
 	return (pid);
@@ -136,6 +155,7 @@
 	struct procfs_status tmp;
 
 	sprintf(buf, "/proc/%d/mem", pid);
+	usleep(500000);
 
 	fd = open(buf, O_RDWR);
 	if (fd == -1) {
@@ -146,7 +166,7 @@
 		 */
 		if (!failisfatal && kill(pid, 0) == -1)
 			return (-1);
-		err(8, "cannot open %s", buf);
+		err(8, "cannot open2 %s", buf);
 	}
 
 	if (ioctl(fd, PIOCSTATUS, &tmp) == -1) {

--r5Pyd7+fXNt84Ff3--



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