Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Dec 2016 23:16:47 -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:  <20161220071647.GB82223@wkstn-mjohnston.west.isilon.com>
In-Reply-To: <20161220.030224.323335605995825210.hrs@allbsd.org>
References:  <20161217.151014.1579687141761225852.hrs@allbsd.org> <20161219030125.GB57753@wkstn-mjohnston.west.isilon.com> <20161220.030224.323335605995825210.hrs@allbsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Dec 20, 2016 at 03:02:24AM +0900, Hiroki Sato wrote:
> Mark Johnston <markj@FreeBSD.org> wrote
>   in <20161219030125.GB57753@wkstn-mjohnston.west.isilon.com>:
> 
> ma> On Sat, Dec 17, 2016 at 03:10:14PM +0900, Hiroki Sato wrote:
> ma> >  Do I misunderstand clause-local variable?  I noticed this when I use
> ma> >  if-then clause which was recently implemented as a syntax sugar to
> ma> >  split a probe automatically.  The following ended up with the same
> ma> >  result:
> ma>
> ma> I think this is more a quirk of copyin() than of clause-local variables.
> ma> In particular:
> ma> - your example works as expected if copyinstr() is used instead of
> ma>   copyin(), and
> ma> - your example works if one assigns this->st = stringof(copyin(...)).

I meant to also note here that the example fails if a thread-local
variable is used instead.

> ma>
> ma> copyin() and copyinstr() both copy data into a scratch buffer. However,
> ma> copyinstr() returns a pass-by-reference string, while copyin() returns a
> ma> pass-by-value pointer. The DIF instruction which saves to a clause-local
> ma> variable, STLS, performs a deep copy of pass-by-reference variables to
> ma> some dedicated storage. The scratch space containing the
> ma> copyin()/copyinstr() is not preserved between enablings of the same
> ma> probe, so the string copied during the first probe is not available in
> ma> the second probe when copyin() is used.
> 
>  The difference of the scratch space when using copyin() and
>  copyinstr() were the following ("-" is copyin() and "+" is
>  copyinstr()):
> 
>   NAME             ID   KND SCP FLAG TYPE
>   arg0             106  scl glb r    D type (integer) (size 8)
>  -st               500  scl loc w    D type (pointer) (size 8)
>  +st               500  scl loc w    string (unknown) by ref (size 256)
> 
>  As you explained copyinstr() had DIF_TF_BYREF and DIF_OP_STLS
>  performed dtrace_vcopy().  However, I still do not understand the
>  difference of the behavior across the boundary of two clauses for a
>  single probe.  Is it correct that the cause is that the contents of
>  the scratch space which came from copyin() or copyinstr() are not
>  preserved across multiple clauses of a single probe?

Indeed. These multiple clauses are considered to be distinct enablings
of the probe, and thus get their own scratch space - see the
dtrace_buffer_reserve() call near the beginning of the enabling loop in
dtrace_probe(). Each enabling reserves space in the tracing buffer, but
it seems that there's no mechanism to reserve space for the result of a
copyin(). dtrace_ecb_action_add() computes the amount of reserved space
required for each enabling of a probe and includes space for the buffer
created by printf(), for example.

So what happens is that STLS saves a pointer into scratch space that
gets overwritten by the record header for the second enabling. I'm not
claiming that this isn't a bug - perhaps copyin calls should cause space
to be reserved.

>  If it is true, I am still wondering why copyinstr() works.  I think
>  DIF_OP_LDLS in the second probe to load this->st always fails if the
>  scratch space is not preserved regardless of whether the data type
>  involves dereference or not.

See the handling for pass-by-reference types in the STLS and LDLS
implementations. STLS saves the entire string to the vstate struct in
the enabling state. But variable state is shared between the enablings,
so the LDLS instruction from the second probe is able to access the
string.



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