btrace(8): add initial support for cli arguments
authordv <dv@openbsd.org>
Wed, 8 Sep 2021 13:29:51 +0000 (13:29 +0000)
committerdv <dv@openbsd.org>
Wed, 8 Sep 2021 13:29:51 +0000 (13:29 +0000)
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 [new file with mode: 0644]
regress/usr.sbin/btrace/staticv.bt [new file with mode: 0644]
regress/usr.sbin/btrace/staticv.ok [new file with mode: 0644]
usr.sbin/btrace/TODO
usr.sbin/btrace/bt_parse.y
usr.sbin/btrace/bt_parser.h
usr.sbin/btrace/btrace.8
usr.sbin/btrace/btrace.c

diff --git a/regress/usr.sbin/btrace/staticv.args b/regress/usr.sbin/btrace/staticv.args
new file mode 100644 (file)
index 0000000..14646f2
--- /dev/null
@@ -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 (file)
index 0000000..f4adb2a
--- /dev/null
@@ -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 (file)
index 0000000..5fb7e5b
--- /dev/null
@@ -0,0 +1 @@
+3 42 1337 -2019
index aad8a66..f2f6a66 100644 (file)
@@ -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:
 
index e1e8da6..d5e567e 100644 (file)
@@ -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 <mpi@openbsd.org>
@@ -123,12 +123,11 @@ static int pflag;
 %token <v.number>      NUMBER
 
 %type  <v.string>      gvar lvar
-%type  <v.number>      staticv
 %type  <v.i>           beginend
 %type  <v.probe>       probe pname
 %type  <v.filter>      filter
 %type  <v.stmt>        action stmt stmtblck stmtlist block
-%type  <v.arg>         pat vargs mentry mpat pargs
+%type  <v.arg>         pat vargs mentry mpat pargs staticv
 %type  <v.arg>         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 }" */
index ec77e34..b7288e7 100644 (file)
@@ -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 <mpi@openbsd.org>
@@ -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,
index e6c5734..d5ff5f0 100644 (file)
@@ -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 <mpi@openbsd.org>
 .\"
@@ -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:
index ccdfabe..5fb1b60 100644 (file)
@@ -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 <mpi@openbsd.org>
@@ -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;