6 Replies Latest reply: Aug 17, 2010 5:09 AM by 807559 RSS

    clause local variable question

    807559
      Hi,

      I still don't have a glue how clause local variables work. Using the simple D :

      #pragma D option quiet
      
      int this  x;
      
      
      BEGIN
      {
        check1 = 0;
        check2 = 0;
      }
      
      syscall::read:entry
      / execname == "in.mpathd" /
      {
        this->x = check1 != 0 ? this->x : 1;
        check1 = 1;
        printf("1st clause: %d \n", this->x);
      }
      
      syscall::read:entry
      / execname == "in.mpathd" /
      {
        printf("2nd clause: %d \n", this->x++);
      }
      
      syscall::write:entry
      / execname == "in.mpathd" /
      {
        this->x =  check2 != 0 ? this->x : 1000;
        check2 = 1;
        printf("3nd clause: %d \n", this->x);
      }
      I am getting the following result:

      3nd clause: 1000
      1st clause: 1
      2nd clause: 1
      3nd clause: 2
      1st clause: 2
      2nd clause: 2
      3nd clause: 3
      1st clause: 3
      2nd clause: 3
      3nd clause: 4
      1st clause: 4
      2nd clause: 4
      3nd clause: 5
      1st clause: 5
      2nd clause: 5
      3nd clause: 6
      1st clause: 6
      2nd clause: 6
      3nd clause: 7
      1st clause: 7
      2nd clause: 7
      3nd clause: 8
      1st clause: 8
      2nd clause: 8
      3nd clause: 9
      1st clause: 9
      2nd clause: 9
      3nd clause: 10
      1st clause: 10
      2nd clause: 10
      3nd clause: 0
      1st clause: 0
      2nd clause: 0
      3nd clause: 1
      1st clause: 1
      2nd clause: 1
      3nd clause: 2
      1st clause: 2
      2nd clause: 2
      3nd clause: 0
      1st clause: 0
      2nd clause: 0
      3nd clause: 3
      1st clause: 3
      2nd clause: 3
      3nd clause: 1
      1st clause: 1
      2nd clause: 1
      3nd clause: 2
      1st clause: 2
      2nd clause: 2
      3nd clause: 3
      1st clause: 3
      2nd clause: 3
      3nd clause: 4
      1st clause: 4
      2nd clause: 4
      3nd clause: 5
      1st clause: 5
      2nd clause: 5
      3nd clause: 6
      1st clause: 6
      2nd clause: 6
      3nd clause: 7
      1st clause: 7
      2nd clause: 7
      3nd clause: 8
      1st clause: 8
      2nd clause: 8
      3nd clause: 9
      1st clause: 9
      2nd clause: 9
      3nd clause: 10
      1st clause: 10
      2nd clause: 10
      3nd clause: 11
      1st clause: 11
      2nd clause: 11
      3nd clause: 12
      1st clause: 12
      2nd clause: 12
      3nd clause: 0
      1st clause: 0
      2nd clause: 0
      3nd clause: 11
      1st clause: 11
      2nd clause: 11
      I was expecting that the value of this->x within syscall::read:entry should be incremented by 1 as the probe fires and this->x within syscall::write:entry should remain 1000. Hmm...
        • 1. Re: clause local variable question
          807559
          This sounds like object-oriented thinking applied to DTrace, which is not quite what clause-local variables promise. Consider this passage in the Solaris Dynamic Tracing Guide, pp. 67:

          Clause-local variables are only active for the lifetime of a given probe clause. After DTrace performs the actions associated with your clauses for a given probe, the storage for all clause-local variables is reclaimed and reused for the next clause. For this reason, clause-local variables are the only D variables that are not initially filled with zeroes. Note that if your program contains multiple clauses for a single probe, any clause-local variables will remain intact as the clauses are executed...

          The sanity of a clause-local variable used in multiple clauses for the same probe definition is guaranteed; separate, sanitized storage space for each probe definition in the program is not. So when syscall::write:entry accesses this->x, it finds what syscall::read:entry left behind.

          Just use different variables for different probe definitions. It is less confusing in any event:
          #!/usr/sbin/dtrace -s
          
          #pragma D option quiet
          
          BEGIN
          {
                  printf("BEGIN");
                  this->y = 99;
          }
          
          syscall::read:entry
          / !this->x /
          {
                  this->x = 0;
                  printf("Clause %d: %d\n", epid, this->x);
          }
          
          syscall::read:entry
          {
                  printf("Clause %d: %d\n", epid, this->x++);
          }
          
          syscall::read:entry
          / this->x == 20 /
          {
                  printf("Clause %d: %d\n", epid, this->x);
                  exit(0);
          }
          
          syscall::write:entry
          {
                  printf("Clause %d: %d\n", epid, this->y++);
          }
          • 2. Re: clause local variable question
            807559
            Hello Michael,

            thank you for the explanation. The output of your D brings some new questions:
            BEGINClause 2: 0
            Clause 3: 0
            Clause 3: 1
            Clause 5: 0      -> should be 99 ?
            Clause 3: 2
            Clause 5: 0
            Clause 2: 0      -> should not be reentered again?
            Clause 3: 0
            Clause 3: 1
            Clause 3: 2
            Clause 3: 3
            Clause 5: 99
            Clause 5: 100
            Clause 5: 101
            Clause 5: 102
            Clause 5: 103
            Clause 5: 104
            Clause 5: 105
            Clause 5: 106
            Clause 5: 107
            Clause 5: 108
            Clause 5: 109
            Clause 2: 0
            Clause 3: 0
            Clause 3: 1
            Clause 5: 0
            Clause 3: 2
            Clause 5: 1
            Clause 3: 3
            Clause 3: 4
            Clause 3: 5
            Clause 3: 6
            Clause 3: 7
            Clause 5: 1
            Clause 3: 8
            Clause 3: 9
            Clause 5: 2
            Clause 3: 10
            Clause 3: 11
            Clause 5: 3
            Clause 3: 12
            Clause 3: 13
            Clause 5: 4
            Clause 3: 14
            Clause 3: 15
            Clause 5: 5
            Clause 5: 110
            Clause 5: 111
            Clause 5: 112
            Clause 5: 113
            Clause 5: 114
            Clause 5: 115
            Clause 5: 116
            Clause 5: 117
            Clause 5: 118
            Clause 5: 119
            Clause 5: 120
            Clause 5: 121
            Clause 5: 122
            Clause 5: 123
            Clause 5: 124
            Clause 5: 125
            Clause 5: 126
            Clause 2: 0
            Clause 3: 0
            Clause 5: 127
            Clause 3: 1
            Clause 5: 128
            Clause 3: 2
            Clause 5: 129
            Clause 3: 3
            Clause 5: 2   -> should be 130?
            Clause 3: 4
            Clause 5: 3
            Clause 3: 5
            Clause 5: 4
            Clause 5: 5
            Clause 5: 6
            Clause 3: 6
            Clause 3: 7
            Clause 3: 8
            Clause 5: 7
            Clause 3: 9
            Clause 3: 10
            Clause 3: 11
            Clause 5: 8
            Clause 3: 12
            Clause 3: 13
            Clause 3: 14
            Clause 5: 9
            Clause 3: 15
            Clause 3: 16
            Clause 3: 17
            Clause 5: 10
            Clause 3: 18
            Clause 3: 19
            Clause 4: 20     -> should exit here?
            Clause 5: 1       -> 1 again?
            Clause 3: 4
            Clause 3: 5
            Clause 3: 6
            Clause 5: 2
            Clause 3: 7
            Clause 3: 8
            Clause 3: 9
            Clause 5: 3
            Clause 3: 10
            Clause 3: 11
            Clause 3: 12
            I'm wondering that the initial value of probe 5 is 0, not 99.
            Should not have the action of Clause 2 executed just once, because of the predicate / !this->x / ? But it appears several times.
            After Clause 4: 20 the D should exit. Why are there still probes firing and why the value of this->x has become 4 ?
            Should not clause 5 increment this->y by 1 if it's fired? Why does this->y get values < 99 ?

            Edited by: go_insane on Aug 11, 2010 3:18 AM
            • 3. Re: clause local variable question
              807559
              Oy.

              I changed the assignment in clause 2 to this->x = 1, rather than zero. My tests did not re-enter clause 2 after that.

              I did not get clause 5 to output 99. I have a guess why, but I don't want to offer it until you make the change above. I'd be curious to see if clause 5 reporting zero goes away, which I think it will.

              I also did not see clause 5 report incorrectly after this change.

              If all that works the same for you, then let's look at why your clause 4 did not exit when it should have.
              • 4. Re: clause local variable question
                807559
                Hello Michael,

                i've changed this->x to 1 in clause 2.
                But the result is curious again:

                BEGINClause 5: 0
                Clause 5: 1
                Clause 5: 99
                Clause 5: 100
                Clause 2: 1
                Clause 3: 1
                Clause 5: 2
                Clause 5: 0
                Clause 2: 1
                Clause 3: 1
                Clause 5: 1
                Clause 3: 2
                Clause 5: 101
                Clause 5: 102
                Clause 5: 103
                Clause 5: 104
                Clause 5: 105
                Clause 5: 106
                Clause 5: 107
                Clause 5: 108
                Clause 5: 109
                Clause 5: 110
                Clause 5: 111
                Clause 5: 112
                Clause 3: 2
                Clause 3: 3
                Clause 5: 3
                Clause 3: 4
                Clause 5: 4
                Clause 5: 5
                Clause 3: 5
                Clause 3: 6
                Clause 5: 6
                Clause 3: 7
                Clause 3: 8
                Clause 3: 9
                Clause 3: 10
                Clause 5: 7
                Clause 5: 8
                Clause 5: 9
                Clause 5: 10
                Clause 5: 2
                Clause 3: 3
                Clause 3: 4
                Clause 5: 3
                Clause 3: 5
                Clause 5: 113
                Clause 5: 114
                Clause 5: 115
                Clause 5: 116
                Clause 5: 117
                Clause 5: 118
                Clause 5: 119
                Clause 5: 120
                Clause 5: 121
                Clause 5: 122
                Clause 5: 123
                Clause 5: 124
                Clause 2: 1
                Clause 3: 1
                Clause 3: 2
                Clause 5: 125
                Clause 3: 3
                Clause 3: 4
                Clause 3: 5
                Clause 3: 6
                Clause 3: 7
                Clause 5: 126
                Clause 5: 127
                Clause 5: 128
                Clause 5: 129
                Clause 5: 130
                Clause 5: 131
                Clause 5: 132
                Clause 5: 133
                Clause 5: 134
                Clause 5: 135
                Clause 5: 136
                Clause 5: 137
                Clause 5: 138
                Clause 5: 139
                Clause 5: 140
                Clause 5: 141
                Clause 5: 142
                Clause 5: 143
                Clause 5: 144
                Clause 5: 145
                Clause 5: 146
                Clause 5: 147
                Clause 5: 148
                Clause 5: 149
                Clause 5: 0
                Clause 3: 11
                Clause 3: 12
                Clause 5: 11
                Clause 3: 13
                Clause 5: 12
                Clause 3: 14
                Clause 5: 13
                Clause 3: 15
                Clause 5: 14
                Clause 3: 16
                Clause 5: 15
                Clause 3: 17
                Clause 5: 16
                Clause 3: 18
                Clause 5: 17
                Clause 3: 19
                Clause 4: 20
                Clause 5: 150
                Clause 5: 151
                Clause 5: 152
                Clause 5: 153
                Clause 5: 154
                Clause 5: 155
                Clause 5: 156
                Clause 5: 157
                Clause 5: 158
                Clause 5: 159
                Clause 5: 160
                Clause 5: 161
                Clause 5: 162
                Clause 5: 163
                Clause 5: 164
                Clause 5: 165
                Clause 5: 166
                Clause 5: 167
                Clause 5: 168
                Clause 5: 169
                Clause 5: 170
                Edited by: go_insane on Aug 16, 2010 6:10 AM
                • 5. Re: clause local variable question
                  807559
                  Post the script you are now working with?
                  • 6. Re: clause local variable question
                    807559
                    #!/usr/sbin/dtrace -s
                    
                    #pragma D option quiet
                    
                    BEGIN
                    {
                            printf("BEGIN");
                            this->y = 99;
                    }
                    
                    syscall::read:entry
                    / !this->x /
                    {
                            this->x = 1;
                            printf("Clause %d: %d\n", epid, this->x);
                    }
                    
                    syscall::read:entry
                    {
                            printf("Clause %d: %d\n", epid, this->x++);
                    }
                    
                    syscall::read:entry
                    / this->x == 20 /
                    {
                            printf("Clause %d: %d\n", epid, this->x);
                            exit(0);
                    }
                    
                    syscall::write:entry
                    {
                            printf("Clause %d: %d\n", epid, this->y++);
                    }