summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2020-04-23 14:54:12 +0000
committermpi <mpi@openbsd.org>2020-04-23 14:54:12 +0000
commit6f386ca5730c9fa4c12a842278e6f70e938ce66e (patch)
tree4f181aaf110859f71ab2b28a571bfd450c66cbc6
parentExplain in the DESCRIPTION section in which cases mixerctl should be used (diff)
downloadwireguard-openbsd-6f386ca5730c9fa4c12a842278e6f70e938ce66e.tar.xz
wireguard-openbsd-6f386ca5730c9fa4c12a842278e6f70e938ce66e.zip
Extend map to support keys composed of multiple arguments.
Keys are still strings representing the output value. The following example is now possible to count the number of "on CPU" events ordered by thread ID and executable name: # btrace -e 'tracepoint:sched:on__cpu { @[tid, comm] = count() }' ^C @[138836, idle0]: 830941 @[161307, sshd]: 716476 @[482901, softnet]: 582008 @[104443, systqmp]: 405749 @[269230, update]: 396133 @[326533, softclock]: 316926 @[61040, sshd]: 177201 @[453567, reaper]: 119676 @[446052, ksh]: 85675 @[26270, syslogd]: 66625 @[504699, sshd]: 52958 @[446052, sshd]: 32207 @[44046, tset]: 13333 @[162960, zerothread]: 101 @[313046, ntpd]: 1
-rw-r--r--usr.sbin/btrace/TODO5
-rw-r--r--usr.sbin/btrace/bt_parse.y8
-rw-r--r--usr.sbin/btrace/btrace.c114
3 files changed, 79 insertions, 48 deletions
diff --git a/usr.sbin/btrace/TODO b/usr.sbin/btrace/TODO
index 74f28acc5bd..a9e603f7161 100644
--- a/usr.sbin/btrace/TODO
+++ b/usr.sbin/btrace/TODO
@@ -7,9 +7,12 @@ Missing language features:
- if/else
- scratch variable ($name)
- `args', tracepoint arguments support (requires kernel work)
-- str()
+- str(args->buf, args->count)
- @ = hist(x)
- @ = lhist(x, min, max, step)
+- 'cpu' builtin, reports cpuid
+- 'argv'
+- $1 support
Improvements:
diff --git a/usr.sbin/btrace/bt_parse.y b/usr.sbin/btrace/bt_parse.y
index c17caea9829..6a6bef6ecaa 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.10 2020/03/27 09:37:06 mpi Exp $ */
+/* $OpenBSD: bt_parse.y,v 1.11 2020/04/23 14:54:12 mpi Exp $ */
/*
* Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -208,7 +208,7 @@ term : '(' term ')' { $$ = $2; }
gvar : '@' STRING { $$ = $2; }
| '@' { $$ = UNNAMED_MAP; }
-map : gvar '[' arg ']' { $$ = bm_get($1, $3); }
+map : gvar '[' arglist ']' { $$ = bm_get($1, $3); }
;
marg : arg { $$ = $1; }
@@ -229,7 +229,7 @@ NL : /* empty */ | '\n'
stmt : ';' NL { $$ = NULL; }
| gvar '=' arg { $$ = bv_set($1, $3); }
- | gvar '[' arg ']' '=' marg { $$ = bm_set($1, $3, $6); }
+ | gvar '[' arglist ']' '=' marg { $$ = bm_set($1, $3, $6); }
| fnN '(' arglist ')' { $$ = bs_new($1, $3, NULL); }
| fn1 '(' arg ')' { $$ = bs_new($1, $3, NULL); }
| fn0 '(' ')' { $$ = bs_new($1, NULL, NULL); }
@@ -695,7 +695,7 @@ again:
}
#define allowed_to_end_number(x) \
- (isspace(x) || x == ')' || x == '/' || x == '{' || x == ';' || x == ']')
+ (isspace(x) || x == ')' || x == '/' || x == '{' || x == ';' || x == ']' || x == ',')
/* parsing number */
if (isdigit(c)) {
diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c
index df59fc56d63..d0815350041 100644
--- a/usr.sbin/btrace/btrace.c
+++ b/usr.sbin/btrace/btrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.c,v 1.15 2020/04/23 09:14:27 mpi Exp $ */
+/* $OpenBSD: btrace.c,v 1.16 2020/04/23 14:54:12 mpi Exp $ */
/*
* Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -85,10 +85,8 @@ void stmt_store(struct bt_stmt *, struct dt_evt *);
void stmt_time(struct bt_stmt *, struct dt_evt *);
void stmt_zero(struct bt_stmt *);
struct bt_arg *ba_read(struct bt_arg *);
-int ba2dtflag(struct bt_arg *);
-
-/* FIXME: use a real hash. */
-#define ba2hash(_b, _e) ba2str((_b), (_e))
+const char *ba2hash(struct bt_arg *, struct dt_evt *);
+int ba2dtflags(struct bt_arg *);
/*
* Debug routines.
@@ -435,7 +433,7 @@ rules_setup(int fd)
struct bt_arg *ba;
SLIST_FOREACH(ba, &bs->bs_args, ba_next)
- dtrq->dtrq_evtflags |= ba2dtflag(ba);
+ dtrq->dtrq_evtflags |= ba2dtflags(ba);
}
if (dtrq->dtrq_evtflags & DTEVT_KSTACK)
@@ -819,6 +817,34 @@ ba_read(struct bt_arg *ba)
return bv->bv_value;
}
+const char *
+ba2hash(struct bt_arg *ba, struct dt_evt *dtev)
+{
+ static char buf[256];
+ char *hash;
+ int l, len;
+
+ l = snprintf(buf, sizeof(buf), "%s", ba2str(ba, dtev));
+ if (l < 0 || (size_t)l > sizeof(buf)) {
+ warn("string too long %d > %lu", l, sizeof(buf));
+ return buf;
+ }
+
+ len = 0;
+ while ((ba = SLIST_NEXT(ba, ba_next)) != NULL) {
+ len += l;
+ hash = buf + len;
+
+ l = snprintf(hash, sizeof(buf) - len, ", %s", ba2str(ba, dtev));
+ if (l < 0 || (size_t)l > (sizeof(buf) - len)) {
+ warn("hash too long %d > %lu", l + len, sizeof(buf));
+ break;
+ }
+ }
+
+ return buf;
+}
+
/*
* Helper to evaluate the operation encoded in `ba' and return its
* result.
@@ -966,52 +992,54 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev)
}
/*
- * Return dt(4) flag indicating which data should be recorded by the
+ * Return dt(4) flags indicating which data should be recorded by the
* kernel, if any, for a given `ba'.
*/
int
-ba2dtflag(struct bt_arg *ba)
+ba2dtflags(struct bt_arg *ba)
{
- int flag = 0;
+ int flags = 0;
if (ba->ba_type == B_AT_MAP)
ba = ba->ba_key;
- switch (ba->ba_type) {
- case B_AT_STR:
- case B_AT_LONG:
- case B_AT_VAR:
- break;
- case B_AT_BI_KSTACK:
- flag = DTEVT_KSTACK;
- break;
- case B_AT_BI_USTACK:
- flag = DTEVT_USTACK;
- break;
- case B_AT_BI_COMM:
- flag = DTEVT_EXECNAME;
- break;
- case B_AT_BI_PID:
- case B_AT_BI_TID:
- case B_AT_BI_NSECS:
- break;
- case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
- flag = DTEVT_FUNCARGS;
- break;
- case B_AT_BI_RETVAL:
- flag = DTEVT_RETVAL;
- break;
- case B_AT_MF_COUNT:
- case B_AT_MF_MAX:
- case B_AT_MF_MIN:
- case B_AT_MF_SUM:
- case B_AT_OP_ADD ... B_AT_OP_DIVIDE:
- break;
- default:
- xabort("invalid argument type %d", ba->ba_type);
- }
+ do {
+ switch (ba->ba_type) {
+ case B_AT_STR:
+ case B_AT_LONG:
+ case B_AT_VAR:
+ break;
+ case B_AT_BI_KSTACK:
+ flags |= DTEVT_KSTACK;
+ break;
+ case B_AT_BI_USTACK:
+ flags |= DTEVT_USTACK;
+ break;
+ case B_AT_BI_COMM:
+ flags |= DTEVT_EXECNAME;
+ break;
+ case B_AT_BI_PID:
+ case B_AT_BI_TID:
+ case B_AT_BI_NSECS:
+ break;
+ case B_AT_BI_ARG0 ... B_AT_BI_ARG9:
+ flags |= DTEVT_FUNCARGS;
+ break;
+ case B_AT_BI_RETVAL:
+ flags |= DTEVT_RETVAL;
+ break;
+ case B_AT_MF_COUNT:
+ case B_AT_MF_MAX:
+ case B_AT_MF_MIN:
+ case B_AT_MF_SUM:
+ case B_AT_OP_ADD ... B_AT_OP_DIVIDE:
+ break;
+ default:
+ xabort("invalid argument type %d", ba->ba_type);
+ }
+ } while ((ba = SLIST_NEXT(ba, ba_next)) != NULL);
- return flag;
+ return flags;
}
long