Skip to content

Commit

Permalink
Add support for built-in variable stackdepth
Browse files Browse the repository at this point in the history
Add space to the "mem" BPF map where we can write a stack of maximum
depth.  (This approach should be replaced eventually with a more general
mechanism for using scratch space.)

Since precompiled BPF code needs to verify the use of the new buffer, we
we make its offset and size available to get_bvar() via STKOFF and STKSIZ.

For DIF_VAR_STACKDEPTH, add code to write the stack and return its length.

Fix test/unittest/stackdepth/tst.value.d:

  *)  Use a probe that has a kernel stack.

  *)  Change the postprocessing to check properly whether a line is empty.

  *)  Remove xfail.

Consolidate stackdepth tests with other built-in-variable tests:

  *)  stackdepth/tst.default.d was already simply a subset of
      variables/bvar/tst.stackdepth.d and so can be deleted.

  *)  stackdepth/tst.value.* is moved to variables/bvar/tst.stackdepth2.*

Signed-off-by: Eugene Loh <eugene.loh@oracle.com>
Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>
  • Loading branch information
euloh authored and kvanhees committed Jun 18, 2021
1 parent 84606f8 commit c26d66d
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 25 deletions.
24 changes: 22 additions & 2 deletions bpf/get_bvar.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ extern struct bpf_map_def probes;
extern struct bpf_map_def state;

extern uint64_t STBSZ;
extern uint64_t STKOFF;
extern uint64_t STKSIZ;

#define error(dctx, fault, illval) \
({ \
Expand Down Expand Up @@ -54,8 +56,26 @@ noinline uint64_t dt_get_bvar(dt_dctx_t *dctx, uint32_t id)
case DIF_VAR_ARG9:
return mst->argv[id - DIF_VAR_ARG0];
case DIF_VAR_STACKDEPTH: {
/* FIXME: no stack() yet */
return 0;
uint32_t bufsiz = (uint32_t) (uint64_t) (&STKSIZ);
uint64_t flags = 0 & BPF_F_SKIP_FIELD_MASK;
char *buf = ((char *) dctx->buf) + ((uint64_t) &STKOFF);
uint64_t stacksize;

stacksize = bpf_get_stack(dctx->ctx, buf, bufsiz, flags);
if (stacksize < 0)
return error(dctx, DTRACEFLT_BADSTACK, 0 /* FIXME */);

/*
* While linux/bpf.h does not describe the meaning of
* bpf_get_stack()'s return value outside of its sign,
* it is presumably the length of the copied stack.
*
* If stacksize==bufsiz, presumably the stack is larger than
* what we can retrieve. But it's also possible that the
* buffer was exactly large enough. So, leave it to the user
* to interpret the result.
*/
return stacksize / sizeof(uint64_t);
}
case DIF_VAR_CALLER: {
uint64_t flags = 0 & BPF_F_SKIP_FIELD_MASK;
Expand Down
6 changes: 4 additions & 2 deletions libdtrace/dt_bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,10 @@ dt_bpf_gmap_create(dtrace_hdl_t *dtp)

if (create_gmap(dtp, "mem", BPF_MAP_TYPE_PERCPU_ARRAY,
sizeof(uint32_t),
roundup(sizeof(dt_mstate_t), 8) + 8 +
roundup(dtp->dt_maxreclen, 8), 1) == -1)
roundup(sizeof(dt_mstate_t), 8) + 8
+ roundup(dtp->dt_maxreclen, 8)
+ 8 * dtp->dt_options[DTRACEOPT_MAXFRAMES],
1) == -1)
return -1; /* dt_errno is set for us */

/*
Expand Down
2 changes: 2 additions & 0 deletions libdtrace/dt_bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ extern "C" {
#define DT_CONST_CLID 3
#define DT_CONST_ARGC 4
#define DT_CONST_STBSZ 5
#define DT_CONST_STKOFF 6
#define DT_CONST_STKSIZ 7

extern int perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu,
int group_fd, unsigned long flags);
Expand Down
7 changes: 7 additions & 0 deletions libdtrace/dt_cc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2331,6 +2331,13 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
case DT_CONST_STBSZ:
nrp->dofr_data = dtp->dt_strlen;
continue;
case DT_CONST_STKOFF:
nrp->dofr_data = roundup(dtp->dt_maxreclen, 8);
continue;
case DT_CONST_STKSIZ:
nrp->dofr_data = sizeof(uint64_t)
* dtp->dt_options[DTRACEOPT_MAXFRAMES];
continue;
default:
/* probe name -> value is probe id */
if (strchr(idp->di_name, ':') != NULL)
Expand Down
2 changes: 2 additions & 0 deletions libdtrace/dt_dlibs.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ static const dt_ident_t dt_bpf_symbols[] = {
DT_BPF_SYMBOL_ID(CLID, DT_IDENT_SCALAR, DT_CONST_CLID),
DT_BPF_SYMBOL_ID(ARGC, DT_IDENT_SCALAR, DT_CONST_ARGC),
DT_BPF_SYMBOL_ID(STBSZ, DT_IDENT_SCALAR, DT_CONST_STBSZ),
DT_BPF_SYMBOL_ID(STKOFF, DT_IDENT_SCALAR, DT_CONST_STKOFF),
DT_BPF_SYMBOL_ID(STKSIZ, DT_IDENT_SCALAR, DT_CONST_STKSIZ),
/* End-of-list marker */
{ NULL, }
};
Expand Down
20 changes: 0 additions & 20 deletions test/unittest/stackdepth/tst.default.d

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
/* @@xfail: dtv2 */

#pragma D option destructive
#pragma D option quiet
Expand Down
File renamed without changes.
File renamed without changes.

0 comments on commit c26d66d

Please sign in to comment.