From 58afdee70d18227ff57089cd50d71573337e811d Mon Sep 17 00:00:00 2001 From: dv Date: Wed, 8 Sep 2021 13:29:51 +0000 Subject: [PATCH] btrace(8): add initial support for cli arguments This adds initial support for passing cli args to btrace(8) for use in bt(5) scripts. Similar to bpftrace, they are referenced via $1, $2, etc. with $# being the number of command line arguments provided. Adds an initial regress test and a Makefile change to allow providing arguments to regress tests in a .args file. Currently no limit is imposed on the number of arguments, keeping a similar approach as observed in bpftrace. References to undefined arguments result in a new "nil" type that contextually acts as a zero or empty string. More work can be done here to improve bpftrace compatibility. ok mpi@, jasper@ --- regress/usr.sbin/btrace/staticv.args | 1 + regress/usr.sbin/btrace/staticv.bt | 3 +++ regress/usr.sbin/btrace/staticv.ok | 1 + usr.sbin/btrace/TODO | 2 -- usr.sbin/btrace/bt_parse.y | 37 ++++++++++++++++++++-------- usr.sbin/btrace/bt_parser.h | 3 ++- usr.sbin/btrace/btrace.8 | 11 +++++---- usr.sbin/btrace/btrace.c | 30 +++++++++++----------- 8 files changed, 54 insertions(+), 34 deletions(-) create mode 100644 regress/usr.sbin/btrace/staticv.args create mode 100644 regress/usr.sbin/btrace/staticv.bt create mode 100644 regress/usr.sbin/btrace/staticv.ok diff --git a/regress/usr.sbin/btrace/staticv.args b/regress/usr.sbin/btrace/staticv.args new file mode 100644 index 00000000000..14646f2d360 --- /dev/null +++ b/regress/usr.sbin/btrace/staticv.args @@ -0,0 +1 @@ +42 1337 -2019 \ No newline at end of file diff --git a/regress/usr.sbin/btrace/staticv.bt b/regress/usr.sbin/btrace/staticv.bt new file mode 100644 index 00000000000..f4adb2a0355 --- /dev/null +++ b/regress/usr.sbin/btrace/staticv.bt @@ -0,0 +1,3 @@ +BEGIN { + printf("%d %d %d %d\n", $#, $1, $2, $3); +} diff --git a/regress/usr.sbin/btrace/staticv.ok b/regress/usr.sbin/btrace/staticv.ok new file mode 100644 index 00000000000..5fb7e5bdc3e --- /dev/null +++ b/regress/usr.sbin/btrace/staticv.ok @@ -0,0 +1 @@ +3 42 1337 -2019 diff --git a/usr.sbin/btrace/TODO b/usr.sbin/btrace/TODO index aad8a6657f4..f2f6a66af1f 100644 --- a/usr.sbin/btrace/TODO +++ b/usr.sbin/btrace/TODO @@ -7,8 +7,6 @@ Missing language features: - if/else - `args', tracepoint arguments support (requires kernel work) - str(args->buf, args->count) -- 'argv' -- $2, $3, $n (with n > 1) support Improvements: diff --git a/usr.sbin/btrace/bt_parse.y b/usr.sbin/btrace/bt_parse.y index e1e8da69648..d5e567e78a7 100644 --- a/usr.sbin/btrace/bt_parse.y +++ b/usr.sbin/btrace/bt_parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: bt_parse.y,v 1.39 2021/09/07 19:29:12 mpi Exp $ */ +/* $OpenBSD: bt_parse.y,v 1.40 2021/09/08 13:29:51 dv Exp $ */ /* * Copyright (c) 2019-2021 Martin Pieuchot @@ -123,12 +123,11 @@ static int pflag; %token NUMBER %type gvar lvar -%type staticv %type beginend %type probe pname %type filter %type action stmt stmtblck stmtlist block -%type pat vargs mentry mpat pargs +%type pat vargs mentry mpat pargs staticv %type expr term fterm variable factor %% @@ -150,8 +149,8 @@ pname : STRING ':' STRING ':' STRING { $$ = bp_new($1, $3, $5, 0); } | STRING ':' HZ ':' NUMBER { $$ = bp_new($1, "hz", NULL, $5); } ; -staticv : NUMBER - | '$' NUMBER { $$ = get_varg($2); } +staticv : '$' NUMBER { $$ = get_varg($2); } + | '$' '#' { $$ = get_nargs(); } ; gvar : '@' STRING { $$ = $2; } @@ -212,8 +211,9 @@ variable: lvar { $$ = bl_find($1); } ; factor : '(' expr ')' { $$ = $2; } - | staticv { $$ = ba_new($1, B_AT_LONG); } + | NUMBER { $$ = ba_new($1, B_AT_LONG); } | BUILTIN { $$ = ba_new(NULL, $1); } + | staticv | variable | mentry ; @@ -263,14 +263,31 @@ action : '{' stmtlist '}' { $$ = $2; } %% -int +struct bt_arg* get_varg(int index) { - extern int vargs[]; + extern int nargs; + extern char **vargs; + const char *errstr = NULL; + long val; + + if (0 < index && index <= nargs) { + val = (long)strtonum(vargs[index-1], LONG_MIN, LONG_MAX, + &errstr); + if (errstr == NULL) + return ba_new(val, B_AT_LONG); + return ba_new(vargs[index-1], B_AT_STR); + } - assert(index == 1); + return ba_new(0L, B_AT_NIL); +} + +struct bt_arg* +get_nargs(void) +{ + extern int nargs; - return vargs[index - 1]; + return ba_new((long) nargs, B_AT_LONG); } /* Create a new rule, representing "probe / filter / { action }" */ diff --git a/usr.sbin/btrace/bt_parser.h b/usr.sbin/btrace/bt_parser.h index ec77e345e1e..b7288e73675 100644 --- a/usr.sbin/btrace/bt_parser.h +++ b/usr.sbin/btrace/bt_parser.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bt_parser.h,v 1.18 2021/08/31 08:39:26 mpi Exp $ */ +/* $OpenBSD: bt_parser.h,v 1.19 2021/09/08 13:29:51 dv Exp $ */ /* * Copyright (c) 2019-2021 Martin Pieuchot @@ -125,6 +125,7 @@ struct bt_arg { B_AT_VAR, /* global/local variable */ B_AT_MAP, /* global map (@map[]) */ B_AT_HIST, /* histogram */ + B_AT_NIL, /* empty value */ B_AT_BI_PID, B_AT_BI_TID, diff --git a/usr.sbin/btrace/btrace.8 b/usr.sbin/btrace/btrace.8 index e6c57349523..d5ff5f03fae 100644 --- a/usr.sbin/btrace/btrace.8 +++ b/usr.sbin/btrace/btrace.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: btrace.8,v 1.5 2021/04/21 10:22:36 mpi Exp $ +.\" $OpenBSD: btrace.8,v 1.6 2021/09/08 13:29:51 dv Exp $ .\" .\" Copyright (c) 2019 Martin Pieuchot .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 21 2021 $ +.Dd $Mdocdate: September 8 2021 $ .Dt BTRACE 8 .Os .Sh NAME @@ -24,6 +24,7 @@ .Nm btrace .Op Fl lnv .Op Fl e Ar program | Ar file +.Op Ar argument ... .Sh DESCRIPTION The .Nm @@ -33,9 +34,9 @@ It interprets the .Xr bt 5 program in .Ar file -and communicates with the dynamic tracer device using the interface -described -in +with optional +.Ar arguments +and communicates with the dynamic tracer device using the interface described in .Xr dt 4 . .Pp The options are as follows: diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c index ccdfabea109..5fb1b601ae1 100644 --- a/usr.sbin/btrace/btrace.c +++ b/usr.sbin/btrace/btrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: btrace.c,v 1.48 2021/09/07 19:29:12 mpi Exp $ */ +/* $OpenBSD: btrace.c,v 1.49 2021/09/08 13:29:51 dv Exp $ */ /* * Copyright (c) 2019 - 2021 Martin Pieuchot @@ -115,7 +115,8 @@ size_t dt_ndtpi; /* # of elements in the array */ struct dt_evt bt_devt; /* fake event for BEGIN/END */ uint64_t bt_filtered; /* # of events filtered out */ -int vargs[1]; +char **vargs; +int nargs = 0; int verbose = 0; volatile sig_atomic_t quit_pending; @@ -131,7 +132,6 @@ main(int argc, char *argv[]) { int fd = -1, ch, error = 0; const char *filename = NULL, *btscript = NULL; - const char *errstr; int showprobes = 0, noaction = 0; setlocale(LC_ALL, ""); @@ -163,25 +163,17 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc > 0) { - if (btscript != NULL) - usage(); - + if (argc > 0 && btscript == NULL) { filename = argv[0]; btscript = read_btfile(filename); argc--; argv++; } - if (argc == 1) { - vargs[0] = strtonum(*argv, 1, INT_MAX, &errstr); - if (errstr != NULL) - errx(1, "invalid argument %s: %s", *argv, errstr); - argc--; - argv++; - } + nargs = argc; + vargs = argv; - if (argc != 0 || (btscript == NULL && !showprobes)) + if (btscript == NULL && !showprobes) usage(); if (btscript != NULL) { @@ -216,7 +208,7 @@ main(int argc, char *argv[]) __dead void usage(void) { - fprintf(stderr, "usage: %s [-lnv] [-e program | file]\n", + fprintf(stderr, "usage: %s [-lnv] [-e program | file] [argument ...]\n", getprogname()); exit(1); } @@ -1264,6 +1256,9 @@ ba2long(struct bt_arg *ba, struct dt_evt *dtev) val = ba2long(map_get((struct map *)bv->bv_value, ba2str(ba->ba_key, dtev)), dtev); break; + case B_AT_NIL: + val = 0L; + break; case B_AT_BI_PID: val = dtev->dtev_pid; break; @@ -1311,6 +1306,9 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev) snprintf(buf, sizeof(buf), "%ld",(long)ba->ba_value); str = buf; break; + case B_AT_NIL: + str = ""; + break; case B_AT_BI_KSTACK: str = builtin_stack(dtev, 1); break; -- 2.20.1