[DTrace-devel] [PATCH v2] Implementation of the exit() action

Eugene Loh eugene.loh at oracle.com
Thu Apr 9 11:51:46 PDT 2020


Nice and focused.


On 04/09/2020 12:20 AM, Kris Van Hees wrote:
> The exit() action is quite instrumental to the use of DTrace because it
> allows a tracing script to terminate the tracing session.
>
> Because exit() must be able to signal that trace data processing is
> done, dt_consume_one(), dt_consume_cpu(), and dt_consume() have been
> updated to return a dtrace_workstatus_t value to indicate whether
> processing of trace data is to continue (DTRACE_WORKSTATUS_OKAY),
> is done (DTRACE_WORKSTATUS_DONE), or whether an error occurred
> (DTRACE_WORKSTATUS_ERROR).
>
> Signed-off-by: Kris Van Hees <kris.van.hees at oracle.com>
> ---
>   libdtrace/dt_cg.c      |  5 +++--
>   libdtrace/dt_consume.c | 37 ++++++++++++++++++++++++-------------
>   libdtrace/dt_work.c    |  9 +--------
>   3 files changed, 28 insertions(+), 23 deletions(-)
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index f71fc62c..492a5b61 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -362,11 +362,12 @@ dt_cg_act_exit(dt_pcb_t *pcb, dt_node_t *dnp, dtrace_actkind_t kind)
>   	dt_cg_node(dnp->dn_args, &pcb->pcb_ir, pcb->pcb_regs);
>   
>   	off = dt_rec_add(pcb->pcb_hdl, dt_cg_fill_gap, DTRACEACT_EXIT,
> -			 sizeof(uint64_t), sizeof(uint64_t), NULL,
> +			 sizeof(uint32_t), sizeof(uint32_t), NULL,
>   			 DT_ACT_EXIT);
>   
> -	instr = BPF_STORE(BPF_DW, BPF_REG_9, off, BPF_REG_0);	/* FIXME */
> +	instr = BPF_STORE(BPF_W, BPF_REG_9, off, dnp->dn_args->dn_reg);
>   	dt_irlist_append(dlp, dt_cg_node_alloc(DT_LBL_NONE, instr));
> +	dt_regset_free(pcb->pcb_regs, dnp->dn_args->dn_reg);
>   }
>   
>   static void
> diff --git a/libdtrace/dt_consume.c b/libdtrace/dt_consume.c
> index 46e1efaf..ae8a7ea8 100644
> --- a/libdtrace/dt_consume.c
> +++ b/libdtrace/dt_consume.c
> @@ -2254,10 +2254,10 @@ nextepid:
>   	return (dt_handle_cpudrop(dtp, cpu, DTRACEDROP_PRINCIPAL, drops));
>   }
>   #else
> -int
> +dtrace_workstatus_t
>   dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, int cpu, char *buf,
>   	       dtrace_consume_probe_f *efunc, dtrace_consume_rec_f *rfunc,
> -	       int flow, int quiet, dtrace_epid_t last, void *arg)
> +	       int flow, int quiet, dtrace_epid_t *last, void *arg)
>   {
>   	char				*data = buf;
>   	struct perf_event_header	*hdr;
> @@ -2270,6 +2270,7 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, int cpu, char *buf,
>   		char			*ptr = data;
>   		uint32_t		size, epid, tag;
>   		int			i;
> +		int			done = 0;
>   		dtrace_probedata_t	pdat;
>   
>   		/*
> @@ -2319,7 +2320,7 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, int cpu, char *buf,
>   			return rval;
>   
>   		if (flow)
> -			dt_flowindent(dtp, &pdat, last, DTRACE_EPIDNONE);
> +			dt_flowindent(dtp, &pdat, *last, DTRACE_EPIDNONE);
>   
>   		rval = (*efunc)(&pdat, arg);
>   
> @@ -2345,6 +2346,8 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, int cpu, char *buf,
>   			dtrace_recdesc_t	*rec;
>   
>   			rec = &pdat.dtpda_ddesc->dtdd_recs[i];
> +			if (rec->dtrd_action == DTRACEACT_EXIT)
> +				done = 1;
>   
>   			pdat.dtpda_data = data + rec->dtrd_offset;
>   			rval = (*rfunc)(&pdat, rec, arg);
> @@ -2371,7 +2374,9 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, int cpu, char *buf,
>   		 */
>   		rval = (*rfunc)(&pdat, NULL, arg);
>   
> -		return epid;
> +		*last = epid;
> +
> +		return done ? DTRACE_WORKSTATUS_DONE : DTRACE_WORKSTATUS_OKAY;
>   	} else if (hdr->type == PERF_RECORD_LOST) {
>   		uint64_t	lost;
>   
> @@ -2386,9 +2391,9 @@ dt_consume_one(dtrace_hdl_t *dtp, FILE *fp, int cpu, char *buf,
>   		lost = *(uint64_t *)(data + sizeof(uint64_t));
>   
>   		/* FIXME: To be implemented */
> -		return -1;
> +		return DTRACE_WORKSTATUS_ERROR;
>   	} else
> -		return -1;
> +		return DTRACE_WORKSTATUS_ERROR;
>   }
>   
>   int
> @@ -2406,6 +2411,7 @@ dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dt_peb_t *peb,
>   	dt_pebset_t			*pebset = dtp->dt_pebset;
>   	uint64_t			data_size = pebset->data_size;
>   	int				flow, quiet;
> +	dtrace_workstatus_t		rval = DTRACE_WORKSTATUS_OKAY;
>   
>   	flow = (dtp->dt_options[DTRACEOPT_FLOWINDENT] != DTRACEOPT_UNSET);
>   	quiet = (dtp->dt_options[DTRACEOPT_QUIET] != DTRACEOPT_UNSET);
> @@ -2450,15 +2456,18 @@ dt_consume_cpu(dtrace_hdl_t *dtp, FILE *fp, int cpu, dt_peb_t *peb,
>   				event = dst;
>   			}
>   
> -			last = dt_consume_one(dtp, fp, cpu, event, efunc, rfunc,
> -					      flow, quiet, last, arg);
> +			rval = dt_consume_one(dtp, fp, cpu, event, efunc, rfunc,
> +					      flow, quiet, &last, arg);
> +			if (rval != DTRACE_WORKSTATUS_OKAY)
> +				return rval;
> +
>   			tail += hdr->size;
>   		} while (tail != head);
>   
>   		ring_buffer_write_tail(rb_page, tail);
>   	}
>   
> -	return 0;
> +	return DTRACE_WORKSTATUS_OKAY;
>   }
>   #endif
>   
> @@ -2666,7 +2675,7 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp, dtrace_bufdesc_t *buf,
>   	return (rval);
>   }
>   
> -int
> +dtrace_workstatus_t
>   dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
>       dtrace_consume_probe_f *pf, dtrace_consume_rec_f *rf, void *arg)
>   {
> @@ -2779,8 +2788,10 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
>   	timeout /= NANOSEC / MILLISEC;
>   	cnt = epoll_wait(dtp->dt_poll_fd, events, dtp->dt_conf.numcpus,
>   			 timeout);
> -	if (cnt < 0)
> -		return dt_set_errno(dtp, errno);
> +	if (cnt < 0) {
> +		dt_set_errno(dtp, errno);
> +		return DTRACE_WORKSTATUS_ERROR;
> +	}
>   
>   	/*
>   	 * Loop over the buffers that have data available, and process them one
> @@ -2795,6 +2806,6 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
>   			return rval;
>   	}
>   
> -	return 0;
> +	return DTRACE_WORKSTATUS_OKAY;
>   #endif
>   }
> diff --git a/libdtrace/dt_work.c b/libdtrace/dt_work.c
> index 7889ba78..df7f8f5c 100644
> --- a/libdtrace/dt_work.c
> +++ b/libdtrace/dt_work.c
> @@ -337,13 +337,6 @@ dtrace_workstatus_t
>   dtrace_work(dtrace_hdl_t *dtp, FILE *fp, dtrace_consume_probe_f *pfunc,
>   	    dtrace_consume_rec_f *rfunc, void *arg)
>   {
> -	dtrace_workstatus_t	rval;
> -
> -	rval = DTRACE_WORKSTATUS_OKAY;
> -
> -	if (dtrace_consume(dtp, fp, pfunc, rfunc, arg) == -1)
> -		return DTRACE_WORKSTATUS_ERROR;
> -
> -	return rval;
> +	return dtrace_consume(dtp, fp, pfunc, rfunc, arg);
>   }
>   #endif




More information about the DTrace-devel mailing list