[dtrace-discuss] Dtrace "fork()-o-meter" ...
Roland Mainz
roland.mainz at nrubsig.org
Sat Jan 13 13:51:15 PST 2007
Chip Bennett wrote:
> Chip Bennett wrote:
> > The errors you're getting from your example, I think are just from the
> > shell not parsing the quotes the way you expect, when DTrace invokes
> > the command. If you're thinking that your bash script is supposed to
> > display all of the arguments from the command line (it appears that's
> > what's intended), when I tried:
> >
> > /bin/bash -c 'i=0 ; while [ $i -lt 100 ] ; do i=$(echo $((i + 1)) ) ;
> > done' xxx yyy zzz
> >
> >
> > at the shell prompt (without DTrace), it didn't work there either. No
> > syntax errors, but also no echos.
> Roland,
>
> I see: the '((...))' syntax is like '[...]', only the expression result
> is reversed. And somehow the ((...)) mechanism causes a fork, so the
> loop forks 100 times. My bad: I wasn't familiar with the syntax.
$(( ... )) is used for math stuff in ksh93 and bash. The idea of my loop
is to trick the shells into something like a "fork() as mad as you
can"-loop. Depending on the shell you may see between 200 (if both $(
... ) and (( ... )) fork children) and 0 child processes (bash3 does
100, ksh93 does 0 (ksh93 has some nice optimisations to avoid any
|fork()|s unless it's absolutely unavoidable)).
> So your original command was:
>
> '/bin/bash -c "i=0 ; while [ $i -lt 100 ] ; do i=$(echo $((i +
> 1)) ) ; done"'
>
> I ran the following DTrace script (called ex.d):
>
> proc:::exec-success
> {
> trace(curpsinfo->pr_argc);
> trace(curpsinfo->pr_psargs);
> }
>
> And then in another window ran:
>
> dtrace -s fom.d -c '/bin/bash -c "i=0 ; while [ $i -lt 100 ] ; do
> i=$(echo $((i + 1)) ) ; done"'
>
> "fom.d" is what I call my version of fork-o-meter, which looks like this:
>
> #pragma D option quiet
> syscall::*fork*:entry
Note that just catching |fork()| is not enougth since some shells may
use newer ways to spawn children (like |posix_spawn()| (if available and
correctly working)).
> / progenyof ($target) /
> {
> total++;
> }
> END
> {
> printf ("Total forks %d\n", total);
> }
>
> This is the trace output I got from each script:
>
> ------ fom.d:
> ;: -c: line 0: unexpected EOF while looking for matching `"'
> ;: -c: line 1: syntax error: unexpected end of file
> Total forks 0
>
> ------ ex.d
> 0 20049 exec_common:exec-success 5 dtrace -s fom.d
> -c /bin/bash -c "i=0 ; while [ $i -lt 100 ] ; do i=$(echo $((i
> 0 20049 exec_common:exec-success 5 dtrace -s fom.d
> -c /bin/bash -c "i=0 ; while [ $i -lt 100 ] ; do i=$(echo $((i
> 0 20049 exec_common:exec-success 19 /bin/bash -c "i=0
> ; while [ $i -lt 100 ] ; do i=$(echo $((i + 1)) ) ; done"
>
> So pr_argc is the right value for the first two execs, because the bash
> script string should be getting passed as one long argument. However,
> it appears that DTrace is ignoring the quotes and breaking up the
> command line into 19 whitespace delimited arguments. So bash isn't
> receiving the string as one long argument.
Grumpf... ten curses into the direction of the person who designed
"dtrace"'s "-c" option like that... xx@@@!!!... ;-(
... we can't change "-c" to work like in all other shells, e.g.
-- snip --
-c If the -c option is present then commands are read
from the first arg. Any remaining arguments
become position parameters starting at 0 .
-- snip --
(this is from the ksh93 manual page), right ?
> I think I understand why the DTrace authors did it this way
> (mind-reading switch ON :-) ). Other commands that get passed a
> second command (like truss) can handle this because everything after the
> truss options is part of the second command. However, DTrace also has
> to deal with a variable number of arguments to the D program itself.
Usual workaround (for shells) is to provide an EOF (or better:
end-of-arguments) marker (and treat all arguments after this marker as
"normal" ones again). This solution could be used for both the argument
list after "-c" and the arguments passed to the Dtrace script. But I
guess we can't fix that anymore and now have to live with this
xx@@@!!!... ;-(
> As a work-around, in the case of the bash script, you could put the
> script in a file.
Yes and no. It will not work for interactive shells... ;-(
> But what if I had an application with a command line
> argument that had to have an embedded space? At present, is there any
> other way to pass whitespace through DTrace to the -c invoked command?
AFAIK no. Sounds like a "bug" for me... and I even guess we'll have to
suffer from that for all eternity because it's kept around for
backwards-compatibility reasons... ;-(
... however if soneone wants to fix this please either get "-c" working
as used in a POSIX shell or pass the whole string (command+arguments) to
the |system()| call and let it parse the arguments (this should avoid
another row of nasty suprises with things like ${IFS}&co.).
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 7950090
(;O/ \/ \O;)
More information about the dtrace-discuss
mailing list