summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2020-04-23 14:54:13 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2020-04-23 14:54:13 +0000
commit8944c0b50a51cd93a68fbf485f97427e7ae53a07 (patch)
tree3e1ed7acb4779d8ff1362de758847276c03d98d4 /usr.sbin
parent2375802807d95213b35c045c12bf3df8fce597ab (diff)
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
Diffstat (limited to 'usr.sbin')
-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