Linux DTrace development list
 help / color / mirror / Atom feed
* [PATCH] cg: allow providers to specify a skip count for stack retrieval
@ 2024-05-01 18:22 Kris Van Hees
  2024-05-01 19:40 ` Eugene Loh
  0 siblings, 1 reply; 3+ messages in thread
From: Kris Van Hees @ 2024-05-01 18:22 UTC (permalink / raw)
  To: dtrace, dtrace-devel

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@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


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] cg: allow providers to specify a skip count for stack retrieval
  2024-05-01 18:22 [PATCH] cg: allow providers to specify a skip count for stack retrieval Kris Van Hees
@ 2024-05-01 19:40 ` Eugene Loh
  2024-05-01 20:12   ` Kris Van Hees
  0 siblings, 1 reply; 3+ messages in thread
From: Eugene Loh @ 2024-05-01 19:40 UTC (permalink / raw)
  To: dtrace, dtrace-devel

Reviewed-by: Eugene Loh <eugene.loh@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@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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] cg: allow providers to specify a skip count for stack retrieval
  2024-05-01 19:40 ` Eugene Loh
@ 2024-05-01 20:12   ` Kris Van Hees
  0 siblings, 0 replies; 3+ messages in thread
From: Kris Van Hees @ 2024-05-01 20:12 UTC (permalink / raw)
  To: Eugene Loh; +Cc: dtrace, dtrace-devel

On Wed, May 01, 2024 at 03:40:09PM -0400, Eugene Loh wrote:
> Reviewed-by: Eugene Loh <eugene.loh@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?

Ah yes, need to adjust that one also.  Thanks!

Incidentally, caller also needs to be fixed in this way.

AND this skip should NOT be applied to ustack() (nor ucaller and ustackdepth).

v2 coming soon :)

> 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@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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-05-01 20:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-01 18:22 [PATCH] cg: allow providers to specify a skip count for stack retrieval Kris Van Hees
2024-05-01 19:40 ` Eugene Loh
2024-05-01 20:12   ` Kris Van Hees

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox