[DTrace-devel] [PATCH v2 20/20] Support probeprov, probemod, probefunc, probename built-in variables

Eugene Loh eugene.loh at oracle.com
Tue Jun 8 13:00:57 PDT 2021


On 6/8/21 11:34 AM, Kris Van Hees wrote:

> On Mon, Jun 07, 2021 at 06:57:46PM -0400, Eugene Loh wrote:
>> On 6/3/21 11:21 AM, Kris Van Hees wrote:
>>> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
>>> @@ -54,6 +54,8 @@ dt_cg_tramp_prologue_act(dt_pcb_t *pcb, dt_activity_t act)
>>>    	uint_t		lbl_exit = pcb->pcb_exitlbl;
>>>    
>>>    	assert(mem != NULL);
>>> +	assert(state != NULL);
>>> +	assert(prid != NULL);
>> Cool.  On the other hand, if one is going to do this, then might as well
>> also fix the "state =" case in dt_cg_act_exit() as well.
> Wasn't meant to be part of this patch anyway - probably something I happened
> to see and fix as I was implementing code and forgot to mark to be in its own
> patch or save it for later.  I'll probably just take it out for now because
> I certainly won't be able to do a comprehensive review of all code to catch
> more of these places where an assert would be really useful.

Okay.  FWIW, the only other assert() of this particular flavor was (so 
far as I can tell) the one I mentioned.  That is, I did look for other 
instances of this particular kind.  But either way you want to handle it 
is fine by me.

>>> @@ -753,13 +755,51 @@ dt_cg_store_val(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind,
>>>    
>>>    		return 0;
>>>    	} else if (dt_node_is_string(dnp)) {
>>> +		dt_ident_t	*idp;
>>> +		uint_t		vcopy = dt_irlist_label(dlp);
>>> +		int		reg = dt_regset_alloc(drp);
>>> +
>>>    		off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, kind,
>>>    				 size, 1, pfp, arg);
>>>    
>>> -		emit(dlp, BPF_MOV_REG(BPF_REG_0, BPF_REG_9));
>>> -		emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, off));
>>> -		dt_cg_memcpy(dlp, drp, BPF_REG_0, dnp->dn_reg, size);
>>> +		/* Retrieve the length of the string.  */
>>> +		dt_cg_strlen(dlp, drp, reg, dnp->dn_reg);
>>> +
>>> +		if (dt_regset_xalloc_args(drp) == -1)
>>> +			longjmp(yypcb->pcb_jmpbuf, EDT_NOREG);
>>> +
>>> +		/* Determine the number of bytes used for the length. */
>>> +		emit(dlp,   BPF_MOV_REG(BPF_REG_1, reg));
>>> +		idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_vint_size");
>>> +		assert(idp != NULL);
>>> +		dt_regset_xalloc(drp, BPF_REG_0);
>>> +		emite(dlp,  BPF_CALL_FUNC(idp->di_id), idp);
>>> +
>>> +		/* Add length of the string (adjusted for terminating byte). */
>>> +		emit(dlp,   BPF_ALU64_IMM(BPF_ADD, reg, 1));
>>> +		emit(dlp,   BPF_ALU64_REG(BPF_ADD, BPF_REG_0, reg));
>>> +		dt_regset_free(drp, reg);
>>> +
>>> +		/*
>>> +		 * Copy string data (varint length + string content) to the
>>> +		 * output buffer at [%r9 + off].  The amount of bytes copied is
>>> +		 * the lesser of the data size and the maximum string size.
>>> +		 */
>>> +		emit(dlp,   BPF_MOV_REG(BPF_REG_1, BPF_REG_9));
>>> +		emit(dlp,   BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, off));
>>> +		emit(dlp,   BPF_MOV_REG(BPF_REG_2, dnp->dn_reg));
>>>    		dt_regset_free(drp, dnp->dn_reg);
>>> +		emit(dlp,   BPF_MOV_REG(BPF_REG_3, BPF_REG_0));
>>> +		dt_regset_free(drp, BPF_REG_0);
>>> +		emit(dlp,   BPF_BRANCH_IMM(BPF_JLT, BPF_REG_3, size, vcopy));
>>> +		emit(dlp,   BPF_MOV_IMM(BPF_REG_3, size));
>>> +		idp = dt_dlib_get_func(yypcb->pcb_hdl, "dt_memcpy");
>>> +		assert(idp != NULL);
>>> +		dt_regset_xalloc(drp, BPF_REG_0);
>>> +		emitle(dlp, vcopy,
>>> +			    BPF_CALL_FUNC(idp->di_id), idp);
>>> +		dt_regset_free_args(drp);
>>> +		dt_regset_free(drp, BPF_REG_0);
>>>    
>>>    		return 0;
>>>    	}
>> I guess I already mentioned in my other email that I don't think the
>> prefix should be written to the output buffer.  (The consumer not only
>> tries to print the varint, but it also checks it for unprintable
>> characters, leading to rather surprising variations in output.)  The
>> other email proposes a patch, though I imagine you can cook one up just
>> as easily.  Main thing is tests to catch this sort of thing.  I'd be
>> interested in seeing this patch again after such fixes.
> I think your conclusion is wrong.  There is nothing wrong with including the
> prefix in the output buffer, and in fact it can be very beneficial and may be
> used in the future to reduce wasted space in output records and a variety of
> other improvements based on having this information readily available.
>
> The fact that the trace() action is nt behaving right is not necessarily a
> function of this code putting out the wrong data (length prefix included with
> the string data).  It seems more like a problem with trace() not being able
> to digest the data correctly.  And yes, trace() has not been updated to deal
> with strings - and that is an interesting issue that will need some attention
> and simply not make it into this patch series.
>
> And yes, tests should catch this stuff and it shows that we still have some
> major holes in the test coverage.  This case is where there need to be more
> tests for the trace() action to cover all the cases we should support (and
> negative tests for things that should not be supported).
Okay.  Thanks for the explanation.  FWIW, I was less concerned about 
writing the prefix than I was simply about the producer-consumer 
miscommunication.  I can see the value in writing the prefix, but I just 
figured leaving the consumer alone was the intended strategy. Anyhow, 
again, thanks for the comments.



More information about the DTrace-devel mailing list