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
        [EMAIL PROTECTED]
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) {
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to