On Sat, Dec 17, 2016 at 03:10:14PM +0900, Hiroki Sato wrote:
> Hi,
> 
>  I have trouble with clause-local variable.  A minimum working example
>  is attached.  The "sample" program simply displays a string in an
>  infinite loop with a USDT named as "dump-str", sample_debug.d does
>  copyin() and printf() the whole buffer assuming it is
>  nul-terminated:
> 
>  | sample$target:::dump-str
>  | {
>  |         this->st = copyin(arg0, 1024);
>  |
>  |         printf("(1)st = %s, %p\n", stringof(this->st),
>  |             (char *)this->st);
>  | }
>  | sample$target:::dump-str
>  | {
>  |         printf("(2)st = %s, %p\n", stringof(this->st),
>  |             (char *)this->st);
>  |         printf("(3)st = %s\n", stringof(copyin(arg0, 1024)));
>  | }
> 
>  The odd part is that it does not work with splitting the probe into
>  the two as above but works fine without the split.  The result was as
>  follows:
> 
>  |  % sudo make test
>  | dtrace -C -I/var/home/hrs/sample_str -s sample_debug.d -c 
> /var/home/hrs/sample_str/sample
>  | dtrace: script 'sample_debug.d' matched 5 probes
>  | CPU     ID                    FUNCTION:NAME
>  |   0  61714                    main:dump-str (1)st = test-uname, 
> fffffe0001a19118
>  |
>  |   0  61714                    main:dump-str (2)st = , fffffe0001a19118
>  | (3)st = test-uname
> 
>  this->st became empty at the beginning of the second probe.
> 
>  The symptom varied depending on the address of this->st, so I am
>  guessing that this->st was incorrectly freed at the end of the first
>  probe.  If I use copyinstr(arg0) instead of copyin(), this problem
>  does not occur.
> 
>  Do I misunderstand clause-local variable?  I noticed this when I use
>  if-then clause which was recently implemented as a syntax sugar to
>  split a probe automatically.  The following ended up with the same
>  result:

I think this is more a quirk of copyin() than of clause-local variables.
In particular:
- your example works as expected if copyinstr() is used instead of
  copyin(), and
- your example works if one assigns this->st = stringof(copyin(...)).

copyin() and copyinstr() both copy data into a scratch buffer. However,
copyinstr() returns a pass-by-reference string, while copyin() returns a
pass-by-value pointer. The DIF instruction which saves to a clause-local
variable, STLS, performs a deep copy of pass-by-reference variables to
some dedicated storage. The scratch space containing the
copyin()/copyinstr() is not preserved between enablings of the same
probe, so the string copied during the first probe is not available in
the second probe when copyin() is used.
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-dtrace
To unsubscribe, send any mail to "[email protected]"

Reply via email to