[DTrace-devel] [PATCH 1/2] Add clause flags

Eugene Loh eugene.loh at oracle.com
Tue Sep 15 22:24:47 PDT 2020


Suggestions incorporated, except for that business of setting the 
DATAREC flag in dt_cg_store_value().  See questions below.


On 09/15/2020 09:50 PM, Kris Van Hees wrote:

> On Tue, Sep 15, 2020 at 10:26:35PM -0400, eugene.loh at oracle.com wrote:
>> From: Eugene Loh <eugene.loh at oracle.com>
>>
>> There are compile-time rules to enforce regarding which actions are
>> compatible with which others.  E.g., data-recording actions cannot
>> follow commits, etc.  Introduce flags that track clause actions during
>> compilation so that these rules can be enforced.
>>
>> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
>> @@ -589,6 +601,16 @@ dt_cg_act_exit(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>>   	struct bpf_insn	instr;
>>   	dt_irlist_t	*dlp = &pcb->pcb_ir;
>>   	uint_t		off;
>> +	int		*cfp = &pcb->pcb_stmt->dtsd_clauseflags;
>> +
>> +	/* process clause flags */
>> +	if (*cfp & DT_CLSFLAG_SPECULATE)
>> +		dnerror(dnp, D_EXIT_SPEC,
>> +		    "exit( ) may not follow speculate( )\n");
>> +        if (*cfp & DT_CLSFLAG_COMMIT)
>> +                dnerror(dnp, D_DREC_COMM,
>> +		    "data-recording actions may not follow commit( )\n");
>> +	*cfp |= DT_CLSFLAG_EXIT | DT_CLSFLAG_DATAREC;
> This should only set DT_CLSFLAG_EXIT, and the DT_CLSFLAG_DATAREC should be set
> in dt_cg_store_val() since that is the function that calls dt_add_rec() and
> then also generates the instructions to actually write the value to the output
> buffer.

I do not understand the rationale.  It would seem to me that here is a 
perfectly fine place to set the DATAREC flag.  We know what the action 
is:  it's exit().  We need not care about how the action is implemented 
(whether with a call to dt_cg_store_val, direct calls to dt_add_rec, or 
whatever).  Indeed, we just tested for D_DREC_COMM ("data-recording 
actions may not... blahblahblah").  So we have said definitively that 
this is a data-recording action, regardless of how we now implement that 
action.

>>   	dt_cg_node(dnp->dn_args, &pcb->pcb_ir, pcb->pcb_regs);
>>   
>> @@ -638,6 +660,13 @@ dt_cg_act_printf(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>>   	dt_pfargv_t	*pfp;
>>   	char		n[DT_TYPE_NAMELEN];
>>   	char		*str;
>> +	int		*cfp = &pcb->pcb_stmt->dtsd_clauseflags;
>> +
>> +	/* process clause flags */
>> +	if (*cfp & DT_CLSFLAG_COMMIT)
>> +		dnerror(dnp, D_DREC_COMM,
>> +		    "data-recording actions may not follow commit( )\n");
>> +	*cfp |= DT_CLSFLAG_DATAREC;
> See comment above about setting DT_CLS_FLAG_DATARC from dt_cg_store_val().

Actually, the printf action is a better example of what I'm talking 
about.  The subsequent code has different code paths:  one that calls 
dt_rec_add() directly and the other is a call to dt_cg_store_val().  We 
should set the DATAREC flag because of what we know about the action, 
not because of what we know about the various functions we use to 
implement it -- that is, that a side effect of dt_cg_store_val is to set 
the DATAREC flag while dt_rec_add does not have such a side effect.

>>   	/*
>>   	 * Ensure that the format string is a string constant.
>> @@ -810,6 +853,13 @@ dt_cg_act_trace(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>>   	char		n[DT_TYPE_NAMELEN];
>>   	dt_node_t	*arg = dnp->dn_args;
>>   	int		type = 0;
>> +	int		*cfp = &pcb->pcb_stmt->dtsd_clauseflags;
>> +
>> +	/* process clause flags */
>> +	if (*cfp & DT_CLSFLAG_COMMIT)
>> +		dnerror(dnp, D_DREC_COMM,
>> +		        "data-recording actions may not follow commit( )\n");
>> +	*cfp |= DT_CLSFLAG_DATAREC;
> See comment above about setting DT_CLS_FLAG_DATARC from dt_cg_store_val().
>
>>   	if (dt_node_is_void(arg)) {
>>   		dnerror(arg, D_TRACE_VOID,




More information about the DTrace-devel mailing list