From ad83098edb01c4ad2043f3a689e94e6322714727 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 27 Aug 2017 18:44:43 +0200 Subject: [PATCH 190/325] share/dtrace: Import flowtrace 2017-01-28/d600753af03 Obtained from: ElectroBSD --- share/dtrace/Makefile | 1 + share/dtrace/flowtrace | 165 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100755 share/dtrace/flowtrace diff --git a/share/dtrace/Makefile b/share/dtrace/Makefile index 218da556452f..b94fb50f40fd 100644 --- a/share/dtrace/Makefile +++ b/share/dtrace/Makefile @@ -10,6 +10,7 @@ SCRIPTS= blocking \ disklatency \ disklatencycmd \ fbt-time \ + flowtrace \ geli-key-monitor \ geli-request-monitor \ hotopen \ diff --git a/share/dtrace/flowtrace b/share/dtrace/flowtrace new file mode 100755 index 000000000000..9e890f61a311 --- /dev/null +++ b/share/dtrace/flowtrace @@ -0,0 +1,165 @@ +#!/usr/sbin/dtrace -s + +/*************************************************************************** + * flowtrace.d + * + * Enables flow tracing after entering the function specified as + * first argument and disables it again after the function returns. + * + * For a number of currently-hardcoded functions the children + * don't get shown in the output to make it easier to comprehend. + * + * XXX: It would be more efficient to not generate probes for them. + * This probably requires another script that generates the D + * code on the fly. + * + * Copyright (c) 2012 Fabian Keil + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************/ + +#pragma D option defaultargs +#pragma D option dynvarsize=10m +#pragma D option bufsize=50m +#pragma D option switchrate=10hz +#pragma D option quiet + +dtrace:::BEGIN +{ + /* + * Initialize indent[] which is used to indent the probefunc + * according to the stackdepth. Unlike "#pragma D option flowindent" + * this doesn't break in case of missing return probes. + * + * The rest of the values are filled in the dtrace::BEGIN probe + * at the end of the script. + */ + indent[0] = ""; + + traced_function = $$1; + + this->timestamp = walltimestamp; + this->msecs = (this->timestamp / 1000000) % 1000; + printf("%d %d %Y.%.3d 00: Trace in progress. Waiting to enter %s. Hit CTRL-C to exit.\n", + cpu, tid, this->timestamp, this->msecs, traced_function); +} + +/* Prepare to trace every function on this thread from now on ... */ +fbt::$$1:entry +{ + self->trace_me_yo = 1; +} + +/* ... except for the children of these functions. */ +fbt::hpet_intr:return, +fbt::lapic_handle_intr:return, +fbt::termcn_cnputc:return, +fbt::printf:return, +fbt::cv_signal:return, +fbt::sleepq_broadcast:return +/self->trace_me_yo && self->stfu == stackdepth/ +{ + self->stfu = 0; +} + +/* This is where the actual tracing happens. */ +fbt::: +/self->trace_me_yo && ! self->stfu/ +{ + this->timestamp = walltimestamp; + this->msecs = (this->timestamp / 1000000) % 1000; + this->direction = probename == "entry" ? "-->" : "<--"; + printf("%d %d %Y.%.3d %.2d: %s %s %s:%s\n", + cpu, tid, this->timestamp, this->msecs, + stackdepth, indent[stackdepth], + this->direction, probefunc, probename); +} + +fbt::hpet_intr:entry, +fbt::lapic_handle_intr:entry, +fbt::termcn_cnputc:entry, +fbt::printf:entry, +fbt::cv_signal:entry, +fbt::sleepq_broadcast:entry +/self->trace_me_yo && !self->stfu/ +{ + this->timestamp = walltimestamp; + this->msecs = (this->timestamp / 1000000) % 1000; + printf("%d %d %Y.%.3d %.2d: %s [...]\n", + cpu, tid, this->timestamp, this->msecs, + stackdepth, indent[stackdepth]); + self->stfu = stackdepth; +} + +/* Done tracing */ +fbt::$$1:return +{ + self->trace_me_yo = 0; + exit(0); +} + +dtrace:::BEGIN +{ + /* perl -e 'for my $i (0..50) {printf(" indent[%s%d] = \"%s\";\n", $i < 10 ? " " : "", $i, " " x $i);}' */ + indent[ 0] = ""; + indent[ 1] = " "; + indent[ 2] = " "; + indent[ 3] = " "; + indent[ 4] = " "; + indent[ 5] = " "; + indent[ 6] = " "; + indent[ 7] = " "; + indent[ 8] = " "; + indent[ 9] = " "; + indent[10] = " "; + indent[11] = " "; + indent[12] = " "; + indent[13] = " "; + indent[14] = " "; + indent[15] = " "; + indent[16] = " "; + indent[17] = " "; + indent[18] = " "; + indent[19] = " "; + indent[20] = " "; + indent[21] = " "; + indent[22] = " "; + indent[23] = " "; + indent[24] = " "; + indent[25] = " "; + indent[26] = " "; + indent[27] = " "; + indent[28] = " "; + indent[29] = " "; + indent[30] = " "; + indent[31] = " "; + indent[32] = " "; + indent[33] = " "; + indent[34] = " "; + indent[35] = " "; + indent[36] = " "; + indent[37] = " "; + indent[38] = " "; + indent[39] = " "; + indent[40] = " "; + indent[41] = " "; + indent[42] = " "; + indent[43] = " "; + indent[44] = " "; + indent[45] = " "; + indent[46] = " "; + indent[47] = " "; + indent[48] = " "; + indent[49] = " "; + indent[50] = " "; +} -- 2.32.0