[DTrace-devel] [PATCH] cg: allow providers to specify a skip count for stack retrieval
Eugene Loh
eugene.loh at oracle.com
Wed May 1 19:40:09 UTC 2024
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
I haven't played much with stack/fentry/fexit, so I hope this is right
(e.g., stable number of skip frames). Are our tests robust enough to
assure us?
BUT! What about stackdepth in bpf/get_bvar.c?
On 5/1/24 14:22, Kris Van Hees wrote:
> Some probes cause extra frames to be reported with bpf_get_stack() that
> need to be skipped to ensure we report the correct stack trace to the
> consumer. FBT probes based on fentry/fexit probes need this.
>
> Signed-off-by: Kris Van Hees<kris.van.hees at oracle.com>
> ---
> libdtrace/dt_cg.c | 6 ++++--
> libdtrace/dt_prov_fbt.c | 1 +
> libdtrace/dt_provider.h | 1 +
> 3 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/libdtrace/dt_cg.c b/libdtrace/dt_cg.c
> index 27246a40..36975406 100644
> --- a/libdtrace/dt_cg.c
> +++ b/libdtrace/dt_cg.c
> @@ -2595,7 +2595,8 @@ dt_cg_act_stack_sub(dt_pcb_t *pcb, dt_node_t *dnp, int reg, int off, dtrace_actk
> dt_irlist_t *dlp = &pcb->pcb_ir;
> dt_regset_t *drp = pcb->pcb_regs;
> uint64_t arg;
> - int nframes, stacksize, prefsz, align = sizeof(uint64_t);
> + int nframes, stacksize, prefsz, skip;
> + int align = sizeof(uint64_t);
> uint_t lbl_valid = dt_irlist_label(dlp);
>
> /* Get sizing information from dnp->dn_arg. */
> @@ -2603,6 +2604,7 @@ dt_cg_act_stack_sub(dt_pcb_t *pcb, dt_node_t *dnp, int reg, int off, dtrace_actk
> prefsz = kind == DTRACEACT_USTACK ? sizeof(uint64_t) : 0;
> nframes = DTRACE_USTACK_NFRAMES(arg);
> stacksize = nframes * sizeof(uint64_t);
> + skip = yypcb->pcb_probe->prov->impl->skip_frames;
>
> /* Handle alignment and reserve space in the output buffer. */
> if (reg >= 0) {
> @@ -2644,7 +2646,7 @@ dt_cg_act_stack_sub(dt_pcb_t *pcb, dt_node_t *dnp, int reg, int off, dtrace_actk
> emit(dlp, BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, off + prefsz));
> }
> emit(dlp, BPF_MOV_IMM(BPF_REG_3, stacksize));
> - emit(dlp, BPF_MOV_IMM(BPF_REG_4, (0 & BPF_F_SKIP_FIELD_MASK)
> + emit(dlp, BPF_MOV_IMM(BPF_REG_4, (skip & BPF_F_SKIP_FIELD_MASK)
> | (kind == DTRACEACT_USTACK ? BPF_F_USER_STACK : 0)));
> dt_regset_xalloc(drp, BPF_REG_0);
> emit(dlp, BPF_CALL_HELPER(BPF_FUNC_get_stack));
> diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
> index 0ddffa20..dfeecfd1 100644
> --- a/libdtrace/dt_prov_fbt.c
> +++ b/libdtrace/dt_prov_fbt.c
> @@ -431,6 +431,7 @@ static void kprobe_detach(dtrace_hdl_t *dtp, const dt_probe_t *prp)
> dt_provimpl_t dt_fbt_fprobe = {
> .name = prvname,
> .prog_type = BPF_PROG_TYPE_TRACING,
> + .skip_frames = 4,
> .populate = &populate,
> .load_prog = &fprobe_prog_load,
> .trampoline = &fprobe_trampoline,
> diff --git a/libdtrace/dt_provider.h b/libdtrace/dt_provider.h
> index a24b1d00..bf3af0be 100644
> --- a/libdtrace/dt_provider.h
> +++ b/libdtrace/dt_provider.h
> @@ -44,6 +44,7 @@ typedef struct dt_argdesc {
> typedef struct dt_provimpl {
> const char *name; /* provider generic name */
> int prog_type; /* BPF program type */
> + uint32_t skip_frames; /* # of stack frames to skip */
> int (*populate)(dtrace_hdl_t *dtp); /* register probes */
> int (*provide)(dtrace_hdl_t *dtp, /* provide probes */
> const dtrace_probedesc_t *pdp);
> -- 2.42.0
More information about the DTrace-devel
mailing list