From d2392c6601f5e1e0ca8bba14b1e856f43169c5e3 Mon Sep 17 00:00:00 2001 From: mpi Date: Wed, 21 Apr 2021 10:26:18 +0000 Subject: [PATCH] Extend print() to support any kind of variable. --- usr.sbin/btrace/bt_parse.y | 8 ++--- usr.sbin/btrace/bt_parser.h | 10 ++++-- usr.sbin/btrace/btrace.c | 64 ++++++++++++++++++++++++++++--------- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/usr.sbin/btrace/bt_parse.y b/usr.sbin/btrace/bt_parse.y index dc814246682..0fbf19ba6c6 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.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 @@ -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); } ; diff --git a/usr.sbin/btrace/bt_parser.h b/usr.sbin/btrace/bt_parser.h index 6cc84c32f34..5db6304d589 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.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 @@ -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) */ diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c index 9d3a269f5de..17bb7b187bf 100644 --- a/usr.sbin/btrace/btrace.c +++ b/usr.sbin/btrace/btrace.c @@ -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 @@ -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); -- 2.20.1