-# $OpenBSD: Makefile,v 1.22 2021/09/16 10:54:35 anton Exp $
+# $OpenBSD: Makefile,v 1.23 2021/10/03 22:01:48 dv Exp $
BTRACE?= /usr/sbin/btrace
ALLOWDT!= sysctl -n kern.allowdt
precedence print read-map-after-clear staticv-empty \
syntaxerror
+BT_ARG_LANG_SCRIPTS= staticv str
+
# scripts that use kernel probes
BT_KERN_SCRIPTS= multiprobe
cd ${.CURDIR} && ${BTRACE} $b.bt 2>&1 | diff -u $b.ok /dev/stdin
.endfor
-b=staticv
+.for b in ${BT_ARG_LANG_SCRIPTS}
REGRESS_TARGETS+= run-$b
run-$b:
- ${BTRACE} ${.CURDIR}/$b.bt 42 1337 -2019 2>&1 | \
+ cat ${.CURDIR}/$b.args | xargs ${BTRACE} ${.CURDIR}/$b.bt 2>&1 | \
diff -u ${.CURDIR}/$b.ok /dev/stdin
+.endfor
.for b in ${BT_KERN_SCRIPTS}
REGRESS_TARGETS+= run-$b
BEGIN {
- $str = "string";
+ $s = "string";
print(890);
- print($str);
+ print($s);
print(comm);
}
-.\" $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>
.\"
.\" 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
.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
-/* $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>
%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
%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 */
| 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); }
{ "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 },
-/* $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>
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) */
-/* $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>
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 *);
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);
}
debug("bv=%p var '%s' store (%p)\n", bv, bv_name(bv), bv->bv_value);
}
+/*
+ * 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; }
*/
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:
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;
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;
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:
-/* $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>
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 *);