Merge branch 'freebsd/current/main' into hardened/current/master

This commit is contained in:
HardenedBSD Sync Services 2024-01-10 18:01:41 -07:00
commit 82ca9e264b
No known key found for this signature in database
64 changed files with 3824 additions and 193 deletions

View File

@ -3142,6 +3142,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
${_cddl_lib_libctf} ${_cddl_lib_libzfsbootenv} \
lib/libufs \
lib/libutil lib/libpjdlog ${_lib_libypclnt} lib/libz lib/msun \
lib/libxo \
${_secure_lib_libcrypto} ${_secure_lib_libssl} \
${_lib_libldns} ${_secure_lib_libssh}
@ -3197,6 +3198,7 @@ _generic_libs+= ${_DIR}
.endfor
lib/libtacplus__L: lib/libmd__L lib/libpam/libpam__L
lib/libxo__L: lib/libutil__L
.if ${MK_CDDL} != "no"
_cddl_lib_libumem= cddl/lib/libumem
@ -3237,6 +3239,7 @@ lib/libbe__L: cddl/lib/libzfs__L cddl/lib/libzfsbootenv__L
_cddl_lib_libctf= cddl/lib/libctf
_cddl_lib= cddl/lib
cddl/lib/libctf__L: lib/libz__L cddl/lib/libspl__L
cddl/lib/libdtrace__L: lib/libxo__L
.endif
# cddl/lib/libdtrace requires lib/libproc and lib/librtld_db
_prebuild_libs+= lib/libprocstat lib/libproc lib/librtld_db

View File

@ -18,7 +18,9 @@
.\" CDDL HEADER END
.\" Copyright (c) 2006, Sun Microsystems, Inc. All Rights Reserved.
.\"
.Dd February 24, 2023
.\" $FreeBSD$
.\"
.Dd September 8, 2023
.Dt DTRACE 1
.Os
.Sh NAME
@ -27,7 +29,8 @@
.Sh SYNOPSIS
.Nm
.Op Fl 32 | Fl 64
.Op Fl aACdeFGhHlqSvVwZ
.Op Fl aACdeFGhHlOqSvVwZ
.Op Fl -libxo
.Op Fl b Ar bufsz
.Op Fl c Ar cmd
.Op Fl D Ar name Op Ns = Ns value
@ -355,6 +358,11 @@ writing D programs.
The specified
.Ar path
is added after the default library search path.
.It Fl -libxo
Generate output via
.Xr libxo 3 .
This option is the same as specifying
.Sy oformat .
.It Fl m Oo Ar provider : Oc Ar module Oo Oo Ar predicate Oc Ar action Oc
Specify module name to trace or list
.Fl ( l
@ -398,6 +406,14 @@ argument can be suffixed with an optional D probe clause.
More than one
.Fl n
option can be specified on the command line at a time.
.It Fl O
This option causes
.Nm
to print all the aggregations upon exiting if
.Sy oformat
or
.Fl -libxo
are specified.
.It Fl o Ar output
Specify the
.Ar output
@ -650,6 +666,32 @@ Number of whitespace characters to use when indenting
and
.Fn ustack
output.
.It Sy oformat Ns = Ns Ar format
Specify the format to use for output.
Setting
.Sy oformat
to
.Ql text
makes
.Nm
use regular human-readable output which is its default behavior.
The options passed to
.Sy oformat
are directly forwarded to
.Xr libxo 3 .
Some of the supported formatters include
.Ql json ,
.Ql xml
and
.Ql html .
Note that this option will cause
.Nm
to not produce any output unless printing functions are explicitly called,
or the
.Fl O
flag is specified.
For more information see
.Sx STRUCTURED OUTPUT .
.It Sy statusrate Ns = Ns Ar time
Rate of status checking.
.It Sy switchrate Ns = Ns Ar time
@ -776,6 +818,376 @@ or
.Fl i
options) contain descriptions that do not match any known probes.
.El
.Sh STRUCTURED OUTPUT
.Nm
supports structured output using
.Xr libxo 3 .
The output will always have a top-level object called
.Dq dtrace ,
followed by a list of objects
.Dq probes .
Each of the probe objects will to have a timestamp which is generated at
output time rather than probe firing time, an identifier for the CPU on
which the probe was executed, and the probe's full specification:
.Bd -literal
{
"dtrace": {
"probes": [
{
"timestamp": ...,
"cpu": ...,
"id": ...,
"provider": ...,
"module": ...,
"function": ...,
"name": ...,
"output": [
... (script-specific output)
]
}
]
}
}
<?xml version="1.0"?>
<dtrace>
<probes>
<timestamp>...</timestamp>
<cpu>...</cpu>
<id>...</id>
<provider>...</provider>
<module>...</module>
<function>...</function>
<name>...</name>
<output>
... (script-specific output)
</output>
</probes>
</dtrace>
.Ed
.Pp
It is also possible for XML output to take the following form if some
of the fields are empty (in this example, module and function values
are absent):
.Bd -literal
<?xml version="1.0"?>
<dtrace>
<probes>
...
<module/>
<function/>
...
<output>
... (script-specific output)
</output>
</probes>
</dtrace>
.Ed
.Pp
Similarly,
.Sy oformat
can be used to generate HTML:
.Bd -literal
<div class="line">
<div class="data" data-tag="timestamp">...</div>
<div class="text"></div>
<div class="data" data-tag="cpu">...</div>
<div class="text"></div>
<div class="data" data-tag="id">...</div>
<div class="text"></div>
<div class="data" data-tag="provider">...</div>
<div class="text"></div>
<div class="data" data-tag="module">...</div>
<div class="text"></div>
<div class="data" data-tag="function">...</div>
<div class="text"></div>
<div class="data" data-tag="name">...</div>
<div class="data" data-tag="... (script-specific output)">...</div>
</div>
.Ed
.Pp
Unlike JSON and XML, the
.Dq output
array is not present.
Instead, data is simply formatted into a div of class
.Dq data
and a data-tag is associated with each of the keys.
.Pp
The
.Dq output
array's contents depend on the probes' actions and is explained below.
The examples here are presented in JSON form as opposed to XML or HTML,
however the conversion explained above applies for all output formats.
.Pp
Any scalar output, such as output produced by the
.Fn trace
action is of form:
.Bd -literal
{
"value": ...
}
.Ed
.Pp
The
.Fn printf
action begins with an object containing the formatted output of the
.Fn printf
action.
Subsequent objects contains the value of each of the arguments to
.Fn printf
in its raw form as if the
.Fn trace
action was used instead.
A
.Fn printf
statement which contains no arguments other than the message will only have
one object following the message object and its value will always be 0.
This is an artefact of the implementation and can safely be ignored.
.Bd -literal
# dtrace --libxo json,pretty -n 'BEGIN { printf("... %Y, ..", walltimestamp); }'
{
"message": "... 2023 Sep 7 16:49:02, .."
},
{
"value": 1694105342633402400
},
{
...
}
.Ed
.Pp
Scalar aggregations are aggregations which produce a single value for a given
key.
These aggregations include
.Fn count ,
.Fn min ,
.Fn max ,
.Fn stddev
and
.Fn sum .
Each one of them is represented by the key containing their name.
For example, the output of a
.Fn stddev
aggregation will contain a key
.Dq stddev
inside an
.Dq aggregation-data
object:
.Bd -literal
{
"aggregation-data": [
{
"keys": [
...
],
"stddev": ...
}
],
"aggregation-name": ...
}
.Ed
.Pp
The
.Dq keys
field remains consistent across all aggregations, however
.Fn quantize ,
.Fn lquantize
and
.Fn llquantize
need to be treated differently.
.Sy oformat
will create a new array of objects called
.Dq buckets .
Each of the objects contains a
.Dq value
and a
.Dq count
field which are
the left-hand side and the right-hand side of human-readable
.Nm
output respectively.
The full object has the following format:
.Bd -literal
{
"aggregation-data": [
...
{
"keys": [
...
],
"buckets": [
{
"value": 32,
"count": 0
},
{
"value": 64,
"count": 17
},
...
],
},
...
]
"aggregation-name": ...
}
.Ed
.Pp
Similar to scalar aggregations, named scalar actions such as
.Fn mod ,
.Fn umod ,
.Fn usym ,
.Fn tracemem
and
.Fn printm
will output an object with the key being equal to the
name of the action.
For example,
.Fn printm
output would produce the following object:
.Bd -literal
{
"printm": "0x4054171100"
}
.Ed
.Pp
.Fn sym
is slightly different.
While it will create a
.Dq sym
field which contains its value, in some cases it will also create additional
fields
.Dq object ,
.Dq name
and
.Dq offset :
.Bd -literal
# dtrace -x oformat=json,pretty -On 'BEGIN { sym((uintptr_t)&`prison0); }'
{
"sym": "kernel`prison0",
"object": "kernel",
"name": "prison0"
}
# dtrace --libxo json,pretty -On 'BEGIN { sym((uintptr_t)curthread); }'
{
"sym": "0xfffffe00c18d2000",
"offset": "0xfffffe00c18d2000"
}
.Ed
.Pp
.Fn stack
and
.Fn ustack
actions unroll each of the stack frames into its own object in an array.
The only real difference between them is that the
.Fn stack
action will produce a list called
.Dq stack-frames
while
.Fn ustack
will produce one called
.Dq ustack-frames .
The following is an example of their
.Sy oformat
output:
.Bd -literal
{
"stack-frames": [
{
"symbol": "dtrace.ko`dtrace_dof_create+0x35",
"module": "dtrace.ko",
"name": "dtrace_dof_create",
"offset": "0x35"
},
{
"symbol": "dtrace.ko`dtrace_ioctl+0x81c",
"module": "dtrace.ko",
"name": "dtrace_ioctl",
"offset": "0x81c"
},
...
]
}
{
"ustack-frames": [
{
"symbol": "libc.so.7`ioctl+0xa",
"module": "libc.so.7",
"name": "ioctl",
"offset": "0xa"
},
{
"symbol": "libdtrace.so.2`dtrace_go+0xf3",
"module": "libdtrace.so.2",
"name": "dtrace_go",
"offset": "0xf3"
},
...
]
}
.Ed
.Pp
The
.Fn print
action produces a
.Dq type
list in the following form:
.Bd -literal
{
"type": [
{
"object-name": "kernel",
"name": "struct thread",
"ctfid": 2372
},
{
"member-name": "td_lock",
"name": "struct mtx *volatile",
"ctfid": 2035,
"value": "0xffffffff82158440"
},
...
}
.Ed
.Pp
If the type is invalid, a
.Dq warning
object will be produced containing the diagnostic message as well as two
possible optional fields:
.Dq type-identifier
which contains the CTF identifier of the type and
.Dq size containing the size of an integer, enum or float.
The fields generated will depend on the kind of error that was encountered
while processing the trace data.
.Pp
Finally,
.Sy oformat
provides a special pseudo-probe to represent drops.
As
.Nm
polls for various kinds of drops
.Sy oformat
will produce output similar to the following in order to represent drops:
.Bd -literal
{
"cpu": -1,
"id": -1,
"provider": "dtrace",
"module": "INTERNAL",
"function": "INTERNAL",
"name": "DROP",
"timestamp": ...,
"count": ...,
"total": ...,
"kind": 2,
"msg": "... dynamic variable drops\n"
}
.Ed
.Sh OPERANDS
You can specify zero or more additional arguments on the
.Nm

View File

@ -26,6 +26,7 @@
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2023, Domagoj Stolfa. All rights reserved.
*/
#include <sys/types.h>
@ -55,6 +56,9 @@
#include <spawn.h>
#endif
#undef NORETURN /* needed because libxo redefines it */
#include <libxo/xo.h>
typedef struct dtrace_cmd {
void (*dc_func)(struct dtrace_cmd *); /* function to compile arg */
dtrace_probespec_t dc_spec; /* probe specifier context */
@ -77,7 +81,7 @@ typedef struct dtrace_cmd {
#define E_USAGE 2
static const char DTRACE_OPTSTR[] =
"3:6:aAb:Bc:CdD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
"3:6:aAb:Bc:CdD:ef:FGhHi:I:lL:m:n:o:Op:P:qs:SU:vVwx:X:Z";
static char **g_argv;
static int g_argc;
@ -167,6 +171,7 @@ usage(FILE *fp)
"\t-m enable or list probes matching the specified module name\n"
"\t-n enable or list probes matching the specified probe name\n"
"\t-o set output file\n"
"\t-O print output upon exiting (specific to oformat)\n"
"\t-p grab specified process-ID and cache its symbol tables\n"
"\t-P enable or list probes matching the specified provider name\n"
"\t-q set quiet mode (only output explicitly traced data)\n"
@ -907,7 +912,10 @@ errhandler(const dtrace_errdata_t *data, void *arg)
static int
drophandler(const dtrace_dropdata_t *data, void *arg)
{
error(data->dtdda_msg);
if (!dtrace_oformat(g_dtp)) {
error(data->dtdda_msg);
}
return (DTRACE_HANDLE_OK);
}
@ -1126,7 +1134,9 @@ chew(const dtrace_probedata_t *data, void *arg)
}
if (!g_flowindent) {
if (!g_quiet) {
if (dtrace_oformat(g_dtp)) {
dtrace_oformat_probe(g_dtp, data, cpu, pd);
} else if (!g_quiet) {
char name[DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 2];
(void) snprintf(name, sizeof (name), "%s:%s",
@ -1313,7 +1323,8 @@ main(int argc, char *argv[])
g_ofp = stdout;
int done = 0, mode = 0;
int err, i, c;
int err, i, c, new_argc, libxo_specified;
int print_upon_exit = 0;
char *p, **v;
struct ps_prochandle *P;
pid_t pid;
@ -1336,6 +1347,15 @@ main(int argc, char *argv[])
(g_psv = malloc(sizeof (struct ps_prochandle *) * argc)) == NULL)
fatal("failed to allocate memory for arguments");
new_argc = xo_parse_args(argc, argv);
if (new_argc < 0)
return (usage(stderr));
if (new_argc != argc)
libxo_specified = 1;
argc = new_argc;
g_argv[g_argc++] = argv[0]; /* propagate argv[0] to D as $0/$$0 */
argv[0] = g_pname; /* rewrite argv[0] for getopt errors */
@ -1532,6 +1552,10 @@ main(int argc, char *argv[])
} else if (g_mode == DMODE_ANON)
(void) dtrace_setopt(g_dtp, "linkmode", "primary");
if (libxo_specified)
dtrace_oformat_configure(g_dtp);
/*
* Now that we have libdtrace open, make a second pass through argv[]
* to perform any dtrace_setopt() calls and change any compiler flags.
@ -1624,6 +1648,10 @@ main(int argc, char *argv[])
dcp->dc_arg = optarg;
break;
case 'O':
print_upon_exit = 1;
break;
case 'q':
if (dtrace_setopt(g_dtp, "quiet", 0) != 0)
dfatal("failed to set -q");
@ -1765,6 +1793,11 @@ main(int argc, char *argv[])
(void) dtrace_getopt(g_dtp, "quiet", &opt);
g_quiet = opt != DTRACEOPT_UNSET;
if (dtrace_oformat(g_dtp)) {
if (dtrace_setopt(g_dtp, "quiet", 0) != 0)
dfatal("failed to set quiet (caused by oformat)");
}
/*
* Now make a fifth and final pass over the options that have been
* turned into programs and saved in g_cmdv[], performing any mode-
@ -1777,6 +1810,9 @@ main(int argc, char *argv[])
if (g_ofile != NULL && (g_ofp = fopen(g_ofile, "a")) == NULL)
fatal("failed to open output file '%s'", g_ofile);
if (dtrace_oformat(g_dtp))
dtrace_set_outfp(g_ofp);
for (i = 0; i < g_cmdc; i++)
exec_prog(&g_cmdv[i]);
@ -1811,6 +1847,9 @@ main(int argc, char *argv[])
if ((g_ofp = fopen(g_ofile, "a")) == NULL)
fatal("failed to open output file '%s'", g_ofile);
if (dtrace_oformat(g_dtp))
dtrace_set_outfp(g_ofp);
for (i = 0; i < g_cmdc; i++) {
anon_prog(&g_cmdv[i],
dtrace_dof_create(g_dtp, g_cmdv[i].dc_prog, 0), i);
@ -1971,12 +2010,21 @@ main(int argc, char *argv[])
g_pslive = g_psc; /* count for prochandler() */
dtrace_oformat_setup(g_dtp);
do {
if (!g_intr && !done)
dtrace_sleep(g_dtp);
#ifdef __FreeBSD__
if (g_siginfo) {
/*
* XXX: Supporting SIGINFO with oformat makes little sense, as
* it can't really produce sensible DTrace output.
*
* If needed, we could support it by having an imaginary
* "SIGINFO" probe that we can construct in the output but leave
* it out for now.
*/
if (g_siginfo && !dtrace_oformat(g_dtp)) {
(void)dtrace_aggregate_print(g_dtp, g_ofp, NULL);
g_siginfo = 0;
}
@ -2013,14 +2061,24 @@ main(int argc, char *argv[])
clearerr(g_ofp);
} while (!done);
oprintf("\n");
if (!dtrace_oformat(g_dtp))
oprintf("\n");
if (!g_impatient) {
/*
* Since there is no way to format a probe here and machine-readable
* output makes little sense without explicitly asking for it, we print
* nothing upon Ctrl-C if oformat is specified. If the user wishes to
* get output upon exit, they must write an explicit dtrace:::END probe
* to do so.
*/
if ((!g_impatient && !dtrace_oformat(g_dtp)) ||
(!g_impatient && print_upon_exit)) {
if (dtrace_aggregate_print(g_dtp, g_ofp, NULL) == -1 &&
dtrace_errno(g_dtp) != EINTR)
dfatal("failed to print aggregations");
}
dtrace_oformat_teardown(g_dtp);
dtrace_close(g_dtp);
return (g_status);
}

View File

@ -1,6 +1,6 @@
PING6(56=40+8+8 bytes) ::1 --> ::1
PING(56=40+8+8 bytes) ::1 --> ::1
1 packets transmitted, 1 packets received, 0.0% packet loss
2 ip:::send (args[2]: 6 16, args[5]: 6 0 16)
2 ip:::send (args[2]: 6 16, args[5]: 6 0 16)

View File

@ -59,7 +59,7 @@ pinger()
{
while true; do
ping -A inet localhost
/usr/bin/sleep 1
sleep 1
done
}

View File

@ -54,7 +54,7 @@ rupper()
{
while true; do
rup localhost
/usr/bin/sleep 1
sleep 1
done
}

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[probefunc] = avg(tid);
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[execname] = count();
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,73 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
self->ts = timestamp;
}
syscall:::return
/self->ts/
{
@[probefunc] = llquantize(timestamp - self->ts, 2, 1, 32, 32);
self->ts = 0;
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,73 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
self->ts = timestamp;
}
syscall:::return
/self->ts/
{
@[probefunc] = lquantize(timestamp - self->ts, 0, 1000000, 100);
self->ts = 0;
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[probefunc] = max(tid);
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[probefunc] = min(tid);
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,73 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
self->ts = timestamp;
}
syscall:::return
/self->ts/
{
@[probefunc] = quantize(timestamp - self->ts);
self->ts = 0;
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[probefunc] = stddev(tid);
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[probefunc] = sum(1);
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[mod((uintptr_t)rand())] = count();
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
fbt:::entry
{
@[stack()] = count();
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[sym((uintptr_t)rand())] = count();
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[ustack()] = count();
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
@[usym((uintptr_t)rand())] = count();
}
tick-5s
{
exit(0);
}
END
{
printa(@);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,61 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
fbt:::entry
{
x[timestamp] = 1;
}
tick-5s
{
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,57 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
mod(0);
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,60 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
print(*curthread);
print(*curthread->td_proc);
print(*curthread->td_ucred);
print(*curthread->td_ucred->cr_prison);
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,57 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
printf("Hello World!");
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,57 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
printm(100, memref(curthread, 10));
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,61 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
stack();
}
tick-1s
{
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,57 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
sym(0);
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,66 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
trace(0);
trace(1);
trace(2);
trace(3);
trace(4);
trace(5);
trace(6);
trace(7);
trace(8);
trace(9);
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,57 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
tracemem(curthread, 10);
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,57 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
umod(0);
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,61 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
syscall:::entry
{
ustack();
}
tick-1s
{
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -0,0 +1,57 @@
#!/usr/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
#
# Copyright (c) 2023 Domagoj Stolfa
#
bname=`basename $0`
dtraceout=/tmp/dtrace.$bname
script()
{
$dtrace -o $dtraceout.$1 -x oformat=$1 -s /dev/stdin <<__EOF__
BEGIN
{
usym(0);
exit(0);
}
__EOF__
}
if [ $# != 1 ]; then
echo expected one argument: '<'dtrace-path'>'
exit 2
fi
dtrace=$1
script json
jq . $dtraceout.json
if [ $? != 0 ]; then
echo $bname: failed to produce valid JSON. see $dtraceout.json
exit 1
fi
script xml
xmllint $dtraceout.xml
if [ $? != 0 ]; then
echo $bname: failed to produce valid XML. see $dtraceout.xml
exit 1
fi
rm $dtraceout.json
rm $dtraceout.xml
exit 0

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -68,7 +68,7 @@ EOF
sleeper()
{
while true; do
/usr/bin/sleep 1
sleep 1
done
}

View File

@ -1,4 +1,4 @@
#!/usr/bin/env ksh
#!/usr/local/bin/ksh -p
#
# CDDL HEADER START
#

View File

@ -45,7 +45,7 @@ outf=/tmp/sched.args.$$
script()
{
$dtrace -c '/usr/bin/sleep 10' -o $outf -qs /dev/stdin <<EOF
$dtrace -c 'sleep 10' -o $outf -qs /dev/stdin <<EOF
xdt:sched::off-cpu,
xdt:sched::on-cpu,
xdt:sched::block,

View File

@ -35,6 +35,7 @@
#include <unistd.h>
#include <dt_impl.h>
#include <assert.h>
#include <dt_oformat.h>
#ifdef illumos
#include <alloca.h>
#else
@ -471,9 +472,14 @@ dt_aggregate_snap_cpu(dtrace_hdl_t *dtp, processorid_t cpu)
}
if (buf->dtbd_drops != 0) {
xo_open_instance("probes");
dt_oformat_drop(dtp, cpu);
if (dt_handle_cpudrop(dtp, cpu,
DTRACEDROP_AGGREGATION, buf->dtbd_drops) == -1)
DTRACEDROP_AGGREGATION, buf->dtbd_drops) == -1) {
xo_close_instance("probes");
return (-1);
}
xo_close_instance("probes");
}
if (buf->dtbd_size == 0)
@ -2127,8 +2133,13 @@ dtrace_aggregate_print(dtrace_hdl_t *dtp, FILE *fp,
if (func == NULL)
func = dtrace_aggregate_walk_sorted;
if ((*func)(dtp, dt_print_agg, &pd) == -1)
return (dt_set_errno(dtp, dtp->dt_errno));
if (dtp->dt_oformat) {
if ((*func)(dtp, dt_format_agg, &pd) == -1)
return (dt_set_errno(dtp, dtp->dt_errno));
} else {
if ((*func)(dtp, dt_print_agg, &pd) == -1)
return (dt_set_errno(dtp, dtp->dt_errno));
}
return (0);
}

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@
#endif
#include <dt_impl.h>
#include <dt_oformat.h>
#include <dt_program.h>
static const char _dt_errprog[] =
@ -315,6 +316,7 @@ dt_handle_cpudrop(dtrace_hdl_t *dtp, processorid_t cpu,
dtrace_dropdata_t drop;
char str[80], *s;
int size;
struct timeval tv;
assert(what == DTRACEDROP_PRINCIPAL || what == DTRACEDROP_AGGREGATION);
@ -339,6 +341,15 @@ dt_handle_cpudrop(dtrace_hdl_t *dtp, processorid_t cpu,
what == DTRACEDROP_PRINCIPAL ? "" : "aggregation ",
howmany > 1 ? "s" : "", cpu);
if (dtp->dt_oformat) {
(void) gettimeofday(&tv, NULL);
xo_emit("{:timestamp/%ld.%06ld} {:count/%ju} "
"{:total/%ju} {:kind/%d} {:msg/%s}",
tv.tv_sec, tv.tv_usec, (uintmax_t)drop.dtdda_drops,
(uintmax_t)drop.dtdda_total, drop.dtdda_kind,
drop.dtdda_msg);
}
if (dtp->dt_drophdlr == NULL)
return (dt_set_errno(dtp, EDT_DROPABORT));
@ -396,6 +407,7 @@ dt_handle_status(dtrace_hdl_t *dtp, dtrace_status_t *old, dtrace_status_t *new)
char str[80], *s;
uintptr_t base = (uintptr_t)new, obase = (uintptr_t)old;
int i, size;
struct timeval tv;
bzero(&drop, sizeof (drop));
drop.dtdda_handle = dtp;
@ -408,6 +420,8 @@ dt_handle_status(dtrace_hdl_t *dtp, dtrace_status_t *old, dtrace_status_t *new)
if (new->dtst_killed && !old->dtst_killed)
return (dt_set_errno(dtp, EDT_BRICKED));
(void) gettimeofday(&tv, NULL);
for (i = 0; _dt_droptab[i].dtdrt_str != NULL; i++) {
uintptr_t naddr = base + _dt_droptab[i].dtdrt_offset;
uintptr_t oaddr = obase + _dt_droptab[i].dtdrt_offset;
@ -438,12 +452,31 @@ dt_handle_status(dtrace_hdl_t *dtp, dtrace_status_t *old, dtrace_status_t *new)
drop.dtdda_total = nval;
drop.dtdda_drops = nval - oval;
if (dtp->dt_drophdlr == NULL)
if (dtp->dt_oformat) {
xo_open_instance("probes");
dt_oformat_drop(dtp, DTRACE_CPUALL);
xo_emit("{:timestamp/%ld.%06ld} {:count/%ju} "
"{:total/%ju} {:kind/%d} {:msg/%s}",
tv.tv_sec, tv.tv_usec, (uintmax_t)drop.dtdda_drops,
(uintmax_t)drop.dtdda_total, drop.dtdda_kind,
drop.dtdda_msg);
}
if (dtp->dt_drophdlr == NULL) {
if (dtp->dt_oformat)
xo_close_instance("probes");
return (dt_set_errno(dtp, EDT_DROPABORT));
}
if ((*dtp->dt_drophdlr)(&drop,
dtp->dt_droparg) == DTRACE_HANDLE_ABORT)
dtp->dt_droparg) == DTRACE_HANDLE_ABORT) {
if (dtp->dt_oformat)
xo_close_instance("probes");
return (dt_set_errno(dtp, EDT_DROPABORT));
}
if (dtp->dt_oformat)
xo_close_instance("probes");
}
return (0);

View File

@ -211,6 +211,8 @@ typedef struct dt_print_aggdata {
int dtpa_agghist; /* print aggregation as histogram */
int dtpa_agghisthdr; /* aggregation histogram hdr printed */
int dtpa_aggpack; /* pack quantized aggregations */
char dtpa_keyname[256]; /* key name for oformat */
char *dtpa_aggname; /* aggregate name for oformat */
} dt_print_aggdata_t;
typedef struct dt_dirpath {
@ -364,6 +366,7 @@ struct dtrace_hdl {
dtrace_epid_t dt_last_epid; /* most recently consumed EPID */
uint64_t dt_last_timestamp; /* most recently consumed timestamp */
boolean_t dt_has_sugar; /* syntactic sugar used? */
int dt_oformat; /* output format (none, json, xml, html) */
};
/*
@ -702,6 +705,8 @@ extern int dt_print_llquantize(dtrace_hdl_t *, FILE *,
const void *, size_t, uint64_t);
extern int dt_print_agg(const dtrace_aggdata_t *, void *);
extern int dt_format_agg(const dtrace_aggdata_t *, void *);
extern int dt_handle(dtrace_hdl_t *, dtrace_probedata_t *);
extern int dt_handle_liberr(dtrace_hdl_t *,
const dtrace_probedata_t *, const char *);
@ -711,6 +716,8 @@ extern int dt_handle_status(dtrace_hdl_t *,
dtrace_status_t *, dtrace_status_t *);
extern int dt_handle_setopt(dtrace_hdl_t *, dtrace_setoptdata_t *);
extern void dt_oformat_drop(dtrace_hdl_t *, processorid_t);
extern int dt_lib_depend_add(dtrace_hdl_t *, dt_list_t *, const char *);
extern dt_lib_depend_t *dt_lib_depend_lookup(dt_list_t *, const char *);

View File

@ -0,0 +1,34 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023 Domagoj Stolfa
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _DT_OFORMAT_H_
#define _DT_OFORMAT_H_
#undef NORETURN /* needed because libxo redefines it */
#include <libxo/xo.h>
#endif /* _DT_OFORMAT_H_ */

View File

@ -59,6 +59,7 @@
#include <dt_printf.h>
#include <dt_string.h>
#include <dt_provider.h>
#include <dt_oformat.h>
#ifndef illumos
#include <sys/sysctl.h>
#include <string.h>
@ -1736,6 +1737,8 @@ dtrace_close(dtrace_hdl_t *dtp)
free(dtp->dt_kmods);
#endif
free(dtp->dt_provs);
xo_finish();
free(dtp);
}

View File

@ -43,6 +43,7 @@
#include <dt_impl.h>
#include <dt_string.h>
#include <dt_oformat.h>
static int
dt_opt_agg(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
@ -723,6 +724,18 @@ dt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
return (0);
}
static int
dt_opt_oformat(dtrace_hdl_t *dtp, const char *arg, uintptr_t option __unused)
{
if (arg == NULL)
return (dt_set_errno(dtp, EDT_BADOPTVAL));
if (xo_set_options(NULL, arg) < 0)
return (dt_set_errno(dtp, EDT_BADOPTVAL));
return (dtrace_oformat_configure(dtp));
}
static int
dt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
{
@ -1046,6 +1059,7 @@ static const dt_option_t _dtrace_rtoptions[] = {
{ "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },
{ "jstackstrsize", dt_opt_size, DTRACEOPT_JSTACKSTRSIZE },
{ "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },
{ "oformat", dt_opt_oformat, 0 },
{ "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },
{ "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },
{ "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },

View File

@ -27,6 +27,7 @@
*/
/*
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2023, Domagoj Stolfa. All rights reserved.
*/
/*
@ -82,6 +83,7 @@
#include <dt_printf.h>
#include <dt_string.h>
#include <dt_impl.h>
#include <dt_oformat.h>
/* determines whether the given integer CTF encoding is a character */
#define CTF_IS_CHAR(e) \
@ -101,8 +103,10 @@ typedef struct dt_printarg {
int pa_depth; /* member depth */
int pa_nest; /* nested array depth */
FILE *pa_file; /* output file */
const char *pa_object; /* object name */
} dt_printarg_t;
static int dt_format_member(const char *, ctf_id_t, ulong_t, int, void *);
static int dt_print_member(const char *, ctf_id_t, ulong_t, int, void *);
/*
@ -189,7 +193,10 @@ print_bitfield(dt_printarg_t *pap, ulong_t off, ctf_encoding_t *ep)
value >>= shift;
value &= mask;
(void) fprintf(fp, "%#llx", (u_longlong_t)value);
xo_emit("{:value/%#llx}", (u_longlong_t)value);
/* Flush in order to ensure output is aligned properly */
xo_flush();
}
/*
@ -200,24 +207,25 @@ dt_print_hex(FILE *fp, caddr_t addr, size_t size)
{
switch (size) {
case sizeof (uint8_t):
(void) fprintf(fp, "%#x", *(uint8_t *)addr);
xo_emit("{:value/%#x}", *(uint8_t *)addr);
break;
case sizeof (uint16_t):
/* LINTED - alignment */
(void) fprintf(fp, "%#x", *(uint16_t *)addr);
xo_emit("{:value/%#x}", *(uint16_t *)addr);
break;
case sizeof (uint32_t):
/* LINTED - alignment */
(void) fprintf(fp, "%#x", *(uint32_t *)addr);
xo_emit("{:value/%#x}", *(uint32_t *)addr);
break;
case sizeof (uint64_t):
(void) fprintf(fp, "%#llx",
/* LINTED - alignment */
xo_emit("{:value/%#llx}",
(unsigned long long)*(uint64_t *)addr);
break;
default:
(void) fprintf(fp, "<invalid size %u>", (uint_t)size);
xo_emit("<{:warning} {:size/%u}>", "invalid size",
(uint_t)size);
}
/* Flush in order to ensure output is aligned properly */
xo_flush();
}
/*
@ -229,12 +237,16 @@ dt_print_int(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
{
FILE *fp = pap->pa_file;
ctf_file_t *ctfp = pap->pa_ctfp;
dtrace_hdl_t *dtp = pap->pa_dtp;
ctf_encoding_t e;
size_t size;
caddr_t addr = pap->pa_addr + off / NBBY;
if (ctf_type_encoding(ctfp, base, &e) == CTF_ERR) {
(void) fprintf(fp, "<unknown encoding>");
xo_emit("<{:warning}>", "unknown encoding");
/* Flush in order to ensure output is aligned properly */
xo_flush();
return;
}
@ -243,7 +255,8 @@ dt_print_int(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
* would be found.
*/
if (e.cte_format & CTF_INT_VARARGS) {
(void) fprintf(fp, "...");
if (!dtp->dt_oformat)
(void)fprintf(fp, "...");
return;
}
@ -263,11 +276,14 @@ dt_print_int(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
if (CTF_IS_CHAR(e)) {
char c = *(char *)addr;
if (isprint(c))
(void) fprintf(fp, "'%c'", c);
xo_emit("'{:value/%c}'", c);
else if (c == 0)
(void) fprintf(fp, "'\\0'");
xo_emit("'\\{:value/0}'");
else
(void) fprintf(fp, "'\\%03o'", c);
xo_emit("'\\{:value/%03o}'", c);
/* Flush in order to ensure output is aligned properly */
xo_flush();
return;
}
@ -285,22 +301,20 @@ dt_print_float(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
ctf_file_t *ctfp = pap->pa_ctfp;
ctf_encoding_t e;
caddr_t addr = pap->pa_addr + off / NBBY;
dtrace_hdl_t *dtp = pap->pa_dtp;
if (ctf_type_encoding(ctfp, base, &e) == 0) {
if (e.cte_format == CTF_FP_SINGLE &&
e.cte_bits == sizeof (float) * NBBY) {
/* LINTED - alignment */
(void) fprintf(fp, "%+.7e", *((float *)addr));
xo_emit("{:value/%+.7e}", *((float *)addr));
} else if (e.cte_format == CTF_FP_DOUBLE &&
e.cte_bits == sizeof (double) * NBBY) {
/* LINTED - alignment */
(void) fprintf(fp, "%+.7e", *((double *)addr));
xo_emit("{:value/%+.7e}", *((double *)addr));
} else if (e.cte_format == CTF_FP_LDOUBLE &&
e.cte_bits == sizeof (long double) * NBBY) {
/* LINTED - alignment */
(void) fprintf(fp, "%+.16LE", *((long double *)addr));
xo_emit("{:value/%+.16LE}", *((long double *)addr));
} else {
(void) fprintf(fp, "<unknown encoding>");
xo_emit("<{:warning}>", "unknown encoding");
}
}
}
@ -329,8 +343,7 @@ dt_print_ptr(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
if (dtrace_lookup_by_addr(pap->pa_dtp, pc, &sym, &dts) != 0) {
dt_print_hex(fp, addr, size);
} else {
(void) fprintf(fp, "%s`%s", dts.dts_object,
dts.dts_name);
xo_emit("{:value/%s`%s}", dts.dts_object, dts.dts_name);
}
}
}
@ -367,6 +380,7 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
FILE *fp = pap->pa_file;
ctf_file_t *ctfp = pap->pa_ctfp;
caddr_t addr = pap->pa_addr + off / NBBY;
char *str;
ctf_arinfo_t car;
ssize_t eltsize;
ctf_encoding_t e;
@ -374,16 +388,18 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
boolean_t isstring;
int kind;
ctf_id_t rtype;
dtrace_hdl_t *dtp = pap->pa_dtp;
if (ctf_array_info(ctfp, base, &car) == CTF_ERR) {
(void) fprintf(fp, "%p", (void *)addr);
xo_emit("{:value/%p}", (void *)addr);
return;
}
if ((eltsize = ctf_type_size(ctfp, car.ctr_contents)) < 0 ||
(rtype = ctf_type_resolve(ctfp, car.ctr_contents)) == CTF_ERR ||
(kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR) {
(void) fprintf(fp, "<invalid type %lu>", car.ctr_contents);
xo_emit("<{:warning} {:type-identifier/%lu}>", "invalid type",
car.ctr_contents);
return;
}
@ -411,18 +427,44 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
*
* As D will internally represent this as a char[256] array.
*/
if (!isstring || pap->pa_depth != 0)
(void) fprintf(fp, "[ ");
if (dtp->dt_oformat) {
if (!isstring)
xo_open_list("value");
else {
str = malloc(car.ctr_nelems);
if (str == NULL)
return;
*str = 0;
}
} else {
if (!isstring || pap->pa_depth != 0)
(void)fprintf(fp, "[ ");
if (isstring)
(void) fprintf(fp, "\"");
if (isstring)
(void)fprintf(fp, "\"");
}
for (i = 0; i < car.ctr_nelems; i++) {
if (isstring) {
char c = *((char *)addr + eltsize * i);
if (c == '\0')
if (c == '\0') {
if (dtp->dt_oformat)
str[i] = 0;
break;
(void) fprintf(fp, "%c", c);
}
if (dtp->dt_oformat)
str[i] = c;
else
(void)fprintf(fp, "%c", c);
} else if (dtp->dt_oformat) {
dt_printarg_t pa = *pap;
pa.pa_nest += pap->pa_depth + 1;
pa.pa_depth = 0;
pa.pa_addr = addr + eltsize * i;
(void) ctf_type_visit(ctfp, car.ctr_contents,
dt_format_member, &pa);
} else {
/*
* Recursively invoke ctf_type_visit() on each member.
@ -444,15 +486,24 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
}
}
if (isstring)
(void) fprintf(fp, "\"");
if (dtp->dt_oformat) {
if (!isstring)
xo_close_list("value");
else {
xo_emit("{:value/%s}", str);
free(str);
}
} else {
if (isstring)
(void)fprintf(fp, "\"");
if (!isstring || pap->pa_depth != 0) {
if (CTF_IS_STRUCTLIKE(kind))
dt_print_indent(pap);
else
(void) fprintf(fp, " ");
(void) fprintf(fp, "]");
if (!isstring || pap->pa_depth != 0) {
if (CTF_IS_STRUCTLIKE(kind))
dt_print_indent(pap);
else
(void)fprintf(fp, " ");
(void)fprintf(fp, "]");
}
}
}
@ -463,7 +514,8 @@ dt_print_array(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
static void
dt_print_structlike(ctf_id_t id, ulong_t off, dt_printarg_t *pap)
{
(void) fprintf(pap->pa_file, "{");
if (pap->pa_dtp->dt_oformat == DTRACE_OFORMAT_TEXT)
(void)fprintf(pap->pa_file, "{");
}
/*
@ -480,6 +532,7 @@ dt_print_enum(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
ssize_t size;
caddr_t addr = pap->pa_addr + off / NBBY;
int value = 0;
dtrace_hdl_t *dtp = pap->pa_dtp;
/*
* The C standard says that an enum will be at most the sizeof (int).
@ -498,14 +551,19 @@ dt_print_enum(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
value = *(int32_t *)addr;
break;
default:
(void) fprintf(fp, "<invalid enum size %u>", (uint_t)size);
xo_emit("<{:warning} {:size/%u}>", "invalid enum size",
(uint_t)size);
return;
}
if ((ename = ctf_enum_name(ctfp, base, value)) != NULL)
(void) fprintf(fp, "%s", ename);
else
(void) fprintf(fp, "%d", value);
if ((ename = ctf_enum_name(ctfp, base, value)) != NULL) {
xo_emit("{:value/%s}", ename);
} else {
xo_emit("{:value/%d}", value);
}
/* Flush in order to ensure output is aligned properly */
xo_flush();
}
/*
@ -516,7 +574,8 @@ dt_print_enum(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
static void
dt_print_tag(ctf_id_t base, ulong_t off, dt_printarg_t *pap)
{
(void) fprintf(pap->pa_file, "<forward decl>");
if (pap->pa_dtp->dt_oformat == DTRACE_OFORMAT_TEXT)
(void)fprintf(pap->pa_file, "<forward decl>");
}
typedef void dt_printarg_f(ctf_id_t, ulong_t, dt_printarg_t *);
@ -533,6 +592,46 @@ static dt_printarg_f *const dt_printfuncs[] = {
dt_print_tag /* CTF_K_FORWARD */
};
static int
dt_format_member(const char *name, ctf_id_t id, ulong_t off, int depth,
void *data)
{
char type[DT_TYPE_NAMELEN];
int kind;
dt_printarg_t *pap = data;
FILE *fp = pap->pa_file;
ctf_file_t *ctfp = pap->pa_ctfp;
boolean_t arraymember;
boolean_t brief;
ctf_encoding_t e;
ctf_id_t rtype;
if ((rtype = ctf_type_resolve(ctfp, id)) == CTF_ERR ||
(kind = ctf_type_kind(ctfp, rtype)) == CTF_ERR ||
kind < CTF_K_INTEGER || kind > CTF_K_FORWARD) {
xo_emit("{:name/%s} <{:warning} {:type-identifier/%lu}>"
" {:value/0x%llx}",
name, "invalid type", id, pap->pa_addr);
return (0);
}
dt_print_type_name(ctfp, id, type, sizeof (type));
xo_open_instance("type");
if (pap->pa_object) {
xo_emit("{:object-name/%s}", pap->pa_object);
/* Clear the object to avoid duplication */
pap->pa_object = NULL;
}
if (*name != 0)
xo_emit("{:member-name/%s}", name);
xo_emit("{:name/%s} {:ctfid/%ld}", type, id);
dt_printfuncs[kind - 1](rtype, off, pap);
xo_close_instance("type");
return (0);
}
/*
* Print one member of a structure. This callback is invoked from
* ctf_type_visit() recursively.
@ -634,16 +733,12 @@ dt_print_member(const char *name, ctf_id_t id, ulong_t off, int depth,
return (0);
}
/*
* Main print function invoked by dt_consume_cpu().
*/
int
dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
caddr_t addr, size_t len)
static ctf_id_t
dt_print_prepare(dtrace_hdl_t *dtp, const char *typename, caddr_t addr,
size_t len, dt_printarg_t *pa)
{
const char *s;
char *object;
dt_printarg_t pa;
ctf_id_t id;
dt_module_t *dmp;
ctf_file_t *ctfp;
@ -661,20 +756,20 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
;
if (*s != '`')
return (0);
return (CTF_ERR);
object = alloca(s - typename + 1);
bcopy(typename, object, s - typename);
object[s - typename] = '\0';
dmp = dt_module_lookup_by_name(dtp, object);
if (dmp == NULL)
return (0);
return (CTF_ERR);
if (dmp->dm_pid != 0) {
libid = atoi(s + 1);
s = strchr(s + 1, '`');
if (s == NULL || libid > dmp->dm_nctflibs)
return (0);
return (CTF_ERR);
ctfp = dmp->dm_libctfp[libid];
} else {
ctfp = dt_module_getctf(dtp, dmp);
@ -688,18 +783,63 @@ dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
* work.
*/
if (ctfp == NULL || ctf_type_kind(ctfp, id) == CTF_ERR)
return (CTF_ERR);
pa->pa_dtp = dtp;
pa->pa_addr = addr;
pa->pa_ctfp = ctfp;
pa->pa_nest = 0;
pa->pa_depth = 0;
pa->pa_object = strdup(object);
return (id);
}
/*
* Main print function invoked by dt_consume_cpu().
*/
int
dtrace_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
caddr_t addr, size_t len)
{
dt_printarg_t pa;
ctf_id_t id;
id = dt_print_prepare(dtp, typename, addr, len, &pa);
if (id == CTF_ERR)
return (0);
/* setup the print structure and kick off the main print routine */
pa.pa_dtp = dtp;
pa.pa_addr = addr;
pa.pa_ctfp = ctfp;
pa.pa_nest = 0;
pa.pa_depth = 0;
pa.pa_file = fp;
(void) ctf_type_visit(pa.pa_ctfp, id, dt_print_member, &pa);
dt_print_trailing_braces(&pa, 0);
dt_free(dtp, (void *)pa.pa_object);
return (len);
}
/*
* Main format function invoked by dt_consume_cpu().
*/
int
dtrace_format_print(dtrace_hdl_t *dtp, FILE *fp, const char *typename,
caddr_t addr, size_t len)
{
dt_printarg_t pa;
ctf_id_t id;
char toplevel[1024];
id = dt_print_prepare(dtp, typename, addr, len, &pa);
if (id == CTF_ERR)
return (0);
if (ctf_type_name(pa.pa_ctfp, id, toplevel, sizeof(toplevel)) < 0)
return (0);
xo_open_list("type");
(void) ctf_type_visit(pa.pa_ctfp, id, dt_format_member, &pa);
xo_close_list("type");
dt_free(dtp, (void *)pa.pa_object);
return (len);
}

View File

@ -21,6 +21,7 @@
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2023 Domagoj Stolfa. All rights reserved.
* Use is subject to license terms.
*/
@ -128,6 +129,11 @@ extern int dt_print_ustack(dtrace_hdl_t *, FILE *,
extern int dt_print_mod(dtrace_hdl_t *, FILE *, const char *, caddr_t);
extern int dt_print_umod(dtrace_hdl_t *, FILE *, const char *, caddr_t);
extern int dt_format_stack(dtrace_hdl_t *, caddr_t, int, int);
extern int dt_format_ustack(dtrace_hdl_t *, caddr_t, uint64_t);
extern int dt_format_mod(dtrace_hdl_t *, caddr_t);
extern int dt_format_umod(dtrace_hdl_t *, caddr_t);
#ifdef __cplusplus
}
#endif

View File

@ -50,6 +50,7 @@
#include <stdint.h>
#include <dt_impl.h>
#include <dt_oformat.h>
static const struct {
size_t dtps_offset;
@ -992,3 +993,44 @@ dtrace_uaddr2str(dtrace_hdl_t *dtp, pid_t pid,
return (dt_string2str(c, str, nbytes));
}
int
dtrace_oformat_configure(dtrace_hdl_t *dtp)
{
dtp->dt_oformat = xo_get_style(NULL) == XO_STYLE_TEXT ?
DTRACE_OFORMAT_TEXT :
DTRACE_OFORMAT_STRUCTURED;
xo_set_flags(NULL, XOF_DTRT);
return (0);
}
int
dtrace_oformat(dtrace_hdl_t *dtp)
{
return (dtp->dt_oformat != DTRACE_OFORMAT_TEXT);
}
void
dtrace_set_outfp(const FILE *ofp)
{
xo_set_file((FILE *)ofp);
}
void
dtrace_oformat_setup(dtrace_hdl_t *dtp)
{
xo_open_container("dtrace");
xo_open_list("probes");
}
void
dtrace_oformat_teardown(dtrace_hdl_t *dtp)
{
xo_close_list("probes");
xo_close_container("dtrace");
}

View File

@ -25,6 +25,7 @@
*/
/*
* Copyright (c) 2023 by Domagoj Stolfa. All rights reserved.
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
@ -200,6 +201,7 @@ typedef struct dtrace_probedata {
dtrace_flowkind_t dtpda_flow; /* flow kind */
const char *dtpda_prefix; /* recommended flow prefix */
int dtpda_indent; /* recommended flow indent */
uint64_t dtpda_timestamp; /* hrtime of snapshot */
} dtrace_probedata_t;
typedef int dtrace_consume_probe_f(const dtrace_probedata_t *, void *);
@ -233,6 +235,10 @@ extern void *dtrace_printf_create(dtrace_hdl_t *, const char *);
extern void *dtrace_printa_create(dtrace_hdl_t *, const char *);
extern size_t dtrace_printf_format(dtrace_hdl_t *, void *, char *, size_t);
extern int dtrace_sprintf(dtrace_hdl_t *, FILE *, void *,
const dtrace_recdesc_t *, uint_t,
const void *, size_t);
extern int dtrace_fprintf(dtrace_hdl_t *, FILE *, void *,
const dtrace_probedata_t *, const dtrace_recdesc_t *, uint_t,
const void *, size_t);
@ -260,6 +266,8 @@ extern int dtrace_freopen(dtrace_hdl_t *, FILE *, void *,
*/
extern int dtrace_print(dtrace_hdl_t *, FILE *, const char *,
caddr_t, size_t);
extern int dtrace_format_print(dtrace_hdl_t *, FILE *, const char *,
caddr_t, size_t);
/*
* DTrace Work Interface
@ -616,4 +624,18 @@ extern int _dtrace_debug;
#define _SC_NPROCESSORS_MAX _SC_NPROCESSORS_CONF
#endif
/*
* Values for the dt_oformat property.
*/
#define DTRACE_OFORMAT_TEXT 0
#define DTRACE_OFORMAT_STRUCTURED 1
extern int dtrace_oformat_configure(dtrace_hdl_t *);
extern int dtrace_oformat(dtrace_hdl_t *);
extern void dtrace_set_outfp(const FILE *);
extern void dtrace_oformat_setup(dtrace_hdl_t *);
extern void dtrace_oformat_teardown(dtrace_hdl_t *);
extern void dtrace_oformat_probe(dtrace_hdl_t *, const dtrace_probedata_t *,
processorid_t, dtrace_probedesc_t *);
#endif /* _DTRACE_H */

View File

@ -147,7 +147,7 @@ CFLAGS+= -fsanitize=address -fsanitize=undefined
LDFLAGS+= -fsanitize=address -fsanitize=undefined
.endif
LIBADD= ctf elf proc pthread rtld_db
LIBADD= ctf elf proc pthread rtld_db xo
CLEANFILES= dt_errtags.c dt_names.c

View File

@ -34,7 +34,7 @@ CFLAGS+= -fsanitize=address -fsanitize=undefined
LDFLAGS+= -fsanitize=address -fsanitize=undefined
.endif
LIBADD= dtrace ctf elf proc spl
LIBADD= dtrace ctf elf proc spl xo
.if ${MK_DTRACE_TESTS} != "no"
SUBDIR+= tests

View File

@ -39,6 +39,7 @@ TESTS_SUBDIRS+= aggs \
misc \
multiaggs \
offsetof \
oformat \
operators \
pid \
plockstat \

View File

@ -0,0 +1,42 @@
#
# This Makefile was generated by $srcdir/cddl/usr.sbin/dtrace/tests/tools/genmakefiles.sh.
#
PACKAGE= tests
${PACKAGE}FILES= \
tst.agg.avg.ksh \
tst.agg.count.ksh \
tst.agg.llquantize.ksh \
tst.agg.lquantize.ksh \
tst.agg.max.ksh \
tst.agg.min.ksh \
tst.agg.quantize.ksh \
tst.agg.stddev.ksh \
tst.agg.sum.ksh \
tst.aggmod.ksh \
tst.aggstack.ksh \
tst.aggsym.ksh \
tst.aggustack.ksh \
tst.aggusym.ksh \
tst.drop.ksh \
tst.mod.ksh \
tst.print.ksh \
tst.printf.ksh \
tst.printm.ksh \
tst.stack.ksh \
tst.sym.ksh \
tst.trace.ksh \
tst.tracemem.ksh \
tst.umod.ksh \
tst.ustack.ksh \
tst.usym.ksh \
TESTEXES= \
CFILES= \
.include "../../dtrace.test.mk"

View File

@ -12,7 +12,7 @@ ${TESTGROUP}EXEPACKAGE= ${PACKAGE}
TESTWRAPPER= t_dtrace_contrib
ATF_TESTS_SH+= ${TESTWRAPPER}
TEST_METADATA.t_dtrace_contrib+= required_files="/usr/local/bin/ksh"
TEST_METADATA.t_dtrace_contrib+= required_files="/usr/local/bin/ksh /usr/local/bin/jq /usr/local/bin/perl /usr/local/bin/xmllint"
TEST_METADATA.t_dtrace_contrib+= required_user="root"
GENTEST?= ${.CURDIR:H:H}/tools/gentest.sh

View File

@ -70,7 +70,7 @@ runtest()
err.*.ksh|tst.*.ksh)
expr "$TFILE" : 'err.*' >/dev/null && exstatus=1
tst=$TFILE ksh "$TFILE" /usr/sbin/dtrace >$STDOUT 2>$STDERR
tst=$TFILE ksh -p "$TFILE" /usr/sbin/dtrace >$STDOUT 2>$STDERR
status=$?
if [ $status -ne $exstatus ]; then
@ -86,7 +86,7 @@ runtest()
if [ $retval -eq 0 ] && \
head -n 1 $STDOUT | grep -q -E '^#!/.*ksh$'; then
ksh $STDOUT
ksh -p $STDOUT
retval=$?
fi
@ -119,6 +119,10 @@ test stdout:
--
$(cat $STDOUT)
--
test stdout diff:
--
$(diff -u $EXOUT $STDOUT)
--
__EOF__
fi
if [ $(stat -f '%z' $STDERR) -gt 0 ]; then

View File

@ -162,6 +162,8 @@
..
offsetof
..
oformat
..
operators
..
pid

View File

@ -398,7 +398,7 @@ _DP_ucl= m
_DP_vmmapi= util
_DP_opencsd= cxxrt
_DP_ctf= spl z
_DP_dtrace= ctf elf proc pthread rtld_db
_DP_dtrace= ctf elf proc pthread rtld_db xo
_DP_xo= util
_DP_ztest= geom m nvpair umem zpool pthread avl zfs_core spl zutil zfs uutil icp
# The libc dependencies are not strictly needed but are defined to make the

View File

@ -141,18 +141,18 @@ acpi_capm_get_info(apm_info_t aip)
aip->ai_capabilities= 0xff00; /* unknown */
if (acpi_acad_get_acline(&acline))
aip->ai_acline = APM_UNKNOWN; /* unknown */
aip->ai_acline = 1; /* no info -- on-line best guess */
else
aip->ai_acline = acline; /* on/off */
if (acpi_battery_get_battinfo(NULL, &batt) != 0) {
aip->ai_batt_stat = APM_UNKNOWN;
aip->ai_batt_life = APM_UNKNOWN;
aip->ai_batt_time = -1; /* unknown */
aip->ai_batteries = ~0U; /* unknown */
aip->ai_batt_stat = 0; /* "high" old I/F has no unknown state */
aip->ai_batt_life = 255; /* N/A, not -1 */
aip->ai_batt_time = -1; /* unknown */
aip->ai_batteries = ~0U; /* unknown */
} else {
aip->ai_batt_stat = acpi_capm_convert_battstate(&batt);
aip->ai_batt_life = batt.cap;
aip->ai_batt_life = (batt.cap == -1) ? 255 : batt.cap;
aip->ai_batt_time = (batt.min == -1) ? -1 : batt.min * 60;
aip->ai_batteries = acpi_battery_get_units();
}
@ -186,11 +186,11 @@ acpi_capm_get_pwstatus(apm_pwstatus_t app)
app->ap_batt_stat = acpi_capm_convert_battstate(&batt);
app->ap_batt_flag = acpi_capm_convert_battflags(&batt);
app->ap_batt_life = batt.cap;
app->ap_batt_life = (batt.cap == -1) ? 255 : batt.cap;
app->ap_batt_time = (batt.min == -1) ? -1 : batt.min * 60;
if (acpi_acad_get_acline(&acline))
app->ap_acline = APM_UNKNOWN;
app->ap_acline = 1; /* no info -- on-line best guess */
else
app->ap_acline = acline; /* on/off */