truss problems
Dan Nelson
dnelson at allantgroup.com
Tue Apr 11 15:52:52 UTC 2006
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 at allantgroup.com
-------------- next part --------------
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) {
More information about the freebsd-stable
mailing list