Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Dec 2016 19:01:25 -0800
From:      Mark Johnston <markj@FreeBSD.org>
To:        Hiroki Sato <hrs@FreeBSD.org>
Cc:        freebsd-dtrace@freebsd.org
Subject:   Re: clause-local variable with copyin()
Message-ID:  <20161219030125.GB57753@wkstn-mjohnston.west.isilon.com>
In-Reply-To: <20161217.151014.1579687141761225852.hrs@allbsd.org>
References:  <20161217.151014.1579687141761225852.hrs@allbsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20161219030125.GB57753>