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
[-- Attachment #1 --]
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
[-- Attachment #2 --]
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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060411155250.GB4297>
