[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