Extend print() to support any kind of variable.
authormpi <mpi@openbsd.org>
Wed, 21 Apr 2021 10:26:18 +0000 (10:26 +0000)
committermpi <mpi@openbsd.org>
Wed, 21 Apr 2021 10:26:18 +0000 (10:26 +0000)
usr.sbin/btrace/bt_parse.y
usr.sbin/btrace/bt_parser.h
usr.sbin/btrace/btrace.c

index dc81424..0fbf19b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bt_parse.y,v 1.24 2021/04/21 10:22:36 mpi Exp $       */
+/*     $OpenBSD: bt_parse.y,v 1.25 2021/04/21 10:26:18 mpi Exp $       */
 
 /*
  * Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
@@ -169,7 +169,7 @@ binop               : testop
                | '|'                           { $$ = B_AT_OP_BOR; }
                ;
 
-value          : NUMBER                        { $$ = $1; }
+value          : NUMBER
                | '$' NUMBER                    { $$ = get_varg($2); }
                ;
 
@@ -185,7 +185,7 @@ variable    : gvar                          { $$ = bv_get($1); }
 
 builtin                : PID                           { $$ = B_AT_BI_PID; }
                | TID                           { $$ = B_AT_BI_TID; }
-               | BUILTIN                       { $$ = $1; }
+               | BUILTIN
                ;
 
 mexpr          : MOP0 '(' ')'                  { $$ = ba_new(NULL, $1); }
@@ -214,7 +214,7 @@ vargs               : expr
                | vargs ',' expr                { $$ = ba_append($1, $3); }
                ;
 
-printargs      : gvar                          { $$ = bv_get($1); }
+printargs      : term
                | gvar ',' expr                 { $$ = ba_append(bv_get($1), $3); }
                ;
 
index 6cc84c3..5db6304 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bt_parser.h,v 1.13 2021/02/08 09:46:45 mpi Exp $      */
+/*     $OpenBSD: bt_parser.h,v 1.14 2021/04/21 10:26:18 mpi Exp $      */
 
 /*
  * Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
@@ -102,6 +102,12 @@ struct bt_var {
        SLIST_ENTRY(bt_var)      bv_next;       /* linkage in global list */
        const char              *bv_name;       /* name of the variable */
        struct bt_arg           *bv_value;      /* corresponding value */
+       enum bt_vartype {
+               B_VT_STR = 1,
+               B_VT_LONG,
+               B_VT_MAP,
+               B_VT_HIST,
+       }                        bv_type;
 };
 
 /*
@@ -114,7 +120,7 @@ struct bt_arg {
        SLIST_ENTRY(bt_arg)      ba_next;
        void                    *ba_value;
        struct bt_arg           *ba_key;        /* key for maps/histograms */
-       enum  bt_argtype {
+       enum bt_argtype {
                B_AT_STR = 1,                   /* C-style string */
                B_AT_LONG,                      /* Number (integer) */
                B_AT_VAR,                       /* global variable (@var) */
index 9d3a269..17bb7b1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: btrace.c,v 1.31 2021/04/21 10:22:36 mpi Exp $ */
+/*     $OpenBSD: btrace.c,v 1.32 2021/04/21 10:26:18 mpi Exp $ */
 
 /*
  * Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -108,6 +108,8 @@ void                         debug_dump_filter(struct bt_rule *);
 struct dtioc_probe_info        *dt_dtpis;      /* array of available probes */
 size_t                  dt_ndtpi;      /* # of elements in the array */
 
+struct dt_evt           bt_devt;       /* fake event for BEGIN/END */
+
 int                     vargs[1];
 int                     verbose = 0;
 volatile sig_atomic_t   quit_pending;
@@ -465,8 +467,14 @@ rules_setup(int fd)
        if (dokstack)
                kelf_open();
 
+       /* Initialize "fake" event for BEGIN/END */
+       bt_devt.dtev_pbn = -1;
+       memcpy(&bt_devt.dtev_comm, getprogname(), sizeof(bt_devt.dtev_comm));
+       bt_devt.dtev_pid = getpid();
+       bt_devt.dtev_tid = getthrid();
+
        if (rbegin)
-               rule_eval(rbegin, NULL);
+               rule_eval(rbegin, &bt_devt);
 
        /* Enable all probes */
        TAILQ_FOREACH(r, &g_rules, br_next) {
@@ -525,7 +533,7 @@ rules_teardown(int fd)
                kelf_close();
 
        if (rend)
-               rule_eval(rend, NULL);
+               rule_eval(rend, &bt_devt);
        else {
                debug("eval default 'end' rule\n");
 
@@ -595,20 +603,21 @@ rule_printmaps(struct bt_rule *r)
 
                SLIST_FOREACH(ba, &bs->bs_args, ba_next) {
                        struct bt_var *bv = ba->ba_value;
+                       struct map *map;
 
                        if (ba->ba_type != B_AT_MAP && ba->ba_type != B_AT_HIST)
                                continue;
 
-                       if (bv->bv_value != NULL) {
-                               struct map *map = (struct map *)bv->bv_value;
+                       map = (struct map *)bv->bv_value;
+                       if (map == NULL)
+                               continue;
 
-                               if (ba->ba_type == B_AT_MAP)
-                                       map_print(map, SIZE_T_MAX, bv_name(bv));
-                               else
-                                       hist_print((struct hist *)map, bv_name(bv));
-                               map_clear(map);
-                               bv->bv_value = NULL;
-                       }
+                       if (ba->ba_type == B_AT_MAP)
+                               map_print(map, SIZE_T_MAX, bv_name(bv));
+                       else
+                               hist_print((struct hist *)map, bv_name(bv));
+                       map_clear(map);
+                       bv->bv_value = NULL;
                }
        }
 }
@@ -718,6 +727,7 @@ stmt_bucketize(struct bt_stmt *bs, struct dt_evt *dtev)
 
        bv->bv_value = (struct bt_arg *)
            hist_increment((struct hist *)bv->bv_value, bucket, step);
+       bv->bv_type = B_VT_HIST;
 }
 
 
@@ -786,10 +796,11 @@ stmt_insert(struct bt_stmt *bs, struct dt_evt *dtev)
 
        bv->bv_value = (struct bt_arg *)map_insert((struct map *)bv->bv_value,
            hash, bval, dtev);
+       bv->bv_type = B_VT_MAP;
 }
 
 /*
- * Print map entries:  { print(@map[, 8]); }
+ * Print variables:    { print(890); print(@map[, 8]); print(comm); }
  *
  * In this case the global variable 'map' is pointed at by `ba'
  * and '8' is represented by `btop'.
@@ -802,7 +813,6 @@ stmt_print(struct bt_stmt *bs, struct dt_evt *dtev)
        size_t top = SIZE_T_MAX;
 
        assert(bs->bs_var == NULL);
-       assert(ba->ba_type == B_AT_VAR);
 
        /* Parse optional `top' argument. */
        btop = SLIST_NEXT(ba, ba_next);
@@ -810,9 +820,26 @@ stmt_print(struct bt_stmt *bs, struct dt_evt *dtev)
                assert(SLIST_NEXT(btop, ba_next) == NULL);
                top = ba2long(btop, dtev);
        }
+
+       /* Static argument. */
+       if (ba->ba_type != B_AT_VAR) {
+               assert(btop == NULL);
+               printf("%s\n", ba2str(ba, dtev));
+               return;
+       }
+
        debug("map=%p '%s' print (top=%d)\n", bv->bv_value, bv_name(bv), top);
 
-       map_print((struct map *)bv->bv_value, top, bv_name(bv));
+       /* Empty? */
+       if (bv->bv_value == NULL)
+               return;
+
+       if (bv->bv_type == B_VT_MAP)
+               map_print((struct map *)bv->bv_value, top, bv_name(bv));
+       else if (bv->bv_type == B_VT_HIST)
+               hist_print((struct hist *)bv->bv_value, bv_name(bv));
+       else
+               printf("%s\n", ba2str(ba, dtev));
 }
 
 /*
@@ -833,14 +860,21 @@ stmt_store(struct bt_stmt *bs, struct dt_evt *dtev)
        assert(SLIST_NEXT(ba, ba_next) == NULL);
 
        switch (ba->ba_type) {
+       case B_AT_STR:
+               bv->bv_value = ba;
+               bv->bv_type = B_VT_STR;
+               break;
        case B_AT_LONG:
                bv->bv_value = ba;
+               bv->bv_type = B_VT_LONG;
                break;
        case B_AT_BI_NSECS:
                bv->bv_value = ba_new(builtin_nsecs(dtev), B_AT_LONG);
+               bv->bv_type = B_VT_LONG;
                break;
        case B_AT_OP_PLUS ... B_AT_OP_LOR:
                bv->bv_value = ba_new(ba2long(ba, dtev), B_AT_LONG);
+               bv->bv_type = B_VT_LONG;
                break;
        default:
                xabort("store not implemented for type %d", ba->ba_type);