i am a newbie to solaris... can i use if/else/for/while in dtrace script? i see these are key words in dtrace, but when using it dtrace show syntax error... i find through the doc and many examples , can''t find same right syntax... dtrace support this or not ? thanks.... -- This message posted from opensolaris.org
Dan McDonald
2008-Jun-04 13:29 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
On Wed, Jun 04, 2008 at 05:31:11AM -0700, ?? wrote:> i am a newbie to solaris... > > can i use if/else/for/while in dtrace script?for/while ---> Definitely not. As for if/else, D scripts have a boolean you can you per-probe: ip_drop_packet:entry /arg1 == 1/ { printf("IPsec dropped an inbound packet."); } ip_drop_packet:entry /arg1 == 0/ { printf("IPsec dropped an outbound packet."); } Or you can use C''s bool ? true-expr : false-expr syntax: ip_drop_packet:entry { printf("IPsec dropped an %s packet.", arg1 ? "inbound" : "outbound"); } I picked a dinky example, but you can use these more powerfully. Dan
Christophe Kalt
2008-Jun-04 13:58 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
No, see http://docs.sun.com/app/docs/doc/817-6223/chp-typeopexpr-10?a=view -- This message posted from opensolaris.org
Christophe Kalt
2008-Jun-04 14:07 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
No, see http://docs.sun.com/app/docs/doc/817-6223/chp-typeopexpr-10?a=view (Weird, i thought i''d replied already, but my reply seems to be gone?!) -- This message posted from opensolaris.org
James Carlson
2008-Jun-04 14:12 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
Christophe Kalt writes:> No, see http://docs.sun.com/app/docs/doc/817-6223/chp-typeopexpr-10?a=viewThe lack of for/while/goto is an intentional omission in the interest of safety. If/else, though, is another matter. You can easily translate any if/else combination into a series of probes. For example, the following is invalid: fbt:foo:bar:entry /arg0 == 1234/ { trace(arg1); if (arg2 == 5678) trace(arg2); else trace(arg3); } But you can do something like this, and it''s equivalent: fbt:foo:bar:entry /arg0 == 1234/ { trace(arg1); self->test = arg2; } fbt:foo:bar:entry /arg0 == 1234 && self->test == 5678/ { trace(arg2); } fbt:foo:bar:entry /arg0 == 1234 && self->test != 5678/ { trace(arg3); } You can string together sets of probes to get the same effect as any set of if/else statements. (It''d sort of be nice to have direct support in the language for if/else, given the inherent safety and the obvious equivalence ...) -- James Carlson, Solaris Networking <james.d.carlson at sun.com> Sun Microsystems / 35 Network Drive 71.232W Vox +1 781 442 2084 MS UBUR02-212 / Burlington MA 01803-2757 42.496N Fax +1 781 442 1677
Chip Bennett
2008-Jun-04 15:55 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
I explain a lot of why D scripts don''t allow flow control constructs in footnote 1 of this article: http://www.laurustech.com/tech_paper.asp?ID=102. There is also some discussion of how to get the effects of flow control without real flow control. However, I''ll summarize here. The reason for no looping is because probe clauses run as kernel threads with interrupts turned off. If a loop became long, or even worse, infinite, your system would be hosed. The reason for no if/else construct (and another reason for no loops) is because each probe clause must produce a fixed length trace record. If a probe clause generates a 300 byte trace record the first time it is executed, it must always produce a 300 byte trace record. Flow control statements could contain trace or printf actions that could be repeated a variable number of times and break the fixed length rule. But as someone else pointed out, you can break up the clause into multiple clauses with different predicates. (You could even do a kind of loop this way, as long as you know the maximum number of passes. If the max was 100, you would have 100 clauses, and the predicates would control how many would actually execute on a particular pass.) So the next thing you might ask is how come conditional operators (? :) are allowed? Answer: You can''t have a trace/printf actions inside an expression, so there''s no harm. Also, since strings can vary in length, you might ask how does that jive with a fixed length record? Answer: The storage used by a string is actually fixed to the strings max length, which by default is 256. So when you trace a string, it uses 256 byte in the trace record, no matter how long the current length. So, here are the ways that I know to "simulate" flow control: 1) Break the probe clause into multiple clauses with different predicates. 2) Use the -C flag on the dtrace command line to invoke the C preprocessor, and use cpp conditional statements in your D script. 3) Use the conditional operator (logical-exp ? true-value : false-value) 4) Drive your D script using a shell script, calling the D script a multiple/variable number of times, and/or using shell variables in your D script. Chip> -----Original Message----- > From: dtrace-discuss-bounces at opensolaris.org [mailto:dtrace-discuss- > bounces at opensolaris.org] On Behalf Of ?? > Sent: Wednesday, June 04, 2008 7:31 AM > To: dtrace-discuss at opensolaris.org > Subject: [dtrace-discuss] can i use if/else/for/while in dtrace script? > > i am a newbie to solaris... > > can i use if/else/for/while in dtrace script? > > i see these are key words in dtrace, but when using it dtrace show > syntax error... > > i find through the doc and many examples , can''t find same right > syntax... > > dtrace support this or not ? > > thanks.... > > > -- > This message posted from opensolaris.org > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org
Chip Bennett
2008-Jun-04 16:22 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
One more good one. The printf action in DTrace supports variable length format items. You know, the ones where an integer variable defines the length of the field at run time. Example: BEGIN { x = 10; printf ("%*d", x, 123); } This prints the integer 123 in a field width of 10. Since "x" can vary in value, how does this work in an environment where the trace record has to be fixed. This works because DTrace doesn''t record the result of the printf in a trace record: it records the arguments in the printf action (a string and two integers), which are all fixed length. These trace records are later picked up by the dtrace command that is running safely in userland, where the printf is expanded/decoded and the results displayed. Chip You might ask how that works in a environment where the> -----Original Message----- > From: dtrace-discuss-bounces at opensolaris.org [mailto:dtrace-discuss- > bounces at opensolaris.org] On Behalf Of ?? > Sent: Wednesday, June 04, 2008 7:31 AM > To: dtrace-discuss at opensolaris.org > Subject: [dtrace-discuss] can i use if/else/for/while in dtrace script? > > i am a newbie to solaris... > > can i use if/else/for/while in dtrace script? > > i see these are key words in dtrace, but when using it dtrace show > syntax error... > > i find through the doc and many examples , can''t find same right > syntax... > > dtrace support this or not ? > > thanks.... > > > -- > This message posted from opensolaris.org > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org
Vladimir Marek
2008-Jun-04 16:31 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
> The reason for no looping is ... loop became long, or even worse, > infinite, your system would be hosed. > > The reason for no if/else construct is because each probe clause must > produce a fixed length trace record.I always thought that it''s deliberate way of torturing us, the users :) Personally I tend to wrap D scripts into shell scripts to get loops. -- Vlad -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 193 bytes Desc: not available URL: <http://mail.opensolaris.org/pipermail/dtrace-discuss/attachments/20080604/a5ce7d65/attachment.bin>
Chip Bennett
2008-Jun-04 17:07 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
> > The reason for no looping is ... loop became long, or even worse, > > infinite, your system would be hosed. > > > > The reason for no if/else construct is because each probe clause must > > produce a fixed length trace record. > > I always thought that it''s deliberate way of torturing us, the users :) >Amen to that! Am I an experienced user of DTrace who understands why we don''t need flow control, or am I a lemming rationalizing what I''ve been taught to live with? To quote the USENIX paper (http://www.sun.com/bigadmin/content/dtrace/dtrace_usenix.pdf), "To prevent DIF from inducing an infinite loop in probe context, only forward branches are permitted. This safety provision may seem draconian ? it eliminates loops altogether ? but in practice we have not discovered it to present a serious limitation." But this is now becoming philosophical. ;-) Chip
Roman Shaposhnik
2008-Jun-04 17:44 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
On Wed, 2008-06-04 at 13:07 -0400, Chip Bennett wrote:> > > The reason for no looping is ... loop became long, or even worse, > > > infinite, your system would be hosed. > > > > > > The reason for no if/else construct is because each probe clause must > > > produce a fixed length trace record. > > > > I always thought that it''s deliberate way of torturing us, the users :) > > > > Amen to that! Am I an experienced user of DTrace who understands why we don''t need flow control, or am I a lemming rationalizing what I''ve been taught to live with? > To quote the USENIX paper (http://www.sun.com/bigadmin/content/dtrace/dtrace_usenix.pdf), "To prevent DIF from inducing an infinite loop in probe context, only forward > branches are permitted. This safety provision may seem draconian ? it eliminates loops altogether ? but in practice we have not discovered it to present a serious limitation."I believe there''s a curious gap to be potentially exploited here: it seems that DIF object code is capable of slightly more than the language translator offers up front. One idea that has been mentioned here is to have a translator that would morph if-then-else into a sequence of probes. Another idea could be to allow loops with a constant boundary (via loop unrolling of course). I''m currently doing things like these via M4, but I have an unsettling feeling that D++ could be called for ;-) Thanks, Roman.
Roman Shaposhnik
2008-Jun-04 18:04 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
On Wed, 2008-06-04 at 11:55 -0400, Chip Bennett wrote:> I explain a lot of why D scripts don''t allow flow control constructs in footnote 1 of this article: http://www.laurustech.com/tech_paper.asp?ID=102. There is also some discussion of how to get the effects of flow control without real flow control. > > However, I''ll summarize here. The reason for no looping is because probe clauses run as kernel threads with interrupts turned off. If a loop became long, or even worse, infinite, your system would be hosed. > > The reason for no if/else construct (and another reason for no loops) is because each probe clause must produce a fixed length trace record.That''s a very interesting bit of information! Do you the rationale behind such a restriction on a length of a trace record? Thanks, Roman.
James Carlson
2008-Jun-04 18:06 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
Roman Shaposhnik writes:> > fbt:foo:bar:entry > > /arg0 == 1234/ > > { > > trace(arg1); > > self->test = arg2; > > Am I missing something or would this->test be more appropriate in > this case?"self" is local to the thread executing, and thus crosses the boundaries between the separate probe points. "this" is local to a single probe clause. "this->test" wouldn''t work here. -- James Carlson, Solaris Networking <james.d.carlson at sun.com> Sun Microsystems / 35 Network Drive 71.232W Vox +1 781 442 2084 MS UBUR02-212 / Burlington MA 01803-2757 42.496N Fax +1 781 442 1677
Roman Shaposhnik
2008-Jun-04 18:07 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
On Wed, 2008-06-04 at 10:12 -0400, James Carlson wrote:> Christophe Kalt writes: > > No, see http://docs.sun.com/app/docs/doc/817-6223/chp-typeopexpr-10?a=view > > The lack of for/while/goto is an intentional omission in the interest > of safety. > > If/else, though, is another matter. You can easily translate any > if/else combination into a series of probes. For example, the > following is invalid: > > fbt:foo:bar:entry > /arg0 == 1234/ > { > trace(arg1); > if (arg2 == 5678) > trace(arg2); > else > trace(arg3); > } > > But you can do something like this, and it''s equivalent: > > fbt:foo:bar:entry > /arg0 == 1234/ > { > trace(arg1); > self->test = arg2;Am I missing something or would this->test be more appropriate in this case? Thanks, Roman.
James Carlson
2008-Jun-04 18:33 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
Roman Shaposhnik writes:> On Wed, 2008-06-04 at 14:06 -0400, James Carlson wrote: > > "self" is local to the thread executing, and thus crosses the > > boundaries between the separate probe points. "this" is local to a > > single probe clause. > > > > "this->test" wouldn''t work here. > > That''s why I asked. And based one the quote from Adam''s blog -- your > interpretation is NOT what I believe probe-local variables do: > > http://blogs.sun.com/ahl/entry/pid2proc_for_dtrace:[...] Thanks; I wasn''t aware that ''this'' would span distinct clauses as long as the probe point itself remains the same. That''s surprising and useful. ;-} -- James Carlson, Solaris Networking <james.d.carlson at sun.com> Sun Microsystems / 35 Network Drive 71.232W Vox +1 781 442 2084 MS UBUR02-212 / Burlington MA 01803-2757 42.496N Fax +1 781 442 1677
Roman Shaposhnik
2008-Jun-04 18:33 UTC
[dtrace-discuss] can i use if/else/for/while in dtrace script?
On Wed, 2008-06-04 at 14:06 -0400, James Carlson wrote:> Roman Shaposhnik writes: > > > fbt:foo:bar:entry > > > /arg0 == 1234/ > > > { > > > trace(arg1); > > > self->test = arg2; > > > > Am I missing something or would this->test be more appropriate in > > this case? > > "self" is local to the thread executing, and thus crosses the > boundaries between the separate probe points. "this" is local to a > single probe clause. > > "this->test" wouldn''t work here.That''s why I asked. And based one the quote from Adam''s blog -- your interpretation is NOT what I believe probe-local variables do: http://blogs.sun.com/ahl/entry/pid2proc_for_dtrace: "The code isn''t exactly gorgeous, but it gets the job done. It''s a good example of probe-local variables (also somewhat misleadingly called clause-local variables), and demonstrates how you can use them to communicate values between clauses associated with a given probe during a given firing." Unless I''m reading it incorrectly, each variable is associated with a *given* probe during a *given* firing. In your case all of the probes are the same: "fbt:foo:bar:entry" and we''re trying to construct an if-then-else clause for a single firing. Thanks, Roman.
thanks all , when i see dtrace can not use if , i think a solution to my script it''s a time counter dtrace script for all java methods...because dtrace is not start with the jvm at the same time ,so many java method will not have a entry, so at return probe is hard to count time cost... after test , a method throw a Exception will also have a return probe, so this script will work now... #!/usr/sbin/dtrace -s #pragma D option quiet dtrace:::BEGIN { self->index = 0; tstart = timestamp; } hotspot$1:::method-entry { mname = strjoin(strjoin(copyinstr(arg1,arg2),"->"),copyinstr(arg3,arg4)); self->index++; self->mname[self->index] = mname; self->mtime[self->index] = timestamp; @count[mname] = count(); } hotspot$1:::method-return { mname = strjoin(strjoin(copyinstr(arg1,arg2),"->"),copyinstr(arg3,arg4)); mindex = (self->mname[self->index] == mname) ? -1 : 0; mtime = (mindex == -1) ? self->mtime[self->index] : tstart; /* mname = (mindex == -1) ? mname : strjoin("non-start-", mname); printf("method : %s : start : %d\n", mname, tstart); */ @time[mname] = avg(timestamp - mtime); self->index += mindex; } copyinstr sometimes will get a wrong string if havn''t the length param...like this: 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef 0: 6e 6f 6e 2d 73 74 61 72 74 2d 6a 61 76 61 2f 69 non-start-java/i 10: 6f 2f 42 75 66 66 65 72 65 64 57 72 69 74 65 72 o/BufferedWriter 20: 01 c0 d7 42 30 02 e0 d8 13 2d 3e 6e 65 77 4c 69 ...B0....->newLi 30: 6e 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ne.............. 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ -- This message posted from opensolaris.org