summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorDave Voutila <dv@cvs.openbsd.org>2021-10-03 22:01:49 +0000
committerDave Voutila <dv@cvs.openbsd.org>2021-10-03 22:01:49 +0000
commit525ef8fe3a7e850248f2e9bb95b5b61c72f87bb7 (patch)
tree62f39d07dd27691679ebaa741ea2dc42d18be1a4 /usr.sbin
parentf22c4413f58e1caf03db48052895f1668dcb290b (diff)
bt(5)/btrace(8): add support for str()
Implement initial support for the str() function, which is used primarily to truncate or NUL-terminate strings from either cli args or args to tracepoints and syscalls. Current implementation only supports cli args and is primarily for compatability with bpftrace. Future work is needed once dt(4) supports builtin args other than long values. Adds a regress test and wires in argument-based tests again. ok mpi@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/btrace/bt.512
-rw-r--r--usr.sbin/btrace/bt_parse.y11
-rw-r--r--usr.sbin/btrace/bt_parser.h4
-rw-r--r--usr.sbin/btrace/btrace.c47
-rw-r--r--usr.sbin/btrace/btrace.h3
5 files changed, 67 insertions, 10 deletions
diff --git a/usr.sbin/btrace/bt.5 b/usr.sbin/btrace/bt.5
index a70f120fd11..3912c231adf 100644
--- a/usr.sbin/btrace/bt.5
+++ b/usr.sbin/btrace/bt.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bt.5,v 1.11 2021/04/21 10:22:36 mpi Exp $
+.\" $OpenBSD: bt.5,v 1.12 2021/10/03 22:01:48 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: October 3 2021 $
.Dt BT 5
.Os
.Sh NAME
@@ -154,11 +154,17 @@ entries in
.It Fn printf "fmt" ...
Print formatted string
.Va fmt .
+.It Fn str "$N" "[index]"
+Return the string from argument
+.Va $N ,
+truncated to
+.Va index
+characters (up to 64, the default) including a guaranteed NUL-terminator.
.It Fn sum
Returns the sum of all recorded values.
.It Fn time timefmt
Print timestamps using
-.Xr strftime 3
+.Xr strftime 3 .
.It Fn zero "@map"
Set all values from
.Va @map
diff --git a/usr.sbin/btrace/bt_parse.y b/usr.sbin/btrace/bt_parse.y
index faf2b05f119..f519efd87fd 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.43 2021/09/09 12:09:11 mpi Exp $ */
+/* $OpenBSD: bt_parse.y,v 1.44 2021/10/03 22:01:48 dv Exp $ */
/*
* Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
@@ -118,7 +118,7 @@ static int pflag;
%token <v.i> BUILTIN BEGIN END HZ IF
/* Functions and Map operators */
%token <v.i> F_DELETE F_PRINT
-%token <v.i> MFUNC FUNC0 FUNC1 FUNCN OP1 OP4 MOP0 MOP1
+%token <v.i> MFUNC FUNC0 FUNC1 FUNCN OP1 OP2 OP4 MOP0 MOP1
%token <v.string> STRING CSTRING
%token <v.number> NUMBER
@@ -128,7 +128,7 @@ static int pflag;
%type <v.filter> filter
%type <v.stmt> action stmt stmtblck stmtlist block
%type <v.arg> pat vargs mentry mpat pargs staticv
-%type <v.arg> expr term fterm variable factor
+%type <v.arg> expr term fterm variable factor func
%%
grammar : /* empty */
@@ -221,8 +221,12 @@ factor : '(' expr ')' { $$ = $2; }
| staticv
| variable
| mentry
+ | func
;
+func : STR '(' staticv ')' { $$ = ba_new($3, B_AT_FN_STR); }
+ | STR '(' staticv ',' pat ')' { $$ = ba_op(B_AT_FN_STR, $3, $5); }
+ ;
vargs : pat
| vargs ',' pat { $$ = ba_append($1, $3); }
@@ -714,6 +718,7 @@ lookup(char *s)
{ "print", F_PRINT, B_AC_PRINT },
{ "printf", FUNCN, B_AC_PRINTF },
{ "retval", BUILTIN, B_AT_BI_RETVAL },
+ { "str", STR, B_AT_FN_STR },
{ "sum", MOP1, B_AT_MF_SUM },
{ "tid", BUILTIN, B_AT_BI_TID },
{ "time", FUNC1, B_AC_TIME },
diff --git a/usr.sbin/btrace/bt_parser.h b/usr.sbin/btrace/bt_parser.h
index 20fde72791e..6ba180c4379 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.20 2021/09/09 09:53:11 mpi Exp $ */
+/* $OpenBSD: bt_parser.h,v 1.21 2021/10/03 22:01:48 dv Exp $ */
/*
* Copyright (c) 2019-2021 Martin Pieuchot <mpi@openbsd.org>
@@ -148,6 +148,8 @@ struct bt_arg {
B_AT_BI_ARGS,
B_AT_BI_RETVAL,
+ B_AT_FN_STR, /* str($1); str($1, 3); */
+
B_AT_MF_COUNT, /* @map[key] = count() */
B_AT_MF_MAX, /* @map[key] = max(nsecs) */
B_AT_MF_MIN, /* @map[key] = min(pid) */
diff --git a/usr.sbin/btrace/btrace.c b/usr.sbin/btrace/btrace.c
index 14a5212e2aa..e01569fb2d1 100644
--- a/usr.sbin/btrace/btrace.c
+++ b/usr.sbin/btrace/btrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.c,v 1.57 2021/09/21 21:33:35 bluhm Exp $ */
+/* $OpenBSD: btrace.c,v 1.58 2021/10/03 22:01:48 dv Exp $ */
/*
* Copyright (c) 2019 - 2021 Martin Pieuchot <mpi@openbsd.org>
@@ -82,6 +82,7 @@ void rule_printmaps(struct bt_rule *);
uint64_t builtin_nsecs(struct dt_evt *);
const char *builtin_kstack(struct dt_evt *);
const char *builtin_arg(struct dt_evt *, enum bt_argtype);
+struct bt_arg *fn_str(struct bt_arg *, struct dt_evt *, char *);
void stmt_eval(struct bt_stmt *, struct dt_evt *);
void stmt_bucketize(struct bt_stmt *, struct dt_evt *);
void stmt_clear(struct bt_stmt *);
@@ -915,6 +916,10 @@ stmt_store(struct bt_stmt *bs, struct dt_evt *dtev)
bv->bv_value = ba_new(ba2long(ba, dtev), B_AT_LONG);
bv->bv_type = B_VT_LONG;
break;
+ case B_AT_FN_STR:
+ bv->bv_value = ba_new(ba2str(ba, dtev), B_AT_STR);
+ bv->bv_type = B_VT_STR;
+ break;
default:
xabort("store not implemented for type %d", ba->ba_type);
}
@@ -923,6 +928,38 @@ stmt_store(struct bt_stmt *bs, struct dt_evt *dtev)
}
/*
+ * String conversion { str($1); string($1, 3); }
+ *
+ * Since fn_str is currently only called in ba2str, *buf should be a pointer
+ * to the static buffer provided by ba2str.
+ */
+struct bt_arg *
+fn_str(struct bt_arg *ba, struct dt_evt *dtev, char *buf)
+{
+ struct bt_arg *arg, *index;
+ ssize_t len = STRLEN;
+
+ assert(ba->ba_type == B_AT_FN_STR);
+
+ arg = (struct bt_arg*)ba->ba_value;
+ assert(arg != NULL);
+
+ index = SLIST_NEXT(arg, ba_next);
+ if (index != NULL) {
+ /* Should have only 1 optional argument. */
+ assert(SLIST_NEXT(index, ba_next) == NULL);
+ len = MINIMUM(ba2long(index, dtev) + 1, STRLEN);
+ }
+
+ /* All negative lengths behave the same as a zero length. */
+ if (len < 1)
+ return ba_new("", B_AT_STR);
+
+ strlcpy(buf, ba2str(arg, dtev), len);
+ return ba_new(buf, B_AT_STR);
+}
+
+/*
* Expression test: { if (expr) stmt; }
*/
bool
@@ -1216,6 +1253,8 @@ ba_name(struct bt_arg *ba)
return "args";
case B_AT_BI_RETVAL:
return "retval";
+ case B_AT_FN_STR:
+ return "str";
case B_AT_OP_PLUS:
return "+";
case B_AT_OP_MINUS:
@@ -1339,7 +1378,7 @@ ba2long(struct bt_arg *ba, struct dt_evt *dtev)
const char *
ba2str(struct bt_arg *ba, struct dt_evt *dtev)
{
- static char buf[sizeof("18446744073709551615")]; /* UINT64_MAX */
+ static char buf[STRLEN];
struct bt_var *bv;
const char *str;
@@ -1400,6 +1439,9 @@ ba2str(struct bt_arg *ba, struct dt_evt *dtev)
case B_AT_VAR:
str = ba2str(ba_read(ba), dtev);
break;
+ case B_AT_FN_STR:
+ str = (const char*)(fn_str(ba, dtev, buf))->ba_value;
+ break;
case B_AT_OP_PLUS ... B_AT_OP_LOR:
snprintf(buf, sizeof(buf), "%ld", ba2long(ba, dtev));
str = buf;
@@ -1463,6 +1505,7 @@ ba2dtflags(struct bt_arg *ba)
case B_AT_MF_MAX:
case B_AT_MF_MIN:
case B_AT_MF_SUM:
+ case B_AT_FN_STR:
case B_AT_OP_PLUS ... B_AT_OP_LOR:
break;
default:
diff --git a/usr.sbin/btrace/btrace.h b/usr.sbin/btrace/btrace.h
index a45fa98cfc2..ded754e3d18 100644
--- a/usr.sbin/btrace/btrace.h
+++ b/usr.sbin/btrace/btrace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: btrace.h,v 1.9 2021/02/08 09:46:45 mpi Exp $ */
+/* $OpenBSD: btrace.h,v 1.10 2021/10/03 22:01:48 dv Exp $ */
/*
* Copyright (c) 2019 - 2020 Martin Pieuchot <mpi@openbsd.org>
@@ -53,6 +53,7 @@ struct hist *hist_increment(struct hist *, const char *, long);
void hist_print(struct hist *, const char *);
#define KLEN 512 /* # of characters in map key, contain a stack trace */
+#define STRLEN 64 /* maximum # of bytes to output via str() function */
/* printf.c */
int stmt_printf(struct bt_stmt *, struct dt_evt *);