Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145541102
D15418.id42555.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
190 KB
Referenced Files
None
Subscribers
None
D15418.id42555.diff
View Options
Index: stable/11/ObsoleteFiles.inc
===================================================================
--- stable/11/ObsoleteFiles.inc
+++ stable/11/ObsoleteFiles.inc
@@ -38,6 +38,10 @@
# xargs -n1 | sort | uniq -d;
# done
+# 20180513: remove DTrace scripts made obsolete by dwatch(1)
+OLD_FILES+=usr/share/dtrace/watch_execve
+OLD_FILES+=usr/share/dtrace/watch_kill
+OLD_FILES+=usr/share/dtrace/watch_vop_remove
# 20180331: new clang import which bumps version from 5.0.1 to 6.0.0.
OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/allocator_interface.h
OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/asan_interface.h
Index: stable/11/cddl/lib/libdtrace/errno.d
===================================================================
--- stable/11/cddl/lib/libdtrace/errno.d
+++ stable/11/cddl/lib/libdtrace/errno.d
@@ -20,6 +20,7 @@
* CDDL HEADER END
*
* Portions Copyright 2006-2008 John Birrell jb@freebsd.org
+ * Portions Copyright 2018 Devin Teske dteske@freebsd.org
*
* $FreeBSD$
*/
@@ -216,7 +217,15 @@
#pragma D binding "1.0" ENOLINK
inline int EPROTO = 92;
#pragma D binding "1.0" EPROTO
-inline int ELAST = 92;
+inline int ENOTCAPABLE = 93;
+#pragma D binding "1.13" ENOTCAPABLE
+inline int ECAPMODE = 94;
+#pragma D binding "1.13" ECAPMODE
+inline int ENOTRECOVERABLE = 95;
+#pragma D binding "1.13" ENOTRECOVERABLE
+inline int EOWNERDEAD = 96;
+#pragma D binding "1.13" EOWNERDEAD
+inline int ELAST = 96;
#pragma D binding "1.0" ELAST
inline int ERESTART = -1;
#pragma D binding "1.0" ERESTART
@@ -226,3 +235,114 @@
#pragma D binding "1.0" ENOIOCTL
inline int EDIRIOCTL = -4;
#pragma D binding "1.0" EDIRIOCTL
+inline int ERELOOKUP = -5;
+#pragma D binding "1.13" ERELOOKUP
+
+/*
+ * Error strings from <sys/errno.h>
+ */
+#pragma D binding "1.13" strerror
+inline string strerror[int errno] =
+ errno == 0 ? "Success" :
+ errno == EPERM ? "Operation not permitted" :
+ errno == ENOENT ? "No such file or directory" :
+ errno == ESRCH ? "No such process" :
+ errno == EINTR ? "Interrupted system call" :
+ errno == EIO ? "Input/output error" :
+ errno == ENXIO ? "Device not configured" :
+ errno == E2BIG ? "Argument list too long" :
+ errno == ENOEXEC ? "Exec format error" :
+ errno == EBADF ? "Bad file descriptor" :
+ errno == ECHILD ? "No child processes" :
+ errno == EDEADLK ? "Resource deadlock avoided" :
+ errno == ENOMEM ? "Cannot allocate memory" :
+ errno == EACCES ? "Permission denied" :
+ errno == EFAULT ? "Bad address" :
+ errno == ENOTBLK ? "Block device required" :
+ errno == EBUSY ? "Device busy" :
+ errno == EEXIST ? "File exists" :
+ errno == EXDEV ? "Cross-device link" :
+ errno == ENODEV ? "Operation not supported by device" :
+ errno == ENOTDIR ? "Not a directory" :
+ errno == EISDIR ? "Is a directory" :
+ errno == EINVAL ? "Invalid argument" :
+ errno == ENFILE ? "Too many open files in system" :
+ errno == EMFILE ? "Too many open files" :
+ errno == ENOTTY ? "Inappropriate ioctl for device" :
+ errno == ETXTBSY ? "Text file busy" :
+ errno == EFBIG ? "File too large" :
+ errno == ENOSPC ? "No space left on device" :
+ errno == ESPIPE ? "Illegal seek" :
+ errno == EROFS ? "Read-only filesystem" :
+ errno == EMLINK ? "Too many links" :
+ errno == EPIPE ? "Broken pipe" :
+ errno == EDOM ? "Numerical argument out of domain" :
+ errno == ERANGE ? "Result too large" :
+ errno == EAGAIN ? "Resource temporarily unavailable" :
+ errno == EINPROGRESS ? "Operation now in progress" :
+ errno == EALREADY ? "Operation already in progress" :
+ errno == ENOTSOCK ? "Socket operation on non-socket" :
+ errno == EDESTADDRREQ ? "Destination address required" :
+ errno == EMSGSIZE ? "Message too long" :
+ errno == EPROTOTYPE ? "Protocol wrong type for socket" :
+ errno == ENOPROTOOPT ? "Protocol not available" :
+ errno == EPROTONOSUPPORT ? "Protocol not supported" :
+ errno == ESOCKTNOSUPPORT ? "Socket type not supported" :
+ errno == EOPNOTSUPP ? "Operation not supported" :
+ errno == EPFNOSUPPORT ? "Protocol family not supported" :
+ errno == EAFNOSUPPORT ? "Address family not supported by protocol family" :
+ errno == EADDRINUSE ? "Address already in use" :
+ errno == EADDRNOTAVAIL ? "Can't assign requested address" :
+ errno == ENETDOWN ? "Network is down" :
+ errno == ENETUNREACH ? "Network is unreachable" :
+ errno == ENETRESET ? "Network dropped connection on reset" :
+ errno == ECONNABORTED ? "Software caused connection abort" :
+ errno == ECONNRESET ? "Connection reset by peer" :
+ errno == ENOBUFS ? "No buffer space available" :
+ errno == EISCONN ? "Socket is already connected" :
+ errno == ENOTCONN ? "Socket is not connected" :
+ errno == ESHUTDOWN ? "Can't send after socket shutdown" :
+ errno == ETOOMANYREFS ? "Too many references: can't splice" :
+ errno == ETIMEDOUT ? "Operation timed out" :
+ errno == ECONNREFUSED ? "Connection refused" :
+ errno == ELOOP ? "Too many levels of symbolic links" :
+ errno == ENAMETOOLONG ? "File name too long" :
+ errno == EHOSTDOWN ? "Host is down" :
+ errno == EHOSTUNREACH ? "No route to host" :
+ errno == ENOTEMPTY ? "Directory not empty" :
+ errno == EPROCLIM ? "Too many processes" :
+ errno == EUSERS ? "Too many users" :
+ errno == EDQUOT ? "Disc quota exceeded" :
+ errno == ESTALE ? "Stale NFS file handle" :
+ errno == EREMOTE ? "Too many levels of remote in path" :
+ errno == EBADRPC ? "RPC struct is bad" :
+ errno == ERPCMISMATCH ? "RPC version wrong" :
+ errno == EPROGUNAVAIL ? "RPC prog. not avail" :
+ errno == EPROGMISMATCH ? "Program version wrong" :
+ errno == EPROCUNAVAIL ? "Bad procedure for program" :
+ errno == ENOLCK ? "No locks available" :
+ errno == ENOSYS ? "Function not implemented" :
+ errno == EFTYPE ? "Inappropriate file type or format" :
+ errno == EAUTH ? "Authentication error" :
+ errno == ENEEDAUTH ? "Need authenticator" :
+ errno == EIDRM ? "Identifier removed" :
+ errno == ENOMSG ? "No message of desired type" :
+ errno == EOVERFLOW ? "Value too large to be stored in data type" :
+ errno == ECANCELED ? "Operation canceled" :
+ errno == EILSEQ ? "Illegal byte sequence" :
+ errno == ENOATTR ? "Attribute not found" :
+ errno == EDOOFUS ? "Programming error" :
+ errno == EBADMSG ? "Bad message" :
+ errno == EMULTIHOP ? "Multihop attempted" :
+ errno == ENOLINK ? "Link has been severed" :
+ errno == EPROTO ? "Protocol error" :
+ errno == ENOTCAPABLE ? "Capabilities insufficient" :
+ errno == ECAPMODE ? "Not permitted in capability mode" :
+ errno == ENOTRECOVERABLE ? "State not recoverable" :
+ errno == EOWNERDEAD ? "Previous owner died" :
+ errno == ERESTART ? "restart syscall" :
+ errno == EJUSTRETURN ? "don't modify regs, just return" :
+ errno == ENOIOCTL ? "ioctl not handled by this layer" :
+ errno == EDIRIOCTL ? "do direct ioctl in GEOM" :
+ errno == ERELOOKUP ? "retry the directory lookup" :
+ "Unknown error";
Index: stable/11/cddl/lib/libdtrace/io.d
===================================================================
--- stable/11/cddl/lib/libdtrace/io.d
+++ stable/11/cddl/lib/libdtrace/io.d
@@ -18,6 +18,8 @@
*
* CDDL HEADER END
*
+ * Portions Copyright 2018 Devin Teske dteske@freebsd.org
+ *
* $FreeBSD$
*/
/*
@@ -29,47 +31,51 @@
#pragma D depends_on provider io
typedef struct devinfo {
- int dev_major; /* major number */
- int dev_minor; /* minor number */
- int dev_instance; /* instance number */
- string dev_name; /* name of device */
- string dev_statname; /* name of device + instance/minor */
- string dev_pathname; /* pathname of device */
+ int dev_major; /* major number */
+ int dev_minor; /* minor number */
+ int dev_instance; /* instance number */
+ int dev_type; /* type of device */
+ string dev_name; /* name of device */
+ string dev_statname; /* name of device + instance/minor */
+ string dev_pathname; /* pathname of device */
} devinfo_t;
#pragma D binding "1.0" translator
translator devinfo_t < struct devstat *D > {
- dev_major = D->device_number;
- dev_minor = D->unit_number;
- dev_instance = 0;
- dev_name = stringof(D->device_name);
- dev_statname = stringof(D->device_name);
- dev_pathname = stringof(D->device_name);
+ dev_major = D->device_number;
+ dev_minor = D->unit_number;
+ dev_instance = 0;
+ dev_type = D->device_type;
+ dev_name = stringof(D->device_name);
+ dev_statname = stringof(D->device_name);
+ dev_pathname = stringof(D->device_name);
};
typedef struct bufinfo {
- int b_flags; /* flags */
- long b_bcount; /* number of bytes */
- caddr_t b_addr; /* buffer address */
- uint64_t b_blkno; /* expanded block # on device */
- uint64_t b_lblkno; /* block # on device */
- size_t b_resid; /* # of bytes not transferred */
- size_t b_bufsize; /* size of allocated buffer */
-/* caddr_t b_iodone; I/O completion routine */
- int b_error; /* expanded error field */
-/* dev_t b_edev; extended device */
+ int b_cmd; /* I/O operation */
+ int b_flags; /* flags */
+ long b_bcount; /* number of bytes */
+ caddr_t b_addr; /* buffer address */
+ uint64_t b_blkno; /* expanded block # on device */
+ uint64_t b_lblkno; /* block # on device */
+ size_t b_resid; /* # of bytes not transferred */
+ size_t b_bufsize; /* size of allocated buffer */
+/* caddr_t b_iodone; I/O completion routine */
+ int b_error; /* expanded error field */
+/* dev_t b_edev; extended device */
} bufinfo_t;
#pragma D binding "1.0" translator
translator bufinfo_t < struct bio *B > {
- b_flags = B->bio_flags;
- b_bcount = B->bio_bcount;
- b_addr = B->bio_data;
- b_blkno = 0;
- b_lblkno = 0;
- b_resid = B->bio_resid;
- b_bufsize = 0; /* XXX gnn */
- b_error = B->bio_error;
+ b_cmd = B->bio_cmd;
+ b_flags = B->bio_flags;
+ b_bcount = B->bio_bcount;
+ b_addr = B->bio_data;
+ b_blkno = 0;
+ b_lblkno = 0;
+ b_resid = B->bio_resid;
+ b_bufsize = 0; /* XXX gnn */
+ b_error = B->bio_error;
};
/*
@@ -106,4 +112,150 @@
inline int O_TRUNC = 0x0400;
#pragma D binding "1.1" O_TRUNC
+/*
+ * The following inline constants can be used to examine bio_cmd of struct bio
+ * or a translated bufinfo_t.
+ */
+inline int BIO_READ = 0x01;
+#pragma D binding "1.13" BIO_READ
+inline int BIO_WRITE = 0x02;
+#pragma D binding "1.13" BIO_WRITE
+inline int BIO_DELETE = 0x03;
+#pragma D binding "1.13" BIO_DELETE
+inline int BIO_GETATTR = 0x04;
+#pragma D binding "1.13" BIO_GETATTR
+inline int BIO_FLUSH = 0x05;
+#pragma D binding "1.13" BIO_FLUSH
+inline int BIO_CMD0 = 0x06;
+#pragma D binding "1.13" BIO_CMD0
+inline int BIO_CMD1 = 0x07;
+#pragma D binding "1.13" BIO_CMD1
+inline int BIO_CMD2 = 0x08;
+#pragma D binding "1.13" BIO_CMD2
+inline int BIO_ZONE = 0x09;
+#pragma D binding "1.13" BIO_ZONE
+/*
+ * The following inline constants can be used to examine bio_flags of struct
+ * bio or a translated bufinfo_t.
+ */
+inline int BIO_ERROR = 0x01;
+#pragma D binding "1.13" BIO_ERROR
+inline int BIO_DONE = 0x02;
+#pragma D binding "1.13" BIO_DONE
+inline int BIO_ONQUEUE = 0x04;
+#pragma D binding "1.13" BIO_ONQUEUE
+inline int BIO_ORDERED = 0x08;
+#pragma D binding "1.13" BIO_ORDERED
+inline int BIO_UNMAPPED = 0x10;
+#pragma D binding "1.13" BIO_UNMAPPED
+inline int BIO_TRANSIENT_MAPPING = 0x20;
+#pragma D binding "1.13" BIO_TRANSIENT_MAPPING
+inline int BIO_VLIST = 0x40;
+#pragma D binding "1.13" BIO_VLIST
+
+/*
+ * The following inline constants can be used to examine device_type of struct
+ * devstat or a translated devinfo_t.
+ */
+inline int DEVSTAT_TYPE_DIRECT = 0x000;
+#pragma D binding "1.13" DEVSTAT_TYPE_DIRECT
+inline int DEVSTAT_TYPE_SEQUENTIAL = 0x001;
+#pragma D binding "1.13" DEVSTAT_TYPE_SEQUENTIAL
+inline int DEVSTAT_TYPE_PRINTER = 0x002;
+#pragma D binding "1.13" DEVSTAT_TYPE_PRINTER
+inline int DEVSTAT_TYPE_PROCESSOR = 0x003;
+#pragma D binding "1.13" DEVSTAT_TYPE_PROCESSOR
+inline int DEVSTAT_TYPE_WORM = 0x004;
+#pragma D binding "1.13" DEVSTAT_TYPE_WORM
+inline int DEVSTAT_TYPE_CDROM = 0x005;
+#pragma D binding "1.13" DEVSTAT_TYPE_CDROM
+inline int DEVSTAT_TYPE_SCANNER = 0x006;
+#pragma D binding "1.13" DEVSTAT_TYPE_SCANNER
+inline int DEVSTAT_TYPE_OPTICAL = 0x007;
+#pragma D binding "1.13" DEVSTAT_TYPE_OPTICAL
+inline int DEVSTAT_TYPE_CHANGER = 0x008;
+#pragma D binding "1.13" DEVSTAT_TYPE_CHANGER
+inline int DEVSTAT_TYPE_COMM = 0x009;
+#pragma D binding "1.13" DEVSTAT_TYPE_COMM
+inline int DEVSTAT_TYPE_ASC0 = 0x00a;
+#pragma D binding "1.13" DEVSTAT_TYPE_ASC0
+inline int DEVSTAT_TYPE_ASC1 = 0x00b;
+#pragma D binding "1.13" DEVSTAT_TYPE_ASC1
+inline int DEVSTAT_TYPE_STORARRAY = 0x00c;
+#pragma D binding "1.13" DEVSTAT_TYPE_STORARRAY
+inline int DEVSTAT_TYPE_ENCLOSURE = 0x00d;
+#pragma D binding "1.13" DEVSTAT_TYPE_ENCLOSURE
+inline int DEVSTAT_TYPE_FLOPPY = 0x00e;
+#pragma D binding "1.13" DEVSTAT_TYPE_FLOPPY
+inline int DEVSTAT_TYPE_MASK = 0x00f;
+#pragma D binding "1.13" DEVSTAT_TYPE_MASK
+inline int DEVSTAT_TYPE_IF_SCSI = 0x010;
+#pragma D binding "1.13" DEVSTAT_TYPE_IF_SCSI
+inline int DEVSTAT_TYPE_IF_IDE = 0x020;
+#pragma D binding "1.13" DEVSTAT_TYPE_IF_IDE
+inline int DEVSTAT_TYPE_IF_OTHER = 0x030;
+#pragma D binding "1.13" DEVSTAT_TYPE_IF_OTHER
+inline int DEVSTAT_TYPE_IF_MASK = 0x0f0;
+#pragma D binding "1.13" DEVSTAT_TYPE_IF_MASK
+inline int DEVSTAT_TYPE_PASS = 0x100;
+#pragma D binding "1.13" DEVSTAT_TYPE_PASS
+
+#pragma D binding "1.13" device_type_string
+inline string device_type_string[int type] =
+ type == DEVSTAT_TYPE_DIRECT ? "DIRECT" :
+ type == DEVSTAT_TYPE_SEQUENTIAL ? "SEQUENTIAL" :
+ type == DEVSTAT_TYPE_PRINTER ? "PRINTER" :
+ type == DEVSTAT_TYPE_PROCESSOR ? "PROCESSOR" :
+ type == DEVSTAT_TYPE_WORM ? "WORM" :
+ type == DEVSTAT_TYPE_CDROM ? "CDROM" :
+ type == DEVSTAT_TYPE_SCANNER ? "SCANNER" :
+ type == DEVSTAT_TYPE_OPTICAL ? "OPTICAL" :
+ type == DEVSTAT_TYPE_CHANGER ? "CHANGER" :
+ type == DEVSTAT_TYPE_COMM ? "COMM" :
+ type == DEVSTAT_TYPE_ASC0 ? "ASC0" :
+ type == DEVSTAT_TYPE_ASC1 ? "ASC1" :
+ type == DEVSTAT_TYPE_STORARRAY ? "STORARRAY" :
+ type == DEVSTAT_TYPE_ENCLOSURE ? "ENCLOSURE" :
+ type == DEVSTAT_TYPE_FLOPPY ? "FLOPPY" :
+ strjoin("UNKNOWN(", strjoin(lltostr(type), ")"));
+
+#pragma D binding "1.13" device_type
+inline string device_type[int type] =
+ device_type_string[type & DEVSTAT_TYPE_MASK];
+
+#pragma D binding "1.13" device_if_string
+inline string device_if_string[int type] =
+ type == 0 ? "ACCESS" :
+ type == DEVSTAT_TYPE_IF_SCSI ? "SCSI" :
+ type == DEVSTAT_TYPE_IF_IDE ? "IDE" :
+ type == DEVSTAT_TYPE_IF_OTHER ? "OTHER" :
+ strjoin("UNKNOWN(", strjoin(lltostr(type), ")"));
+
+#pragma D binding "1.13" device_if
+inline string device_if[int type] =
+ device_if_string[type & DEVSTAT_TYPE_IF_MASK];
+
+#pragma D binding "1.13" bio_cmd_string
+inline string bio_cmd_string[int cmd] =
+ cmd == BIO_READ ? "READ" :
+ cmd == BIO_WRITE ? "WRITE" :
+ cmd == BIO_DELETE ? "DELETE" :
+ cmd == BIO_GETATTR ? "GETATTR" :
+ cmd == BIO_FLUSH ? "FLUSH" :
+ cmd == BIO_CMD0 ? "CMD0" :
+ cmd == BIO_CMD1 ? "CMD1" :
+ cmd == BIO_CMD2 ? "CMD2" :
+ cmd == BIO_ZONE ? "ZONE" :
+ strjoin("UNKNOWN(", strjoin(lltostr(cmd), ")"));
+
+#pragma D binding "1.13" bio_flag_string
+inline string bio_flag_string[int flag] =
+ flag == BIO_ERROR ? "ERROR" :
+ flag == BIO_DONE ? "DONE" :
+ flag == BIO_ONQUEUE ? "ONQUEUE" :
+ flag == BIO_ORDERED ? "ORDERED" :
+ flag == BIO_UNMAPPED ? "UNMAPPED" :
+ flag == BIO_TRANSIENT_MAPPING ? "TRANSIENT_MAPPING" :
+ flag == BIO_VLIST ? "VLIST" :
+ "";
Index: stable/11/cddl/lib/libdtrace/ip.d
===================================================================
--- stable/11/cddl/lib/libdtrace/ip.d
+++ stable/11/cddl/lib/libdtrace/ip.d
@@ -215,10 +215,10 @@
#pragma D binding "1.6.3" translator
translator csinfo_t < struct inpcb *p > {
- cs_addr = NULL;
- cs_cid = (uint64_t)p;
- cs_pid = 0; /* XXX */
- cs_zoneid = 0;
+ cs_addr = NULL;
+ cs_cid = (uint64_t)p;
+ cs_pid = 0; /* XXX */
+ cs_zoneid = 0;
};
#pragma D binding "1.5" translator
Index: stable/11/cddl/lib/libdtrace/libproc_compat.h
===================================================================
--- stable/11/cddl/lib/libdtrace/libproc_compat.h
+++ stable/11/cddl/lib/libdtrace/libproc_compat.h
@@ -4,7 +4,7 @@
*
* This software was developed by Rui Paulo under sponsorship from the
* FreeBSD Foundation.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
Index: stable/11/cddl/lib/libdtrace/psinfo.d
===================================================================
--- stable/11/cddl/lib/libdtrace/psinfo.d
+++ stable/11/cddl/lib/libdtrace/psinfo.d
@@ -97,4 +97,3 @@
inline lwpsinfo_t *curlwpsinfo = xlate <lwpsinfo_t *> (curthread);
#pragma D attributes Stable/Stable/Common curlwpsinfo
#pragma D binding "1.0" curlwpsinfo
-
Index: stable/11/cddl/lib/libdtrace/regs_x86.d
===================================================================
--- stable/11/cddl/lib/libdtrace/regs_x86.d
+++ stable/11/cddl/lib/libdtrace/regs_x86.d
@@ -1,4 +1,4 @@
-/*
+/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
@@ -116,4 +116,3 @@
#pragma D binding "1.0" R_R14
inline int R_R15 = 18 + 1 + 0;
#pragma D binding "1.0" R_R15
-
Index: stable/11/cddl/lib/libdtrace/sched.d
===================================================================
--- stable/11/cddl/lib/libdtrace/sched.d
+++ stable/11/cddl/lib/libdtrace/sched.d
@@ -81,4 +81,3 @@
inline lgrp_id_t lgrp = curcpu->cpu_lgrp;
#pragma D attributes Stable/Stable/Common lgrp
#pragma D binding "1.0" lgrp
-
Index: stable/11/cddl/lib/libdtrace/signal.d
===================================================================
--- stable/11/cddl/lib/libdtrace/signal.d
+++ stable/11/cddl/lib/libdtrace/signal.d
@@ -20,6 +20,7 @@
* CDDL HEADER END
*
* Portions Copyright 2008 John Birrell jb@freebsd.org
+ * Portions Copyright 2018 Devin Teske dteske@freebsd.org
*
* $FreeBSD$
*/
@@ -86,7 +87,48 @@
#pragma D binding "1.0" SIGUSR1
inline int SIGUSR2 = 31;
#pragma D binding "1.0" SIGUSR2
+inline int SIGTHR = 32;
+#pragma D binding "1.13" SIGTHR
+inline int SIGLIBRT = 33;
+#pragma D binding "1.13" SIGLIBRT
+#pragma D binding "1.13" signal_string
+inline string signal_string[int signal] =
+ signal == SIGHUP ? "SIGHUP" :
+ signal == SIGINT ? "SIGINT" :
+ signal == SIGQUIT ? "SIGQUIT" :
+ signal == SIGILL ? "SIGILL":
+ signal == SIGTRAP ? "SIGTRAP" :
+ signal == SIGABRT ? "SIGABRT" :
+ signal == SIGEMT ? "SIGEMT" :
+ signal == SIGFPE ? "SIGFPE" :
+ signal == SIGKILL ? "SIGKILL" :
+ signal == SIGBUS ? "SIGBUS" :
+ signal == SIGSEGV ? "SIGSEGV" :
+ signal == SIGSYS ? "SIGSYS" :
+ signal == SIGPIPE ? "SIGPIPE" :
+ signal == SIGALRM ? "SIGALRM" :
+ signal == SIGTERM ? "SIGTERM" :
+ signal == SIGURG ? "SIGURG" :
+ signal == SIGSTOP ? "SIGSTOP" :
+ signal == SIGTSTP ? "SIGTSTP" :
+ signal == SIGCONT ? "SIGCONT" :
+ signal == SIGCHLD ? "SIGCHLD" :
+ signal == SIGTTIN ? "SIGTTIN" :
+ signal == SIGTTOU ? "SIGTTOU" :
+ signal == SIGIO ? "SIGIO" :
+ signal == SIGXCPU ? "SIGXCPU" :
+ signal == SIGXFSZ ? "SIGXFSZ" :
+ signal == SIGVTALRM ? "SIGVTALRM" :
+ signal == SIGPROF ? "SIGPROF" :
+ signal == SIGWINCH ? "SIGWINCH" :
+ signal == SIGINFO ? "SIGINFO" :
+ signal == SIGUSR1 ? "SIGUSR1" :
+ signal == SIGUSR2 ? "SIGUSR2" :
+ signal == SIGTHR ? "SIGTHR" :
+ signal == SIGLIBRT ? "SIGLIBRT" :
+ "UNKNOWN";
+
inline int CLD_EXITED = 1;
#pragma D binding "1.0" CLD_EXITED
inline int CLD_KILLED = 2;
@@ -99,3 +141,13 @@
#pragma D binding "1.0" CLD_STOPPED
inline int CLD_CONTINUED = 6;
#pragma D binding "1.0" CLD_CONTINUED
+
+#pragma D binding "1.13" child_signal_string
+inline string child_signal_string[int child_signal] =
+ child_signal == CLD_EXITED ? "child exited" :
+ child_signal == CLD_KILLED ? "child terminated abnormally" :
+ child_signal == CLD_DUMPED ? "child core dumped" :
+ child_signal == CLD_TRAPPED ? "traced child trapped" :
+ child_signal == CLD_STOPPED ? "child stopped" :
+ child_signal == CLD_CONTINUED ? "stopped child continued" :
+ strjoin("unknown SIGCHLD code (", strjoin(lltostr(child_signal), ")"));
Index: stable/11/cddl/lib/libdtrace/tcp.d
===================================================================
--- stable/11/cddl/lib/libdtrace/tcp.d
+++ stable/11/cddl/lib/libdtrace/tcp.d
@@ -118,18 +118,18 @@
int32_t tcps_rcv_ws; /* receive window scaling */
u_long tcps_cwnd; /* congestion window */
u_long tcps_cwnd_ssthresh; /* threshold for congestion avoidance */
- uint32_t tcps_srecover; /* for use in NewReno Fast Recovery */
+ uint32_t tcps_srecover; /* for use in NewReno Fast Recovery */
uint32_t tcps_sack_fack; /* SACK sequence # we have acked */
uint32_t tcps_sack_snxt; /* next SACK seq # for retransmission */
uint32_t tcps_rto; /* round-trip timeout, msec */
uint32_t tcps_mss; /* max segment size */
int tcps_retransmit; /* retransmit send event, boolean */
int tcps_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
- int tcps_debug; /* socket has SO_DEBUG set */
- int tcps_cookie; /* expose the socket's SO_USER_COOKIE */
- int32_t tcps_dupacks; /* consecutive dup acks received */
- uint32_t tcps_rtttime; /* RTT measurement start time */
- uint32_t tcps_rtseq; /* sequence # being timed */
+ int tcps_debug; /* socket has SO_DEBUG set */
+ int tcps_cookie; /* expose the socket's SO_USER_COOKIE */
+ int32_t tcps_dupacks; /* consecutive dup acks received */
+ uint32_t tcps_rtttime; /* RTT measurement start time */
+ uint32_t tcps_rtseq; /* sequence # being timed */
uint32_t tcps_ts_recent; /* timestamp echo data */
} tcpsinfo_t;
@@ -206,31 +206,31 @@
tcps_snxt = p == NULL ? 0 : p->snd_nxt;
tcps_rack = p == NULL ? 0 : p->last_ack_sent;
tcps_rnxt = p == NULL ? 0 : p->rcv_nxt;
- tcps_swnd = p == NULL ? -1 : p->snd_wnd;
- tcps_snd_ws = p == NULL ? -1 : p->snd_scale;
- tcps_swl1 = p == NULL ? -1 : p->snd_wl1;
- tcps_swl2 = p == NULL ? -1 : p->snd_wl2;
- tcps_radv = p == NULL ? -1 : p->rcv_adv;
- tcps_rwnd = p == NULL ? -1 : p->rcv_wnd;
- tcps_rup = p == NULL ? -1 : p->rcv_up;
- tcps_rcv_ws = p == NULL ? -1 : p->rcv_scale;
- tcps_cwnd = p == NULL ? -1 : p->snd_cwnd;
- tcps_cwnd_ssthresh = p == NULL ? -1 : p->snd_ssthresh;
- tcps_srecover = p == NULL ? -1 : p->snd_recover;
+ tcps_swnd = p == NULL ? -1 : p->snd_wnd;
+ tcps_snd_ws = p == NULL ? -1 : p->snd_scale;
+ tcps_swl1 = p == NULL ? -1 : p->snd_wl1;
+ tcps_swl2 = p == NULL ? -1 : p->snd_wl2;
+ tcps_radv = p == NULL ? -1 : p->rcv_adv;
+ tcps_rwnd = p == NULL ? -1 : p->rcv_wnd;
+ tcps_rup = p == NULL ? -1 : p->rcv_up;
+ tcps_rcv_ws = p == NULL ? -1 : p->rcv_scale;
+ tcps_cwnd = p == NULL ? -1 : p->snd_cwnd;
+ tcps_cwnd_ssthresh = p == NULL ? -1 : p->snd_ssthresh;
+ tcps_srecover = p == NULL ? -1 : p->snd_recover;
tcps_sack_fack = p == NULL ? 0 : p->snd_fack;
tcps_sack_snxt = p == NULL ? 0 : p->sack_newdata;
tcps_rto = p == NULL ? -1 : (p->t_rxtcur * 1000) / `hz;
- tcps_mss = p == NULL ? -1 : p->t_maxseg;
+ tcps_mss = p == NULL ? -1 : p->t_maxseg;
tcps_retransmit = p == NULL ? -1 : p->t_rxtshift > 0 ? 1 : 0;
- tcps_srtt = p == NULL ? -1 : p->t_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
+ tcps_srtt = p == NULL ? -1 : p->t_srtt; /* smoothed RTT in units of (TCP_RTT_SCALE*hz) */
tcps_debug = p == NULL ? 0 :
p->t_inpcb->inp_socket->so_options & 1;
tcps_cookie = p == NULL ? -1 :
p->t_inpcb->inp_socket->so_user_cookie;
- tcps_dupacks = p == NULL ? -1 : p->t_dupacks;
- tcps_rtttime = p == NULL ? -1 : p->t_rtttime;
- tcps_rtseq = p == NULL ? -1 : p->t_rtseq;
- tcps_ts_recent = p == NULL ? -1 : p->ts_recent;
+ tcps_dupacks = p == NULL ? -1 : p->t_dupacks;
+ tcps_rtttime = p == NULL ? -1 : p->t_rtttime;
+ tcps_rtseq = p == NULL ? -1 : p->t_rtseq;
+ tcps_ts_recent = p == NULL ? -1 : p->ts_recent;
};
#pragma D binding "1.6.3" translator
@@ -319,74 +319,74 @@
#pragma D binding "1.12.1" PRU_CONNECT
inline int PRU_CONNECT = 4;
#pragma D binding "1.12.1" PRU_ACCEPT
-inline int PRU_ACCEPT = 5 ;
+inline int PRU_ACCEPT = 5 ;
#pragma D binding "1.12.1" PRU_DISCONNECT
-inline int PRU_DISCONNECT= 6;
+inline int PRU_DISCONNECT = 6;
#pragma D binding "1.12.1" PRU_SHUTDOWN
-inline int PRU_SHUTDOWN = 7;
+inline int PRU_SHUTDOWN = 7;
#pragma D binding "1.12.1" PRU_RCVD
-inline int PRU_RCVD = 8;
+inline int PRU_RCVD = 8;
#pragma D binding "1.12.1" PRU_SEND
-inline int PRU_SEND = 9;
+inline int PRU_SEND = 9;
#pragma D binding "1.12.1" PRU_ABORT
-inline int PRU_ABORT = 10;
+inline int PRU_ABORT = 10;
#pragma D binding "1.12.1" PRU_CONTROL
-inline int PRU_CONTROL = 11;
+inline int PRU_CONTROL = 11;
#pragma D binding "1.12.1" PRU_SENSE
-inline int PRU_SENSE = 12;
+inline int PRU_SENSE = 12;
#pragma D binding "1.12.1" PRU_RCVOOB
-inline int PRU_RCVOOB = 13;
+inline int PRU_RCVOOB = 13;
#pragma D binding "1.12.1" PRU_SENDOOB
-inline int PRU_SENDOOB = 14;
+inline int PRU_SENDOOB = 14;
#pragma D binding "1.12.1" PRU_SOCKADDR
-inline int PRU_SOCKADDR = 15;
+inline int PRU_SOCKADDR = 15;
#pragma D binding "1.12.1" PRU_PEERADDR
-inline int PRU_PEERADDR = 16;
+inline int PRU_PEERADDR = 16;
#pragma D binding "1.12.1" PRU_CONNECT2
-inline int PRU_CONNECT2 = 17;
+inline int PRU_CONNECT2 = 17;
#pragma D binding "1.12.1" PRU_FASTTIMO
-inline int PRU_FASTTIMO = 18;
+inline int PRU_FASTTIMO = 18;
#pragma D binding "1.12.1" PRU_SLOWTIMO
-inline int PRU_SLOWTIMO = 19;
+inline int PRU_SLOWTIMO = 19;
#pragma D binding "1.12.1" PRU_PROTORCV
-inline int PRU_PROTORCV = 20;
+inline int PRU_PROTORCV = 20;
#pragma D binding "1.12.1" PRU_PROTOSEND
-inline int PRU_PROTOSEND = 21;
+inline int PRU_PROTOSEND = 21;
#pragma D binding "1.12.1" PRU_SEND_EOF
-inline int PRU_SEND_EOF = 22;
+inline int PRU_SEND_EOF = 22;
#pragma D binding "1.12.1" PRU_SOSETLABEL
-inline int PRU_SOSETLABEL = 23;
+inline int PRU_SOSETLABEL = 23;
#pragma D binding "1.12.1" PRU_CLOSE
-inline int PRU_CLOSE = 24;
+inline int PRU_CLOSE = 24;
#pragma D binding "1.12.1" PRU_FLUSH
-inline int PRU_FLUSH = 25;
+inline int PRU_FLUSH = 25;
#pragma D binding "1.12.1" prureq_string
inline string prureq_string[uint8_t req] =
- req == PRU_ATTACH ? "ATTACH" :
- req == PRU_DETACH ? "DETACH" :
- req == PRU_BIND ? "BIND" :
- req == PRU_LISTEN ? "LISTEN" :
- req == PRU_CONNECT ? "CONNECT" :
- req == PRU_ACCEPT ? "ACCEPT" :
- req == PRU_DISCONNECT ? "DISCONNECT" :
- req == PRU_SHUTDOWN ? "SHUTDOWN" :
- req == PRU_RCVD ? "RCVD" :
- req == PRU_SEND ? "SEND" :
- req == PRU_ABORT ? "ABORT" :
- req == PRU_CONTROL ? "CONTROL" :
- req == PRU_SENSE ? "SENSE" :
- req == PRU_RCVOOB ? "RCVOOB" :
- req == PRU_SENDOOB ? "SENDOOB" :
- req == PRU_SOCKADDR ? "SOCKADDR" :
- req == PRU_PEERADDR ? "PEERADDR" :
- req == PRU_CONNECT2 ? "CONNECT2" :
- req == PRU_FASTTIMO ? "FASTTIMO" :
- req == PRU_SLOWTIMO ? "SLOWTIMO" :
- req == PRU_PROTORCV ? "PROTORCV" :
- req == PRU_PROTOSEND ? "PROTOSEND" :
- req == PRU_SEND ? "SEND_EOF" :
- req == PRU_SOSETLABEL ? "SOSETLABEL" :
- req == PRU_CLOSE ? "CLOSE" :
- req == PRU_FLUSH ? "FLUSE" :
+ req == PRU_ATTACH ? "ATTACH" :
+ req == PRU_DETACH ? "DETACH" :
+ req == PRU_BIND ? "BIND" :
+ req == PRU_LISTEN ? "LISTEN" :
+ req == PRU_CONNECT ? "CONNECT" :
+ req == PRU_ACCEPT ? "ACCEPT" :
+ req == PRU_DISCONNECT ? "DISCONNECT" :
+ req == PRU_SHUTDOWN ? "SHUTDOWN" :
+ req == PRU_RCVD ? "RCVD" :
+ req == PRU_SEND ? "SEND" :
+ req == PRU_ABORT ? "ABORT" :
+ req == PRU_CONTROL ? "CONTROL" :
+ req == PRU_SENSE ? "SENSE" :
+ req == PRU_RCVOOB ? "RCVOOB" :
+ req == PRU_SENDOOB ? "SENDOOB" :
+ req == PRU_SOCKADDR ? "SOCKADDR" :
+ req == PRU_PEERADDR ? "PEERADDR" :
+ req == PRU_CONNECT2 ? "CONNECT2" :
+ req == PRU_FASTTIMO ? "FASTTIMO" :
+ req == PRU_SLOWTIMO ? "SLOWTIMO" :
+ req == PRU_PROTORCV ? "PROTORCV" :
+ req == PRU_PROTOSEND ? "PROTOSEND" :
+ req == PRU_SEND ? "SEND_EOF" :
+ req == PRU_SOSETLABEL ? "SOSETLABEL" :
+ req == PRU_CLOSE ? "CLOSE" :
+ req == PRU_FLUSH ? "FLUSE" :
"unknown" ;
Index: stable/11/cddl/lib/libdtrace/udp.d
===================================================================
--- stable/11/cddl/lib/libdtrace/udp.d
+++ stable/11/cddl/lib/libdtrace/udp.d
@@ -47,7 +47,7 @@
uint16_t udp_sport; /* source port */
uint16_t udp_dport; /* destination port */
uint16_t udp_length; /* total length */
- uint16_t udp_checksum; /* headers + data checksum */
+ uint16_t udp_checksum; /* headers + data checksum */
struct udphdr *udp_hdr; /* raw UDP header */
} udpinfo_t;
Index: stable/11/cddl/usr.sbin/Makefile
===================================================================
--- stable/11/cddl/usr.sbin/Makefile
+++ stable/11/cddl/usr.sbin/Makefile
@@ -3,6 +3,7 @@
.include <src.opts.mk>
SUBDIR= ${_dtrace} \
+ ${_dwatch} \
${_lockstat} \
${_plockstat} \
${_tests} \
@@ -26,6 +27,7 @@
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
_dtrace= dtrace
+_dwatch= dwatch
_lockstat= lockstat
_plockstat= plockstat
.endif
@@ -33,15 +35,18 @@
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \
${MACHINE_CPUARCH} == "riscv"
_dtrace= dtrace
+_dwatch= dwatch
_lockstat= lockstat
.endif
.if ${MACHINE_CPUARCH} == "mips"
_dtrace= dtrace
+_dwatch= dwatch
.endif
.if ${MACHINE_CPUARCH} == "powerpc"
_dtrace= dtrace
+_dwatch= dwatch
_lockstat= lockstat
.endif
Index: stable/11/cddl/usr.sbin/dwatch/Makefile
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/Makefile
+++ stable/11/cddl/usr.sbin/dwatch/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+.include <src.opts.mk>
+
+SUBDIR= libexec
+
+.if ${MK_EXAMPLES} != "no"
+SUBDIR+= examples
+.endif
+
+SCRIPTS= dwatch
+
+MAN= dwatch.1
+
+.include <bsd.prog.mk>
Index: stable/11/cddl/usr.sbin/dwatch/dwatch
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/dwatch
+++ stable/11/cddl/usr.sbin/dwatch/dwatch
@@ -0,0 +1,1401 @@
+#!/bin/sh
+#-
+# Copyright (c) 2014-2018 Devin Teske
+# All rights reserved.
+#
+# 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.
+#
+############################################################ IDENT(1)
+#
+# $Title: Watch processes as they trigger a particular DTrace probe $
+# $FreeBSD$
+#
+############################################################ CONFIGURATION
+
+#
+# DTrace pragma settings
+#
+DTRACE_PRAGMA="
+ option quiet
+ option dynvarsize=16m
+ option switchrate=10hz
+" # END-QUOTE
+
+#
+# Profiles
+#
+: ${DWATCH_PROFILES_PATH="/usr/libexec/dwatch:/usr/local/libexec/dwatch"}
+
+############################################################ GLOBALS
+
+VERSION='$Version: 1.2 $' # -V
+
+pgm="${0##*/}" # Program basename
+
+#
+# Command-line arguments
+#
+PROBE_ARG=
+
+#
+# Command-line defaults
+#
+_MAX_ARGS=64 # -B num
+_MAX_DEPTH=64 # -K num
+
+#
+# Command-line options
+#
+CONSOLE= # -y
+CONSOLE_FORCE= # -y
+[ -t 1 ] && CONSOLE=1 # -y
+COUNT=0 # -N count
+CUSTOM_DETAILS= # -E code
+CUSTOM_TEST= # -t test
+DEBUG= # -d
+DESTRUCTIVE_ACTIONS= # -w
+DEVELOPER= # -dev
+EXECNAME= # -k name
+EXECREGEX= # -z regex
+EXIT_AFTER_COMPILE= # -e
+FILTER= # -r regex
+PROBE_COALESCE= # -F
+GROUP= # -g group
+JID= # -j jail
+LIST= # -l
+LIST_PROFILES= # -Q
+MAX_ARGS=$_MAX_ARGS # -B num
+MAX_DEPTH=$_MAX_DEPTH # -K num
+ONELINE= # -1
+OUTPUT= # -o file
+OUTPUT_CMD= # -O cmd
+PID= # -p pid
+PROBE_TYPE= # -f -m -n -P
+PROFILE= # -X profile
+PSTREE= # -R
+QUIET= # -q
+TIMEOUT= # -T time
+TRACE= # -x
+USER= # -u user
+USE_PROFILE= # -X profile
+VERBOSE= # -v
+
+#
+# Global exit status
+#
+SUCCESS=0
+FAILURE=1
+
+#
+# Miscellaneous
+#
+ACTIONS=
+EVENT_DETAILS=
+EVENT_TAG='printf("%d.%d %s[%d]: ",
+ this->uid0, this->gid0, execname, this->pid0);'
+EVENT_TEST=
+FILE=
+ID=3
+MODULE_CHECKED=
+PROBE=
+PSARGS=1
+RGID=
+RUID=
+SUDO=
+export SUDO_PROMPT="[sudo] Password:"
+TITLE=\$Title:
+
+############################################################ FUNCTIONS
+
+ansi() { local fmt="$2 $4"; [ "$CONSOLE" ] && fmt="\\033[$1m$2\\033[$3m $4";
+ shift 4; printf "$fmt\n" "$@"; }
+die() { exec >&2; [ "$*" ] && echo "$pgm:" "$@"; exit $FAILURE; }
+info() { [ "$QUIET" ] || ansi 35 "INFO" 39 "$@" >&2; }
+
+usage()
+{
+ local optfmt="\t%-10s %s\n"
+ exec >&2
+ [ "$*" ] && printf "%s: %s\n" "$pgm" "$*"
+ printf "Usage: %s [-1defFmnPqRvVwxy] [%s] [%s] [%s] [%s]\n" "$pgm" \
+ "-B num" "-E code" "-g group" "-j jail"
+ printf "\t [%s] [%s] [%s] [%s] [%s] [%s]\n" \
+ "-k name" "-K num" "-N count" "-o file" "-O cmd" "-p pid"
+ printf "\t [%s] [%s] [%s] [%s] [%s] [%s]\n" \
+ "-r regex" "-t test" "-T time" "-u user" "-X profile" \
+ "-z regex"
+ printf "\t probe[,...] [args ...]\n"
+ printf " %s -l [-fmnPqy] [-r regex] [probe ...]\n" "$pgm"
+ printf " %s -Q [-1qy] [-r regex]\n" "$pgm"
+ printf "\n"
+ printf "$optfmt" "-1" \
+ "Print one line per process/profile (Default; disables \`-R')."
+ printf "$optfmt" "-B num" \
+ "Maximum process arguments to display (Default $_MAX_ARGS)."
+ printf "$optfmt" "-d" \
+ "Debug. Send dtrace(1) script to stdout instead of executing."
+ printf "$optfmt" "-e" \
+ "Exit after compiling request but prior to enabling probes."
+ printf "$optfmt" "-E code" \
+ "DTrace code for event details. If \`-', read from stdin."
+ printf "$optfmt" "-f" \
+ "Enable probe matching the specified function name."
+ printf "$optfmt" "-F" \
+ "Coalesce trace output by function."
+ printf "$optfmt" "-g group" \
+ "Group filter. Only show processes matching group name/gid."
+ printf "$optfmt" "-j jail" \
+ "Jail filter. Only show processes matching jail name/jid."
+ printf "$optfmt" "-k name" \
+ "Only show processes matching name."
+ printf "$optfmt" "-K num" \
+ "Maximum directory depth to display (Default $_MAX_DEPTH)."
+ printf "$optfmt" "-l" \
+ "List available probes on standard output and exit."
+ printf "$optfmt" "-m" \
+ "Enable probe matching the specified module name."
+ printf "$optfmt" "-n" \
+ "Enable probe matching the specified probe name."
+ printf "$optfmt" "-N count" \
+ "Exit after count matching entries (Default 0 for disabled)."
+ printf "$optfmt" "-o file" \
+ "Set output file. If \`-', the path \`/dev/stdout' is used."
+ printf "$optfmt" "-O cmd" \
+ "Execute cmd for each event."
+ printf "$optfmt" "-p pid" \
+ "Process id filter. Only show processes with matching pid."
+ printf "$optfmt" "-P" \
+ "Enable probe matching the specified provider name."
+ printf "$optfmt" "-q" \
+ "Quiet. Hide informational messages and all dtrace(1) errors."
+ printf "$optfmt" "-Q" \
+ "List available profiles in DWATCH_PROFILES_PATH and exit."
+ printf "$optfmt" "-r regex" \
+ "Filter. Only show blocks matching awk(1) regular expression."
+ printf "$optfmt" "-R" \
+ "Show parent, grandparent, and ancestor of process."
+ printf "$optfmt" "-t test" \
+ "Test clause (predicate) to limit events (Default none)."
+ printf "$optfmt" "-T time" \
+ "Timeout. Format is \`\#[smhd]' or simply \`\#' for seconds."
+ printf "$optfmt" "-u user" \
+ "User filter. Only show processes matching user name/uid."
+ printf "$optfmt" "-v" \
+ "Verbose. Show all errors from dtrace(1)."
+ printf "$optfmt" "-V" \
+ "Report dwatch version on standard output and exit."
+ printf "$optfmt" "-w" \
+ "Permit destructive actions (copyout*, stop, panic, etc.)."
+ printf "$optfmt" "-x" \
+ "Trace. Print \`<probe-id>' when a probe is triggered."
+ printf "$optfmt" "-X profile" \
+ "Load profile name from DWATCH_PROFILES_PATH."
+ printf "$optfmt" "-y" \
+ "Always treat stdout as console (enable colors/columns/etc.)."
+ printf "$optfmt" "-z regex" \
+ "Only show processes matching awk(1) regular expression."
+ die
+}
+
+dtrace_cmd()
+{
+ local status stdout
+ local timeout=
+
+ if [ "$1" = "-t" ]; then
+ shift
+ [ "$TIMEOUT" ] && timeout=1
+ fi
+
+ exec 3>&1
+ stdout=3
+
+ #
+ # Filter dtrace(1) stderr while preserving exit status
+ #
+ status=$(
+ exec 4>&1
+ to_status=4
+ ( trap 'echo $? >&$to_status' EXIT
+ eval $SUDO ${timeout:+timeout \"\$TIMEOUT\"} dtrace \
+ \"\$@\" 2>&1 ${QUIET:+2> /dev/null} >&$stdout
+ ) | dtrace_stderr_filter >&2
+ )
+
+ return $status
+}
+
+dtrace_stderr_filter()
+{
+ if [ "$VERBOSE" ]; then
+ cat
+ return
+ # NOTREACHED
+ fi
+
+ awk ' # Start awk(1) stderr-filter
+ /[[:digit:]]+ drops? on CPU [[:digit:]]+/ { next }
+ /failed to write to <stdout>: No such file or directory/ { next }
+ /failed to write to <stdout>: Broken pipe/ { next }
+ /processing aborted: Broken pipe/ { next }
+ /invalid address \(0x[[:xdigit:]]+\) in action #[[:digit:]]+/ { next }
+ /out of scratch space in action #[[:digit:]]+/ { next }
+ /^Bus error$/ { next }
+ { print; fflush() }
+ ' # END-QUOTE
+}
+
+expand_probe()
+{
+ local OPTIND=1 OPTARG flag
+ local type=
+
+ while getopts t: flag; do
+ case "$flag" in
+ t) type="$OPTARG" ;;
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
+ local probe="$1"
+ case "$probe" in
+ *:*)
+ echo "$probe"
+ return $SUCCESS
+ ;;
+ esac
+
+ dtrace_cmd -l | awk -v probe="$probe" -v type="$type" '
+ # Start awk(1) processor
+ #################################################### BEGIN
+ BEGIN { getline dtrace_header }
+ #################################################### FUNCTIONS
+ function dump(unused1,unused2) {
+ if (n) {
+ if (NcF[n] == 1) f = N2F[n]
+ if (NcM[n] == 1) m = N2M[n]
+ if (NcP[n] == 1) p = N2P[n]
+ } else if (f) {
+ if (FcM[f] == 1) m = F2M[f]
+ if (FcP[f] == 1) p = F2P[f]
+ if (FcN[f] == 0 && found) n = "entry"
+ } else if (m) {
+ if (McP[m] == 1) p = M2P[m]
+ }
+ printf "%s:%s:%s:%s\n", p, m, f, n
+ exit !found
+ }
+ function inFMP() { return probe in F || probe in M || probe in P }
+ function inNMP() { return probe in N || probe in M || probe in P }
+ function inNFP() { return probe in N || probe in F || probe in P }
+ function inNFM() { return probe in N || probe in F || probe in M }
+ function diva(value, peerA, peerB, peerC) {
+ return value >= peerA && value >= peerB && value >= peerC
+ }
+ #################################################### MAIN
+ type == "name" && $NF != probe { next }
+ type == "function" && NF >=4 && $(NF-1) != probe { next }
+ type == "module" && NF == 5 && $(NF-2) != probe { next }
+ type == "provider" && $2 != probe { next }
+ type || $2 == probe || $3 == probe || $4 == probe || $5 == probe {
+ P[_p = $2]++
+ M[_m = (NF >= 5 ? $(NF-2) : "")]++
+ F[_f = (NF >= 4 ? $(NF-1) : "")]++
+ N[_n = $NF]++
+ if (N2F[_n] != _f) NcF[_n]++; N2F[_n] = _f
+ if (N2M[_n] != _m) NcM[_n]++; N2M[_n] = _m
+ if (N2P[_n] != _p) NcP[_n]++; N2P[_n] = _p
+ if (_n !~ /entry|return/) {
+ if (F2N[_f] != _n) FcN[_f]++
+ F2N[_f] = _n
+ }
+ if (F2M[_f] != _m) FcM[_f]++; F2M[_f] = _m
+ if (F2P[_f] != _p) FcP[_f]++; F2P[_f] = _p
+ if (M2P[_m] != _p) McP[_m]++; M2P[_m] = _p
+ }
+ #################################################### END
+ END {
+ if (type == "name") dump(n = probe, found = probe in N)
+ if (type == "function") dump(f = probe, found = probe in F)
+ if (type == "module") dump(m = probe, found = probe in M)
+ if (type == "provider") dump(p = probe, found = probe in P)
+ if (probe in N) {
+ found = 1
+ if (!inFMP()) dump(n = probe)
+ if (diva(F[probe], N[probe], M[probe], P[probe]))
+ dump(f = probe)
+ if (diva(M[probe], N[probe], F[probe], P[probe]))
+ dump(m = probe)
+ if (diva(P[probe], N[probe], F[probe], M[probe]))
+ dump(p = probe)
+ dump(n = probe) # N is the diva
+ } else if (probe in F) {
+ found = 1
+ if (!inNMP()) dump(f = probe)
+ if (diva(N[probe], F[probe], M[probe], P[probe]))
+ dump(n = probe)
+ if (diva(M[probe], F[probe], N[probe], P[probe]))
+ dump(m = probe)
+ if (diva(P[probe], F[probe], N[probe], M[probe]))
+ dump(p = probe)
+ dump(f = probe) # F is the diva
+ } else if (probe in M) {
+ found = 1
+ if (!inNFP()) dump(m = probe)
+ if (diva(N[probe], M[probe], F[probe], P[probe]))
+ dump(n = probe)
+ if (diva(F[probe], M[probe], N[probe], P[probe]))
+ dump(f = probe)
+ if (diva(P[probe], M[probe], N[probe], F[probe]))
+ dump(p = probe)
+ dump(m = probe) # M is the diva
+ } else if (probe in P) {
+ found = 1
+ if (!inNFM()) dump(p = probe)
+ if (diva(N[probe], P[probe], F[probe], M[probe]))
+ dump(n = probe)
+ if (diva(F[probe], P[probe], N[probe], M[probe]))
+ dump(f = probe)
+ if (diva(M[probe], P[probe], N[probe], F[probe]))
+ dump(m = probe)
+ dump(p = probe) # P is the diva
+ }
+ if (!found) print probe
+ exit !found
+ }
+ ' # END-QUOTE
+}
+
+list_probes()
+{
+ local OPTIND=1 OPTARG flag
+ local column=0 header="PROVIDER:MODULE:FUNCTION:NAME"
+ local filter= quiet= type=
+
+ while getopts f:qt: flag; do
+ case "$flag" in
+ f) filter="$OPTARG" ;;
+ q) quiet=1 ;;
+ t) type="$OPTARG" ;;
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
+ if [ $# -eq 0 ]; then
+ case "$type" in
+ provider) column=1 header="PROVIDER" ;;
+ module) column=2 header="MODULE" ;;
+ function) column=3 header="FUNCTION" ;;
+ name) column=4 header="NAME" ;;
+ esac
+ fi
+
+ [ "$quiet" ] || echo "$header"
+
+ local arg probe=
+ for arg in "$@"; do
+ arg=$( expand_probe -t "$type" -- "$arg" )
+ probe="$probe${probe:+, }$arg"
+ done
+
+ dtrace_cmd -l${probe:+n "$probe"} | awk -v pattern="$(
+ # Prevent backslashes from being lost
+ echo "$filter" | awk 'gsub(/\\/,"&&")||1'
+ )" -v want="$column" -v console="$CONSOLE" '
+ BEGIN { getline dtrace_header }
+ function ans(seq) { return console ? "\033[" seq "m" : "" }
+ NF > 3 && $(NF-1) ~ /^#/ { next }
+ !_[$0 = column[0] = sprintf("%s:%s:%s:%s",
+ column[1] = $2,
+ column[2] = (NF >= 5 ? $(NF-2) : ""),
+ column[3] = (NF >= 4 ? $(NF-1) : ""),
+ column[4] = $NF)]++ &&
+ !__[$0 = column[want]]++ &&
+ gsub(pattern, ans("31;1") "&" ans("39;22")) {
+ print | "sort"
+ }
+ END { close("sort") }
+ ' # END-QUOTE
+
+ exit $SUCCESS
+}
+
+list_profiles()
+{
+ local OPTIND=1 OPTARG flag
+ local filter= oneline= quiet=
+
+ while getopts 1f:q flag; do
+ case "$flag" in
+ 1) oneline=1 ;;
+ f) filter="$OPTARG" ;;
+ q) quiet=1 ;;
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
+ # Prevent backslashes from being lost
+ filter=$( echo "$filter" | awk 'gsub(/\\/,"&&")||1' )
+
+ # Build a list of profiles available
+ local profiles
+ profiles=$( { IFS=:
+ for dir in $DWATCH_PROFILES_PATH; do
+ [ -d "$dir" ] || continue
+ for path in $dir/*; do
+ [ -f "$path" ] || continue
+ name="${path##*/}"
+ [ "$name" = "${name%%[!0-9A-Za-z_-]*}" ] ||
+ continue
+ echo $name
+ done
+ done
+ } | sort -u )
+
+ # Get the longest profile name
+ local longest_profile_name
+ longest_profile_name=$( echo "$profiles" |
+ awk -v N=0 '(L = length($0)) > N { N = L } END { print N }' )
+
+ # Get the width of the terminal
+ local max_size="$( stty size 2> /dev/null )"
+ : ${max_size:=24 80}
+ local max_width="${max_size#*[$IFS]}"
+
+ # Determine how many columns we can display
+ local x=$longest_profile_name ncols=1
+ [ "$QUIET" ] || x=$(( $x + 8 )) # Accommodate leading tab character
+ x=$(( $x + 3 + $longest_profile_name )) # Preload end of next column
+ while [ $x -lt $max_width ]; do
+ ncols=$(( $ncols + 1 ))
+ x=$(( $x + 3 + $longest_profile_name ))
+ done
+
+ # Output single lines if sent to a pipe
+ if [ "$oneline" ]; then
+ echo "$profiles" | awk -v filter="$filter" -v cons="$CONSOLE" '
+ function ans(s) { return cons ? "\033[" s "m" : "" }
+ gsub(filter, ans("31;1") "&" ans("39;22"))
+ ' # END-QUOTE
+ exit $SUCCESS
+ fi
+
+ [ "$quiet" ] || echo PROFILES:
+ echo "$profiles" | awk \
+ -v colsize=$longest_profile_name \
+ -v console="$CONSOLE" \
+ -v ncols=$ncols \
+ -v quiet="$quiet" \
+ -v filter="$filter" \
+ ' # Begin awk(1) processor
+ function ans(seq) { return console ? "\033[" seq "m" : "" }
+ BEGIN {
+ row_item[1] = ""
+ replace = ans("31;1") "&" ans("39;22")
+ ansi_offset = length(replace) - 1
+ }
+ function print_row()
+ {
+ cs = colsize + ansi_offset * \
+ gsub(filter, replace, row_item[1])
+ printf "%s%-*s", quiet ? "" : "\t", cs, row_item[1]
+ for (i = 2; i <= cur_col; i++) {
+ cs = colsize + ansi_offset * \
+ gsub(filter, replace, row_item[i])
+ printf " %-*s", cs, row_item[i]
+ }
+ printf "\n"
+ }
+ $0 ~ filter {
+ n++
+ cur_col = ((n - 1) % ncols) + 1
+ row_item[cur_col] = $0
+ if (cur_col == ncols) print_row()
+ }
+ END { if (cur_col < ncols) print_row() }
+ ' # END-QUOTE
+
+ exit $SUCCESS
+}
+
+shell_escape()
+{
+ echo "$*" | awk 'gsub(/'\''/, "&\\\\&&")||1'
+}
+
+load_profile()
+{
+ local profile="$1"
+
+ [ "$profile" ] ||
+ die "missing profile argument (\`$pgm -Q' to list profiles)"
+
+ local oldIFS="$IFS"
+ local dir found=
+ local ARGV=
+
+ [ $COUNT -gt 0 ] && ARGV="$ARGV -N $COUNT"
+ [ "$DEBUG" ] && ARGV="$ARGV -d"
+ [ "$DESTRUCTIVE_ACTIONS" ] && ARGV="$ARGV -w"
+ [ "$EXIT_AFTER_COMPILE" ] && ARGV="$ARGV -e"
+ [ "$GROUP" ] && ARGV="$ARGV -g $GROUP"
+ [ "$JID" ] && ARGV="$ARGV -j $JID"
+ [ $MAX_ARGS -ne $_MAX_ARGS ] && ARGV="$ARGV -B $MAX_ARGS"
+ [ $MAX_DEPTH -ne $_MAX_DEPTH ] && ARGV="$ARGV -K $MAX_DEPTH"
+ [ "$ONELINE" ] && ARGV="$ARGV -1"
+ [ "$PID" ] && ARGV="$ARGV -p $PID"
+ [ "$PSTREE" ] && ARGV="$ARGV -R"
+ [ "$QUIET" ] && ARGV="$ARGV -q"
+ [ "$TIMEOUT" ] && ARGV="$ARGV -T $TIMEOUT"
+ [ "$TRACE" ] && ARGV="$ARGV -x"
+ [ "$USER" ] && ARGV="$ARGV -u $USER"
+ [ "$VERBOSE" ] && ARGV="$ARGV -v"
+
+ [ "$FILTER" ] &&
+ ARGV="$ARGV -r '$( shell_escape "$FILTER" )'"
+ [ "$EXECREGEX" ] &&
+ ARGV="$ARGV -z '$( shell_escape "$EXECREGEX" )'"
+ [ "$CUSTOM_DETAILS" ] &&
+ ARGV="$ARGV -E '$( shell_escape "$EVENT_DETAILS" )'"
+ [ "$EVENT_TEST" ] &&
+ ARGV="$ARGV -t '$( shell_escape "$EVENT_TEST" )'"
+ [ "$OUTPUT" ] &&
+ ARGV="$ARGV -o '$( shell_escape "$OUTPUT" )'"
+ [ "$OUTPUT_CMD" ] &&
+ ARGV="$ARGV -O '$( shell_escape "$OUTPUT_CMD" )'"
+
+ case "$PROBE_TYPE" in
+ provider) ARGV="$ARGV -P" ;;
+ module) ARGV="$ARGV -m" ;;
+ function) ARGV="$ARGV -f" ;;
+ name) ARGV="$ARGV -n" ;;
+ esac
+
+ IFS=:
+ for dir in $DWATCH_PROFILES_PATH; do
+ [ -d "$dir" ] || continue
+ [ -f "$dir/$profile" ] || continue
+ PROFILE="$profile" found=1
+ info "Sourcing $profile profile [found in %s]" "$dir"
+ . "$dir/$profile"
+ break
+ done
+ IFS="$oldIFS"
+
+ [ "$found" ] ||
+ die "no module named \`$profile' (\`$pgm -Q' to list profiles)"
+}
+
+pproc()
+{
+ local OPTIND=1 OPTARG flag
+ local P= N=0
+
+ while getopts P: flag; do
+ case "$flag" in
+ P) P="$OPTARG" ;;
+ esac
+ done
+ shift $(( OPTIND - 1 ))
+
+ local proc=$1
+ if [ ! "$proc" ]; then
+ if [ "$P" = "0" ]; then
+ proc="curthread->td_proc"
+ else
+ proc="this->proc ? this->proc->p_pptr : NULL"
+ fi
+ fi
+
+ awk 'NR > 1 && $0 { $0 = "\t" $0 }
+ gsub(/\\\t/, "\t") || 1
+ ' <<-EOFPREAMBLE
+ this->proc = $proc;
+ this->uid$P = this->proc ? this->proc->p_ucred->cr_uid : -1;
+ this->gid$P = this->proc ? this->proc->p_ucred->cr_rgid : -1;
+ this->pid$P = this->proc ? this->proc->p_pid : -1;
+ this->jid$P = this->proc ? this->proc->p_ucred->cr_prison->pr_id : -1;
+
+ this->p_args = this->proc ? this->proc->p_args : 0;
+ this->ar_length = this->p_args ? this->p_args->ar_length : 0;
+ this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
+
+ this->args$P = this->arg${P}_$N = this->ar_length > 0 ?
+ \ this->ar_args : stringof(this->proc->p_comm);
+ this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
+ this->ar_args += this->len;
+ this->ar_length -= this->len;
+
+ EOFPREAMBLE
+
+ awk -v P=$P -v MAX_ARGS=$MAX_ARGS '
+ $0 { $0 = "\t" $0 }
+ buf = buf $0 "\n" { }
+ END {
+ while (++N <= MAX_ARGS) {
+ $0 = buf
+ gsub(/P/, P)
+ gsub(/N/, N)
+ gsub(/\\\t/, "\t")
+ sub(/\n$/, "")
+ print
+ }
+ }
+ ' <<-EOFARGS
+ this->argP_N = this->ar_length > 0 ? this->ar_args : "";
+ this->argsP = strjoin(this->argsP,
+ \ strjoin(this->argP_N != "" ? " " : "", this->argP_N));
+ this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
+ this->ar_args += this->len;
+ this->ar_length -= this->len;
+
+ EOFARGS
+
+ N=$(( $MAX_ARGS + 1 ))
+ awk 'sub(/^\\\t/, "\t") || 1, $0 = "\t" $0' <<-EOFPROC
+ this->arg${P}_$N = this->ar_length > 0 ? "..." : "";
+ this->args$P = strjoin(this->args$P,
+ \ strjoin(this->arg${P}_$N != "" ? " " : "", this->arg${P}_$N));
+ EOFPROC
+}
+
+pproc_dump()
+{
+ local OPTIND=1 OPTARG flag
+ local verbose=
+
+ while getopts v flag; do
+ case "$flag" in
+ v) verbose=1 ;;
+ esac
+ done
+ shift $(( $OPTIND - 1 ))
+
+ local P=$1
+ if [ "$verbose" ]; then
+ awk -v P=$P '
+ BEGIN { printf "\t" }
+ NR > 1 && $0 { $0 = "\t" $0 }
+ buf = buf $0 "\n" { }
+ END {
+ $0 = buf
+ if (P < 3) S = sprintf("%" 7-2*(P+1) "s", "")
+ gsub(/S/, S)
+ gsub(/B/, P < 3 ? "\\" : "")
+ gsub(/\\\t/, "\t")
+ sub(/\n$/, "")
+ print
+ }
+ ' <<-EOFPREAMBLE
+ printf(" SB-+= %05d %d.%d %s\n",
+ \ this->pid$P, this->uid$P, this->gid$P, this->args$P);
+ EOFPREAMBLE
+ else
+ cat <<-EOFPREAMBLE
+ printf("%s", this->args$P);
+ EOFPREAMBLE
+ fi
+}
+
+############################################################ MAIN
+
+# If we're running as root, no need for sudo(8)
+[ "$( id -u )" != 0 ] && type sudo > /dev/null 2>&1 && SUDO=sudo
+
+#
+# Process command-line options
+#
+while getopts 1B:deE:fFg:j:k:K:lmnN:o:O:p:PqQr:Rt:T:u:vVwxX:yz: flag; do
+ case "$flag" in
+ 1) ONELINE=1 PSTREE= ;;
+ B) MAX_ARGS="$OPTARG" ;;
+ d) DEBUG=1 ;;
+ e) EXIT_AFTER_COMPILE=1 ;;
+ E) CUSTOM_DETAILS=1
+ EVENT_DETAILS="${EVENT_DETAILS%;}"
+ [ "$EVENT_DETAILS" ] && EVENT_DETAILS="$EVENT_DETAILS;
+ printf(\" \");
+ " # END-QUOTE
+ # Read event code from stdin if `-' is argument
+ [ "$OPTARG" = "-" ] && OPTARG=$( cat )
+ EVENT_DETAILS="$EVENT_DETAILS$OPTARG" ;;
+ f) PROBE_TYPE=function ;;
+ F) PROBE_COALESCE=1 ;;
+ g) GROUP="$OPTARG" ;;
+ j) JID="$OPTARG" ;;
+ k) EXECNAME="$EXECNAME${EXECNAME:+ }$OPTARG"
+ case "$OPTARG" in
+ \**\*) name="${OPTARG%\*}"
+ predicate="strstr(execname, \"${name#\*}\") != NULL" ;;
+ \**) name="${OPTARG#\*}"
+ predicate="strstr(execname, \"$name\") == (execname +"
+ predicate="$predicate strlen(execname) - ${#name})" ;;
+ *\*) predicate="strstr(execname, \"${OPTARG%\*}\") == execname" ;;
+ *) predicate="execname == \"$OPTARG\""
+ esac
+ EVENT_TEST="$predicate${EVENT_TEST:+ ||
+ ($EVENT_TEST)}" ;;
+ K) MAX_DEPTH="$OPTARG" ;;
+ l) LIST=1 ;;
+ m) PROBE_TYPE=module ;;
+ n) PROBE_TYPE=name ;;
+ N) COUNT="$OPTARG" ;;
+ o) OUTPUT="$OPTARG" ;;
+ O) OUTPUT_CMD="$OPTARG" ;;
+ p) PID="$OPTARG" ;;
+ P) PROBE_TYPE=provider ;;
+ q) QUIET=1 ;;
+ Q) LIST_PROFILES=1 ;;
+ r) FILTER="$OPTARG" ;;
+ R) PSTREE=1 ;;
+ t) CUSTOM_TEST="${CUSTOM_TEST:+($CUSTOM_TEST) && }$OPTARG" ;;
+ T) TIMEOUT="$OPTARG" ;;
+ u) USER="$OPTARG" ;;
+ v) VERBOSE=1 ;;
+ V) vers="${VERSION#\$*[:\$]}"
+ vers="${vers% \$}"
+ printf "%s: %s\n" "$pgm" "${vers# }"
+ exit ;;
+ w) DESTRUCTIVE_ACTIONS=1 ;;
+ x) TRACE=1 ;;
+ X) USE_PROFILE=1 PROFILE="$OPTARG" ;;
+ y) CONSOLE=1 CONSOLE_FORCE=1 ;;
+ z) EXECREGEX="$OPTARG" ;;
+ *) usage
+ # NOTREACHED
+ esac
+done
+shift $(( $OPTIND - 1 ))
+
+#
+# List probes if `-l' was given
+#
+[ "$LIST" ] &&
+ list_probes -f "$FILTER" ${QUIET:+-q} -t "$PROBE_TYPE" -- "$@"
+ # NOTREACHED
+
+#
+# List profiles if `-Q' was given
+#
+[ "$LIST_PROFILES" ] &&
+ list_profiles ${ONELINE:+-1} -f "$FILTER" ${QUIET:+-q}
+ # NOTREACHED
+
+#
+# Validate number of arguments
+#
+if [ ! "$PROFILE" ]; then
+ # If not given `-X profile' then a probe argument is required
+ [ $# -gt 0 ] || usage # NOTREACHED
+fi
+
+#
+# Validate `-N count' option argument
+#
+case "$COUNT" in
+"") usage "-N option requires a number argument" ;; # NOTREACHED
+*[!0-9]*) usage "-N argument must be a number" ;; # NOTREACHED
+esac
+
+#
+# Validate `-B num' option argument
+#
+case "$MAX_ARGS" in
+"") usage "-B option requires a number argument" ;; # NOTREACHED
+*[!0-9]*) usage "-B argument must be a number" ;; # NOTREACHED
+esac
+
+#
+# Validate `-K num' option argument
+#
+case "$MAX_DEPTH" in
+"") usage "-K option requires a number argument" ;; # NOTREACHED
+*[!0-9]*) usage "-K argument must be a number" ;; # NOTREACHED
+esac
+
+#
+# Validate `-j jail' option argument
+#
+case "$JID" in
+"") : fall through ;;
+*[!0-9]*) JID=$( jls -j "$JID" jid ) || exit ;;
+esac
+
+#
+# Validate `-u user' option argument
+#
+case "$USER" in
+"") : fall through ;;
+*[![:alnum:]_-]*) RUID="$USER" ;;
+*[!0-9]*) RUID=$( id -u "$USER" 2> /dev/null ) || die "No such user: $USER" ;;
+*) RUID=$USER
+esac
+
+#
+# Validate `-g group' option argument
+#
+case "$GROUP" in
+"") : fall-through ;;
+*[![:alnum:]_-]*) RGID="$GROUP" ;;
+*[!0-9]*)
+ RGID=$( getent group | awk -F: -v group="$GROUP" '
+ $1 == group { print $3; exit found=1 }
+ END { exit !found }
+ ' ) || die "No such group: $GROUP" ;;
+*) RGID=$GROUP
+esac
+
+#
+# Expand probe argument into probe(s)
+#
+case "$1" in
+-*) : Assume dtrace options such as "-c cmd" or "-p pid" ;; # No probe(s) given
+*)
+ PROBE_ARG="$1"
+ shift
+esac
+if [ "$PROBE_ARG" ]; then
+ oldIFS="$IFS"
+ IFS="$IFS,"
+ for arg in $PROBE_ARG; do
+ arg=$( expand_probe -t "$PROBE_TYPE" -- "$arg" )
+ PROBE="$PROBE${PROBE:+, }$arg"
+ done
+ IFS="$oldIFS"
+fi
+
+#
+# Developer switch
+#
+[ "$DEBUG" -a "$EXIT_AFTER_COMPILE" -a "$VERBOSE" ] && DEVELOPER=1 DEBUG=
+
+#
+# Set default event details if `-E code' was not given
+#
+[ "$CUSTOM_DETAILS" ] || EVENT_DETAILS=$( pproc_dump 0 )
+
+#
+# Load profile if given `-X profile'
+#
+[ "$USE_PROFILE" ] && load_profile "$PROFILE"
+[ "$PROBE" ] || die "PROBE not defined by profile and none given as argument"
+
+#
+# Show the user what's being watched
+#
+[ "$DEBUG$EXIT_AFTER_COMPILE" ] || info "Watching '$PROBE' ..."
+
+#
+# Header for watched probe entry
+#
+case "$PROBE" in
+*,*) : fall-through ;;
+*:execve:entry|execve:entry)
+ ACTIONS=$( awk 'gsub(/\\\t/, "\t") || 1' <<-EOF
+ $PROBE /* probe ID $ID */
+ {${TRACE:+
+ \ printf("<$ID>");}
+ \ this->caller_execname = execname;
+ }
+ EOF
+ )
+ PROBE="${PROBE%entry}return"
+ ID=$(( $ID + 1 ))
+ EVENT_TEST="execname != this->caller_execname${EVENT_TEST:+ &&
+ ($EVENT_TEST)}"
+ EVENT_TAG='printf("%d.%d %s[%d]: ",
+ this->uid1, this->gid1, this->caller_execname, this->pid1);'
+ ;;
+esac
+
+#
+# Jail clause/predicate
+#
+if [ "$JID" ]; then
+ prison_id="curthread->td_proc->p_ucred->cr_prison->pr_id"
+ EVENT_TEST="$prison_id == $JID${EVENT_TEST:+ &&
+ ($EVENT_TEST)}"
+fi
+
+#
+# Custom test clause/predicate
+#
+if [ "$CUSTOM_TEST" ]; then
+ case "$EVENT_TEST" in
+ "") EVENT_TEST="$CUSTOM_TEST" ;;
+ *) EVENT_TEST="$EVENT_TEST &&
+ ($CUSTOM_TEST)"
+ esac
+fi
+
+#
+# Make sure dynamic code has trailing semi-colons if non-NULL
+#
+EVENT_TAG="${EVENT_TAG%;}${EVENT_TAG:+;}"
+EVENT_DETAILS="${EVENT_DETAILS%;}${EVENT_DETAILS:+;}"
+
+#
+# DTrace script
+#
+# If `-d' is given, script is sent to stdout for debugging
+# If `-c count", `-g group', `-r regex', or `-u user' is given, run script with
+# dtrace and send output to awk(1) post-processor (making sure to preserve the
+# exit code returned by dtrace invocation). Otherwise, simply run script with
+# dtrace and then exit.
+#
+exec 9<<EOF
+$PROBE /* probe ID 2 */
+{${TRACE:+
+ printf("<2>");
+}
+ /*
+ * Examine process, parent process, and grandparent process details
+ */
+
+ /******************* CURPROC *******************/
+
+ $( pproc -P0 )
+
+ /******************* PPARENT *******************/
+
+ $( if [ "$PSTREE" ]; then pproc -P1; else echo -n \
+ "this->proc = this->proc ? this->proc->p_pptr : NULL;
+ this->pid1 = this->proc ? this->proc->p_pid : -1;
+ this->uid1 = this->proc ? this->proc->p_ucred->cr_uid : -1;
+ this->gid1 = this->proc ? this->proc->p_ucred->cr_rgid : -1;
+ this->jid1 = this->proc ? this->proc->p_ucred->cr_prison->pr_id : -1;"
+ fi )
+
+ /******************* GPARENT *******************/
+
+ $( [ "$PSTREE" ] && pproc -P2 )
+
+ /******************* APARENT *******************/
+
+ $( [ "$PSTREE" ] && pproc -P3 )
+}
+EOF
+PSARGS_ACTION=$( cat <&9 )
+[ "$OUTPUT" -a ! "$CONSOLE_FORCE" ] && CONSOLE=
+{
+ if [ "$DEBUG" ]; then
+ # Send script to stdout
+ cat
+ exit
+ fi
+
+ if [ "$CUSTOM_TEST$EXECNAME$JID$OUTPUT$TIMEOUT$TRACE$VERBOSE" -a \
+ ! "$QUIET" ]
+ then
+ msg=Setting
+ [ "$CUSTOM_TEST" ] && msg="$msg test: $CUSTOM_TEST"
+ [ "$EXECNAME" ] && msg="$msg execname: $EXECNAME"
+ [ "$JID" ] && msg="$msg jid: $JID"
+ [ "$OUTPUT" ] && msg="$msg output: $OUTPUT"
+ [ "$TIMEOUT" ] && msg="$msg timeout: $TIMEOUT"
+ [ "$TRACE" ] && msg="$msg trace: $TRACE"
+ [ "$VERBOSE" ] && msg="$msg verbose: $VERBOSE"
+ info "$msg"
+ fi
+
+ exec 3>&1
+ console_stdout=3
+
+ #
+ # Developer debugging aide
+ #
+ if [ "$DEVELOPER" ]; then
+ #
+ # Run, capture the error line, and focus it
+ #
+ # Example error text to capture line number from:
+ # dtrace: failed to compile script /dev/stdin: line 669: ...
+ #
+ errline=
+ stdin_buf=$( cat )
+ stderr_buf=$( echo "$stdin_buf" |
+ dtrace_cmd -t -es /dev/stdin "$@" 2>&1 > /dev/null )
+ status=$?
+ if [ "$stderr_buf" ]; then
+ errline=$( echo "$stderr_buf" | awk '
+ BEGIN {
+ ti = "\033[31m"
+ te = "\033[39m"
+ }
+ { line = $0 }
+ sub(/.*: line /, "") && sub(/:.*/, "") {
+ print # to errline
+ sub("line " $0, ti "&" te, line)
+ }
+ { print line > "/dev/stderr" }
+ ' 2>&3 )
+ fi
+ if [ "$errline" ]; then
+ echo "$stdin_buf" | awk -v line="${errline%%[^0-9]*}" '
+ BEGIN {
+ start = line < 10 ? 1 : line - 10
+ end = line + 10
+ slen = length(sprintf("%u", start))
+ elen = length(sprintf("%u", end))
+ N = elen > slen ? elen : slen
+ for (i = start; i <= end; i++) {
+ ti[i] = "\033[2m"
+ te[i] = "\033[22m"
+ }
+ ti[line] = "\033[31m"
+ te[line] = "\033[39m"
+ fmt = "%s%*u %s%s\n"
+ }
+ NR < start { next }
+ NR == start, NR == end {
+ printf(fmt, ti[NR], N, NR, $0, te[NR])
+ }
+ NR > end { exit }
+ ' # END-QUOTE
+ fi
+ exit $status
+ fi
+
+ if [ $COUNT -eq 0 -a ! "$EXECREGEX$FILTER$GROUP$OUTPUT_CMD$PID$USER" ]
+ then
+ case "$OUTPUT" in
+ -) output_path=/dev/stdout ;;
+ *) output_path="$OUTPUT"
+ esac
+
+ # Run script without pipe to awk post-processor
+ dtrace_cmd -t \
+ ${DESTRUCTIVE_ACTIONS:+-w} \
+ ${EXIT_AFTER_COMPILE:+-e} \
+ ${OUTPUT:+-o "$output_path"} \
+ -s /dev/stdin \
+ "$@"
+ exit
+ fi
+
+ # Prevent backslashes from being lost
+ FILTER=$( echo "$FILTER" | awk 'gsub(/\\/,"&&")||1' )
+ EXECREGEX=$( echo "$EXECREGEX" | awk 'gsub(/\\/,"&&")||1' )
+
+ if [ ! "$QUIET" ]; then
+ msg=Filtering
+ [ "$EXECREGEX" ] && msg="$msg execregex: $EXECREGEX"
+ [ "$FILTER" ] && msg="$msg filter: $FILTER"
+ [ "$GROUP" ] && msg="$msg group: $GROUP"
+ [ "$OUTPUT_CMD" ] && msg="$msg cmd: $OUTPUT_CMD"
+ [ "$PID" ] && msg="$msg pid: $PID"
+ [ "$USER" ] && msg="$msg user: $USER"
+ [ $COUNT -gt 0 ] && msg="$msg count: $COUNT"
+ info "$msg"
+ fi
+
+ #
+ # Send script output to post-processor for filtering
+ #
+ status=$(
+ exec 4>&1
+ to_status=4
+ ( exec 5>&1; to_dtrace_stderr_filter=5; (
+ trap 'echo $? >&$to_status' EXIT
+ eval $SUDO ${TIMEOUT:+timeout \"\$TIMEOUT\"} dtrace \
+ ${EXIT_AFTER_COMPILE:+-e} \
+ ${DESTRUCTIVE_ACTIONS:+-w} \
+ -s /dev/stdin \
+ \"\$@\" \
+ 2>&$to_dtrace_stderr_filter \
+ ${QUIET:+2> /dev/null}
+ ) | $SUDO awk \
+ -v cmd="$OUTPUT_CMD" \
+ -v console="$CONSOLE" \
+ -v count=$COUNT \
+ -v execregex="$EXECREGEX" \
+ -v filter="$FILTER" \
+ -v gid="$RGID" \
+ -v output="$OUTPUT" \
+ -v pid="$PID" \
+ -v pstree=$PSTREE \
+ -v quiet=$QUIET \
+ -v tty=$( ps -o tty= -p $$ ) \
+ -v uid="$RUID" \
+ ' # Start awk(1) post-processor
+ ############################################ BEGIN
+ BEGIN {
+ true = 1
+ ansi = "(\\033\\[[[:digit:];]+m)?"
+ num = year = day = "[[:digit:]]+"
+ month = "[[:alpha:]]+"
+ date = year " " month " +" day
+ time = "[012][0-9]:[0-5][0-9]:[0-5][0-9]"
+ date_time = ansi date " +" time ansi
+ name1 = "[^\\[]*"
+ name2 = "[^\\n]*"
+ if (output == "-")
+ output = "/dev/stdout"
+
+ #
+ # Field definitions
+ #
+ nexecmatches = 2
+ execstart[1] = sprintf( \
+ "^(%s) (%s)\\.(%s) (%s)\\[(%s)\\]: ",
+ date_time, num, num, name1, num)
+ execstart[2] = sprintf( \
+ "\\n +\\\\?-\\+= (%s) (%s)\\.(%s) ",
+ num, num, num)
+ npidmatches = 2
+ pidstart[1] = sprintf("^(%s) (%s)\\.(%s) (%s)\\[",
+ date_time, num, num, name1)
+ pidstart[2] = "\\n +\\\\?-\\+= "
+ pidpreen[2] = "^0*"
+ piddeflt[2] = "0"
+ ngidmatches = 2
+ gidstart[1] = sprintf("^(%s) (%s)\\.", date_time, num)
+ gidstart[2] = sprintf("\\n +\\\\?-\\+= (%s) (%s)\\.",
+ ansi num ansi, num)
+ nuidmatches = 2
+ uidstart[1] = sprintf("^(%s) ", date_time)
+ uidstart[2] = sprintf("\\n +\\\\?-\\+= (%s) ",
+ ansi num ansi)
+ }
+ ############################################ FUNCTIONS
+ function strip(s) { gsub(/\033\[[0-9;]*m/, "", s); return s }
+ function esc(str) { gsub(/'\''/, "&\\\\&&", str); return str }
+ function arg(str) { return "'\''" esc(str) "'\''" }
+ function env(var, str) { return var "=" arg(str) " " }
+ function ans(seq) { return console ? "\033[" seq "m" : "" }
+ function runcmd() {
+ return system(sprintf("%s/bin/sh -c %s",
+ env("TAG", strip(tag)) \
+ env("DETAILS", strip(details)),
+ arg(cmd)))
+ }
+ function filter_block() {
+ if (length(lines) < 1) return 0
+ block_match = 0
+ newstr = ""
+ start = 1
+ if (match(lines, "^(" date_time ") ")) {
+ newstr = newstr substr(lines, 1,
+ RSTART + RLENGTH - 1)
+ start = RSTART + RLENGTH
+ }
+ replace = ans("31;1") "&" ans("39;22")
+ workstr = substr(lines, start)
+ if (gsub(filter, replace, workstr)) block_match = 1
+ lines = newstr workstr
+ return block_match
+ }
+ function filter_field(startre, fieldre, matchre, isword,
+ preenre, defaultstr)
+ {
+ if (length(lines) < 1) return 0
+ field_match = 0
+ newstr = ""
+ start = 1
+ while ((workstr = substr(lines, start)) &&
+ (workstr ~ (startre fieldre)))
+ {
+ match(workstr, startre)
+ start += end = RSTART + RLENGTH - 1
+ newstr = newstr substr(workstr, 1, end)
+ workstr = substr(workstr, end + 1)
+ match(workstr, fieldre)
+ start += end = RSTART + RLENGTH - 1
+ field = matchstr = substr(workstr, 1, end)
+ sub(preenre, "", matchstr)
+ if (!matchstr) matchstr = defaultstr
+ if (isword) {
+ if (match(matchstr, matchre) &&
+ RSTART == 1 &&
+ RLENGTH == length(matchstr)) {
+ field_match = 1
+ field = ans(7) field ans(27)
+ }
+ } else {
+ replace = ans(7) "&" ans(27)
+ if (gsub(matchre, replace, matchstr)) {
+ field_match = 1
+ field = matchstr
+ }
+ }
+ newstr = newstr field
+ }
+ lines = newstr workstr
+ return field_match
+ }
+ function dump() {
+ lines = block
+ block = ""
+ found = 0
+ if (execregex != "") {
+ for (n = 1; n <= nexecmatches; n++)
+ if (filter_field(execstart[n], name2,
+ execregex)) found = 1
+ if (!found) return
+ }
+ if (pid != "") {
+ for (n = 1; n <= npidmatches; n++)
+ if (filter_field(pidstart[n], num, pid,
+ true, pidpreen[n],
+ piddeflt[n])) found = 1
+ if (!found) return
+ }
+ if (gid != "") {
+ for (n = 1; n <= ngidmatches; n++)
+ if (filter_field(gidstart[n], num,
+ gid, true)) found = 1
+ if (!found) return
+ }
+ if (uid != "") {
+ for (n = 1; n <= nuidmatches; n++)
+ if (filter_field(uidstart[n], num,
+ uid, true)) found = 1
+ if (!found) return
+ }
+ if (filter != "" && !filter_block()) return
+ if (lines) {
+ stdout = 1
+ if (output) {
+ stdout = 0
+ if (!console) lines = strip(lines)
+ print lines > output
+ } else if (cmd) {
+ if (!quiet) print lines
+ tag = details = lines
+ sub(/: .*/, "", tag)
+ sub(/.*: /, "", details)
+ if (!console) tag = strip(tag)
+ runcmd()
+ } else print lines
+ }
+ fflush()
+ ++matches
+ }
+ ############################################ MAIN
+ { block = (block ? block "\n" : block) $0 }
+ !pstree { dump() }
+ $0 ~ sprintf("^%6s\\\\-\\+= %s ", "", num) { dump() }
+ count && matches >= count { exit }
+ ############################################ END
+ END {
+ dump()
+ system(sprintf("pkill -t %s dtrace %s", tty,
+ quiet ? "2> /dev/null" : ""))
+ }
+ ' >&$console_stdout ) | dtrace_stderr_filter >&2
+ ) # status
+ exit $status
+
+} <<EOF
+#!/usr/sbin/dtrace -s
+/* -
+ * Copyright (c) 2014-2018 Devin Teske <dteske@FreeBSD.org>
+ * All rights reserved.
+ * 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.
+ *
+ * $TITLE dtrace(1) script to log process(es) triggering $PROBE $
+ * \$FreeBSD$
+ */
+
+$( echo "$DTRACE_PRAGMA" | awk '
+ !/^[[:space:]]*(#|$)/, sub(/^[[:space:]]*/, "#pragma D ")||1
+' )
+
+int console;
+
+dtrace:::BEGIN { console = ${CONSOLE:-0} } /* probe ID 1 */
+
+/*********************************************************/
+
+${PSARGS:+$PSARGS_ACTION}
+${ACTIONS:+
+/*********************************************************/
+
+$ACTIONS
+}
+/*********************************************************/
+
+$PROBE${EVENT_TEST:+ /$EVENT_TEST/} /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /***********************************************/
+
+ printf("%s%Y%s ",
+ console ? "\033[32m" : "",
+ walltimestamp,
+ console ? "\033[39m" : "");
+
+ /****************** EVENT_TAG ******************/
+
+ ${EVENT_TAG#[[:space:]]}
+${PROBE_COALESCE:+
+ /**************** PROBE_COALESCE ***************/
+
+ printf("%s%s:%s:%s:%s ", probename == "entry" ? "-> " :
+ probename == "return" ? "<- " :
+ probename == "start" ? "-> " :
+ probename == "done" ? "<- " : " | ",
+ probeprov, probemod, probefunc, probename);
+}
+ /**************** EVENT_DETAILS ****************/
+
+ ${EVENT_DETAILS#[[:space:]]}
+
+ /***********************************************/
+
+ printf("\\n");
+${PSTREE:+
+ /*
+ * Print process, parent, grandparent, and ancestor details
+ */
+$( pproc_dump -v 3
+ pproc_dump -v 2
+ pproc_dump -v 1
+ pproc_dump -v 0
+)}
+}
+EOF
+# NOTREACHED
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/dwatch.1
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/dwatch.1
+++ stable/11/cddl/usr.sbin/dwatch/dwatch.1
@@ -0,0 +1,766 @@
+.\" Copyright (c) 2014-2018 Devin Teske
+.\" All rights reserved.
+.\"
+.\" 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 ``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 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 9, 2018
+.Dt DWATCH 1
+.Os
+.Sh NAME
+.Nm dwatch
+.Nd watch processes as they trigger a particular DTrace probe
+.Sh SYNOPSIS
+.Nm
+.Op Fl 1defFmnPqRvVwxy
+.Op Fl B Ar num
+.Op Fl E Ar code
+.Op Fl g Ar group
+.Op Fl j Ar jail
+.Op Fl k Ar name
+.Op Fl K Ar num
+.Op Fl N Ar count
+.Op Fl o Ar file
+.Op Fl O Ar cmd
+.Op Fl p Ar pid
+.Op Fl r Ar regex
+.Op Fl t Ar test
+.Op Fl T Ar time
+.Op Fl u Ar user
+.Op Fl X Ar profile
+.Op Fl z Ar regex
+.Op Fl -
+.Op probe[,...]
+.Op args ...
+.Nm
+.Fl l
+.Op Fl fmnPqy
+.Op Fl r Ar regex
+.Op probe ...
+.Nm
+.Fl Q
+.Op Fl 1qy
+.Op Fl r Ar regex
+.Sh DESCRIPTION
+The
+.Nm
+utility uses
+.Xr dtrace 1
+to display process info when a given DTrace probe point is triggered.
+Only the root user or users with
+.Xr sudo 8
+access can run this command.
+.Pp
+.Nm
+automates the process of generating DTrace scripts to coalesce trace output by
+date/time,
+process info,
+and
+.Op optionally
+probe-specific data.
+.Pp
+Output format without options is:
+.Pp
+.Dl date/time uid.gid execname[pid]: psargs
+.Pp
+For example,
+the command
+.Ql dwatch BEGIN
+produces:
+.Pp
+.Dl INFO Watching 'dtrace:::BEGIN' ...
+.Dl 2017 May 29 08:23:20 0.0 dtrace[60671]: dtrace -s /dev/stdin
+.Pp
+The
+.Fl F
+option causes
+.Nm
+to instead coalesce trace output by date/time,
+process info,
+and probe traversal.
+.Pp
+Output format with the
+.Ql Fl F
+option is:
+.Pp
+.Dl date/time uid.gid execname[pid]: {->,<-, |} prov:mod:func:name ...
+.Pp
+For example,
+the command
+.Ql dwatch -F BEGIN
+produces:
+.Pp
+.Dl INFO Watching 'dtrace:::BEGIN' ...
+.Dl 2017 May 29 21:34:41 0.0 dtrace[86593]: | dtrace:::BEGIN ...
+.Pp
+The
+.Fl R
+option causes
+.Nm
+to display a process tree containing the parent,
+grandparent,
+and ancestor process info.
+.Pp
+Output format with the
+.Ql Fl R
+option is:
+.Pp
+.Dl date/time uid0.gid0 execname[pid0]: psargs0
+.Dl " -+= pid3 uid3.gid3 psargs3"
+.Dl " \e\\-+= pid2 uid2.gid2 psargs2"
+.Dl " \e\\-+= pid1 uid1.gid1 psargs1"
+.Dl " \e\\-+= pid0 uid0.guid0 psargs0"
+.Pp
+For example,
+the command
+.Ql dwatch -R BEGIN
+produces:
+.Pp
+.Dl INFO Watching 'dtrace:::BEGIN' ...
+.Dl 2017 May 29 21:38:54 0.0 dtrace[86899]: dtrace -s /dev/stdin
+.Dl " -+= 86855 604.604 -bash"
+.Dl " \e\\-+= 86857 604.604 /bin/sh /usr/sbin/dwatch -R BEGIN"
+.Dl " \e\\-+= 86897 0.0 sudo dtrace -s /dev/stdin"
+.Dl " \e\\-+= 86899 0.0 dtrace -s /dev/stdin"
+.Pp
+Of particular interest is the ability to filter using regular expressions.
+The
+.Ql Fl g Ar group ,
+.Ql Fl p Ar pid ,
+.Ql Fl r Ar regex ,
+.Ql Fl u Ar user ,
+and
+.Ql Fl z Ar regex
+options can be combined with
+.Ql Fl R
+to match on parent process criteria as well as current process info.
+.Pp
+In contrast,
+the
+.Ql Fl j Ar jail ,
+and
+.Ql Fl k Ar name
+options apply only to the current process even if
+.Ql Fl R
+is given.
+.Pp
+The
+.Ql Fl E Ar code
+option gives the ability to customize probe-specific data.
+For example,
+the command:
+.Pp
+.Dl dwatch -E 'printf("%s", copyinstr(arg0))' chdir
+.Pp
+displays the path argument sent to
+.Xr chdir 2
+calls.
+.Pp
+Profiles can be written for more complex routines and/or convenience.
+To list available profiles use the
+.Ql Fl Q
+option.
+Use the
+.Ql Fl X Ar profile
+option to use a particular profile.
+.Pp
+For example,
+the command
+.Ql dwatch -X kill
+displays arguments sent to
+.Xr kill 2 .
+.Sh OPTIONS
+If a
+.Ar probe
+argument does not contain colon
+.Pq Qo Li ":" Qc
+and none of
+.Ql Fl P ,
+.Ql Fl m ,
+.Ql Fl f ,
+or
+.Ql Fl n
+are given,
+the probe argument is intelligently mapped to its most-likely value.
+Use
+.Ql Nm Fl l Ar name
+to see what probes will match a given name.
+.Pp
+Multiple probes must be given as a single
+.Pq quoted
+argument,
+separated by comma and/or whitespace.
+Any/all arguments following said probes will be passed to
+.Xr dtrace 1
+unmodified.
+.Bl -tag -width "-c count"
+.It Fl 1
+Print one line per process/profile
+.Pq Default; disables Ql Fl R .
+.It Fl B Ar num
+Maximum number of arguments to display
+.Pq Default 64 .
+.It Fl d
+Debug.
+Send
+.Xr dtrace 1
+script to stdout instead of executing.
+.It Fl e
+Exit after compiling request but prior to enabling probes.
+.It Fl E Ar code
+DTrace
+.Ar code
+for event details.
+If `-',
+read from stdin.
+This allows customization of what is printed after date/time and process info.
+By default,
+the name and arguments of the program triggering the probe are shown.
+Can be specified multiple times.
+.It Fl f
+Enable probes matching the specified function names.
+.It Fl F
+Coalesce trace output by probe.
+.It Fl g Ar group
+Group filter.
+Only show processes matching
+.Ar group
+name/gid.
+This can be an
+.Xr awk 1
+regular expression to match a numerical gid.
+.It Fl j Ar jail
+Jail filter.
+Only show processes matching
+.Ar jail
+name/jid.
+.It Fl k Ar name
+Only show processes matching
+.Ar name .
+Can also be of the format
+.Ql Li name*
+to indicate
+.Dq Li begins with ,
+.Ql Li *name
+to indicate
+.Dq Li ends with ,
+or
+.Ql Li *name*
+to indicate
+.Dq Li contains .
+Can be specified multiple times.
+.It Fl K Ar num
+Maximum directory depth to display
+.Pq Default 64 .
+.It Fl l
+List available probes on standard output and exit.
+.It Fl m
+Enable probes matching the specified module names.
+.It Fl X Ar profile
+Load profile from DWATCH_PROFILES_PATH.
+.It Fl n
+Enable probes matching the specified probe names.
+.It Fl N Ar count
+Exit after
+.Ar count
+matching entries
+.Pq Default 0 for disabled .
+.It Fl o Ar file
+Set output file.
+If
+.Ql Li - ,
+the path
+.Ql Li /dev/stdout
+is used.
+.It Fl O Ar cmd
+Execute
+.Ar cmd
+for each event.
+This can be any valid
+.Xr sh 1
+command.
+The environment variables
+.Ql Li $TAG
+and
+.Ql Li $DETAILS
+are set for the given
+.Ar cmd .
+.It Fl p Ar pid
+Process id filter.
+Only show processes with matching
+.Ar pid .
+This can be an
+.Xr awk 1
+regular expression.
+.It Fl P
+Enable probe matching the specified provider name.
+.It Fl q
+Quiet.
+Hide informational messages and all dtrace(1) errors.
+.It Fl Q
+List available profiles in DWATCH_PROFILES_PATH and exit.
+.It Fl r Ar regex
+Filter.
+Only show blocks matching
+.Xr awk 1
+regular expression.
+.It Fl R
+Show parent,
+grandparent,
+and ancestor of process.
+.It Fl t Ar test
+Test clause
+.Pq predicate
+to limit events
+.Pq Default none .
+Can be specified multiple times.
+.It Fl T Ar time
+Timeout.
+The format is
+.Ql Li #[smhd]
+or just
+.Ql Li #
+for seconds.
+.It Fl u Ar user
+User filter.
+Only show processes matching
+.Ar user
+name/uid.
+This can be an
+.Xr awk 1
+regular expression to match a numerical UID.
+.It Fl v
+Verbose.
+Show all errors from
+.Xr dtrace 1 .
+.It Fl V
+Report
+.Nm
+version on standard output and exit.
+.It Fl w
+Permit destructive actions
+.Pq copyout*, stop, panic, etc. .
+.It Fl x
+Trace.
+Print
+.Ql Li <probe-id>
+when a probe is triggered.
+.It Fl y
+Always treat stdout as console
+.Pq enable colors/columns/etc. .
+.It Fl z Ar regex
+Only show processes matching
+.Xr awk 1
+regular expression.
+.El
+.Sh PROFILES
+Profiles customize the data printed during events.
+Profiles are loaded from a colon-separated list of directories in
+.Ev DWATCH_PROFILES_PATH .
+This is an incomplete list of profiles with basic descriptions:
+.Bl -tag -width "vop_readdir"
+.It chmod
+Print mode and path from
+.Xr chmod 2 ,
+.Xr lchmod 2 ,
+.Xr fchmodat 2
+.It errno
+Print non-zero errno results from system calls
+.It io
+Print disk I/O details provided by
+.Xr dtrace_io 4
+.It ip
+Print IPv4 and IPv6 details provided by
+.Xr dtrace_ip 4
+.It kill
+Print signal and pid from
+.Xr kill 2
+.It nanosleep
+Print requested time from
+.Xr nanosleep 2
+.It open
+Print path from
+.Xr open 2 ,
+.Xr openat 2
+.It proc
+Print process execution details provided by
+.Xr dtrace_proc 4
+.It proc-signal
+Print process signal details provided by
+.Xr dtrace_proc 4
+.It rw
+Print buffer contents from
+.Xr read 2 ,
+.Xr write 2
+.It sched
+Print CPU scheduling details provided by
+.Xr dtrace_sched 4
+.It tcp
+Print TCP address/port details provided by
+.Xr dtrace_tcp 4
+.It tcp-io
+Print TCP I/O details provided by
+.Xr dtrace_tcp 4
+.It udp
+Print UDP I/O details provided by
+.Xr dtrace_udp 4
+.It vop_create
+Print filesystem paths being created by
+.Xr VOP_CREATE 9
+.It vop_lookup
+Print filesystem paths being looked-up by
+.Xr VOP_LOOKUP 9
+.It vop_mkdir
+Print directory paths being created by
+.Xr VOP_MKDIR 9
+.It vop_mknod
+Print device node paths being created by
+.Xr VOP_MKNOD 9
+.It vop_readdir
+Print directory paths being read by
+.Xr VOP_READDIR 9
+.It vop_remove
+Print filesystem paths being removed by
+.Xr VOP_REMOVE 9
+.It vop_rename
+Print filesystem paths being renamed by
+.Xr VOP_RENAME 9
+.It vop_rmdir
+Print directory paths being removed by
+.Xr VOP_RMDIR 9
+.It vop_symlink
+Print symlink paths being created by
+.Xr VOP_SYMLINK 9
+.El
+.Sh ENVIRONMENT
+These environment variables affect the execution of
+.Nm :
+.Bl -tag -width "DWATCH_PROFILES_PATH"
+.It Ev DWATCH_PROFILES_PATH
+If
+.Ev DWATCH_PROFILES_PATH
+is set,
+.Nm
+searches for profiles in the colon-separated list of directories in that
+variable instead of the default
+.Ql Li /usr/libexec/dwatch:/usr/local/libexec/dwatch .
+If set to NULL,
+profiles are not loaded.
+.El
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+Watch processes entering system CPU scheduler.
+.Bd -literal -offset indent
+dwatch on-cpu
+.Ed
+.Pp
+List available profiles,
+one line per profile.
+.Bd -literal -offset indent
+dwatch -1 -Q
+.Ed
+.Pp
+Do not execute
+.Xr dtrace 1
+but display script on stdout and exit.
+.Bd -literal -offset indent
+dwatch -d fsync
+.Ed
+.Pp
+Compile and test but do not execute code generated with given probe.
+.Bd -literal -offset indent
+dwatch -e test_probe
+.Ed
+.Pp
+Print argument one being passed to each call of zfs_sync().
+.Bd -literal -offset indent
+dwatch -E 'printf("%i", arg1)' zfs_sync
+.Ed
+.Pp
+Watch all functions named
+.Ql Li read .
+.Bd -literal -offset indent
+dwatch -f read
+.Ed
+.Pp
+Watch all probe traversal.
+.Bd -literal -offset indent
+dwatch -F :
+.Ed
+.Pp
+Watch syscall probe traversal.
+.Bd -literal -offset indent
+dwatch -F syscall
+.Ed
+.Pp
+Display only processes belonging to wheel super-group.
+.Bd -literal -offset indent
+dwatch -g wheel execve
+.Ed
+.Pp
+Display only processes belonging to groups
+.Ql Li daemon
+or
+.Ql Li nobody .
+.Bd -literal -offset indent
+dwatch -g '1|65534' execve
+.Ed
+.Pp
+Ignore jails,
+displaying only base system processes.
+.Bd -literal -offset indent
+dwatch -j 0 execve
+.Ed
+.Pp
+Display only processes running inside the jail named
+.Ql Li myjail .
+.Bd -literal -offset indent
+dwatch -j myjail execve
+.Ed
+.Pp
+Watch syscall traversal by ruby processes.
+.Bd -literal -offset indent
+dwatch -k 'ruby*' -F syscall
+.Ed
+.Pp
+Watch syscall traversal by processes containing
+.Ql Li daemon
+in their name.
+.Bd -literal -offset indent
+dwatch -k '*daemon*' -F syscall
+.Ed
+.Pp
+Watch signals being passed to
+.Xr kill 2 .
+.Bd -literal -offset indent
+dwatch -X kill
+.Ed
+.Pp
+Watch signals being passed between
+.Xr bash 1
+and
+.Xr vi 1 .
+.Bd -literal -offset indent
+dwatch -k bash -k vi -X kill
+.Ed
+.Pp
+Display a list of unique functions available.
+.Bd -literal -offset indent
+dwatch -l -f
+.Ed
+.Pp
+List available probes for functions ending in
+.Ql Li read .
+.Bd -literal -offset indent
+dwatch -l -f '*read'
+.Ed
+.Pp
+List available probes ending in
+.Dq Li read .
+.Bd -literal -offset indent
+dwatch -l -r 'read$'
+.Ed
+.Pp
+Display a list of unique providers.
+.Bd -literal -offset indent
+dwatch -l -P
+.Ed
+.Pp
+Watch paths being removed by
+.Xr VOP_REMOVE 9 .
+.Bd -literal -offset indent
+dwatch -X vop_remove
+.Ed
+.Pp
+Watch the name
+.Ql Li read
+instead of the function
+.Ql Li read .
+The
+.Nm
+selection algorithm will commonly favor the function named
+.Ql Li read
+when not given a type
+.Pq using So Fl P Sc , So Fl m Sc , So Fl f Sc , or So Fl n Sc
+because there are more probes matching the function named
+.Ql Li read
+than probes matching
+.Ql Li read
+for any other type.
+.Bd -literal -offset indent
+dwatch -n read
+.Ed
+.Pp
+Display the first process to call
+.Xr kill 2
+and then exit.
+.Bd -literal -offset indent
+dwatch -N 1 kill
+.Ed
+.Pp
+Watch processes forked by pid 1234.
+.Bd -literal -offset indent
+dwatch -p 1234 execve
+.Ed
+.Pp
+Watch processes forked by either pid 1234 or pid 5678.
+.Bd -literal -offset indent
+dwatch -p '1234|5678' execve
+.Ed
+.Pp
+Watch the provider
+.Ql Li random
+instead of the function
+.Ql Li random .
+The
+.Nm
+selection algorithm will commonly favor the function named
+.Ql Li random
+when not given a type
+.Pq using So Fl P Sc , So Fl m Sc , So Fl f Sc , or So Fl n Sc
+because there are more probes matching the function named
+.Ql Li random
+than probes matching the provider named
+.Ql Li random .
+.Bd -literal -offset indent
+dwatch -P random
+.Ed
+.Pp
+Display available profiles matching
+.Ql Li vop .
+.Bd -literal -offset indent
+dwatch -Q -r vop
+.Ed
+.Pp
+Watch
+.Xr VOP_LOOKUP 9
+paths containing
+.Ql Li /lib/ .
+.Bd -literal -offset indent
+dwatch -r /lib/ -X vop_lookup
+.Ed
+.Pp
+Show process tree for each command as it is executed.
+.Bd -literal -offset indent
+dwatch -R execve
+.Ed
+.Pp
+Watch processes forked by pid 1234 or children thereof.
+.Bd -literal -offset indent
+dwatch -R -p 1234 execve
+.Ed
+.Pp
+Display processes calling
+.Xr write 2
+with
+.Dq nbytes
+less than 10.
+.Bd -literal -offset indent
+dwatch -t 'arg2<10' -E 'printf("%d",arg2)' write
+.Ed
+.Pp
+Display
+.Xr write 2
+buffer when
+.Dq execname
+is not
+.Ql Li dtrace
+and
+.Dq nbytes
+is less than 10.
+.Bd -literal -offset indent
+dwatch -X write -t 'execname != "dtrace" && this->nbytes < 10'
+.Ed
+.Pp
+Watch
+.Ql Li statfs
+for 5 minutes and exit.
+.Bd -literal -offset indent
+dwatch -T 5m statfs
+.Ed
+.Pp
+Display only processes belonging to the root super-user.
+.Bd -literal -offset indent
+dwatch -u root execve
+.Ed
+.Pp
+Display only processes belonging to users
+.Ql Li daemon
+or
+.Ql Li nobody .
+.Bd -literal -offset indent
+dwatch -u '1|65534' execve
+.Ed
+.Pp
+Print version and exit.
+.Bd -literal -offset indent
+dwatch -V
+.Ed
+.Pp
+View the first 100 scheduler preemptions.
+.Bd -literal -offset indent
+dwatch -y -N 100 preempt | less -R
+.Ed
+.Pp
+Display processes matching either
+.Dq Li mkdir
+or
+.Dq Li rmdir .
+.Bd -literal -offset indent
+dwatch -z '(mk|rm)dir' execve
+.Ed
+.Pp
+Run a command and watch network activity only while that command runs.
+.Bd -literal -offset indent
+dwatch -X tcp -- -c "nc -zvw10 google.com 22"
+.Ed
+.Pp
+Watch
+.Xr open 2
+and
+.Xr openat 2
+calls only while pid 1234 is active.
+.Bd -literal -offset indent
+dwatch -X open -- -p 1234
+.Ed
+.Pp
+Watch probe traversal for a given command.
+Note that
+.Dq Li -c true
+is passed to
+.Xr dtrace 1
+since it appears after the
+.Nm
+probe argument.
+.Bd -literal -offset indent
+dwatch -F 'pid$target:::entry' -c true
+.Ed
+.Sh SEE ALSO
+.Xr dtrace 1
+.Sh HISTORY
+.Nm
+first appeared in
+.Fx 12.0-CURRENT .
+.Sh AUTHORS
+.An Devin Teske Aq Mt dteske@FreeBSD.org
Index: stable/11/cddl/usr.sbin/dwatch/examples/Makefile
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/examples/Makefile
+++ stable/11/cddl/usr.sbin/dwatch/examples/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+FILESDIR= ${SHAREDIR}/examples/dwatch
+FILES= profile_template
+
+.include <bsd.prog.mk>
Index: stable/11/cddl/usr.sbin/dwatch/examples/profile_template
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/examples/profile_template
+++ stable/11/cddl/usr.sbin/dwatch/examples/profile_template
@@ -0,0 +1,74 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) profile for XXX entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# XXX
+#
+############################################################ PRAGMAS
+
+# Optional: You can override the default pragmas (shown below)
+
+#DTRACE_PRAGMA="
+# option quiet
+# option dynvarsize=16m
+# switchrate=10hz
+#" # END-QUOTE
+
+############################################################ PROBE
+
+# Optional: dwatch(8) initializes this to the expanded probe arguments
+
+#: ${PROBE:="XXX"}
+
+############################################################ ACTIONS
+
+# Optional actions to be performed before hitting the final print action
+
+#exec 9<<EOF
+#EOF
+#ACTIONS=$( cat <&9 )
+#ID=
+
+############################################################ EVENT ACTION
+
+# The default EVENT value is simply `entry'. This is paired with $PROBE.
+
+#EVENT=
+
+# Optional predicate which must be true before the event action will run
+
+#EVENT_TEST=
+
+############################################################ EVENT TAG
+
+# The EVENT_TAG is run inside the print action after the timestamp has been
+# printed. By default, `UID.GID CMD[PID]: ' of the process is printed.
+
+#exec 9<<EOF
+#EOF
+#EVENT_TAG=$( cat <&9 )
+
+############################################################ EVENT DETAILS
+
+# The DETAILS are run after the EVENT_TAG and by default, the program name and
+# arguments of the process hitting the EVENT action are shown. This can be
+# customized to call-specific information because the `-v' flag of dwatch(8)
+# can provide detailed process information for the EVENT action on lines below
+# the DETAILS.
+#
+# NB: Should produce a single-line and not print a trailing newline.
+
+#exec 9<<EOF
+# printf("XXX");
+#EOF
+#DETAILS=$( cat <&9 )
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/Makefile
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/Makefile
+++ stable/11/cddl/usr.sbin/dwatch/libexec/Makefile
@@ -0,0 +1,87 @@
+# $FreeBSD$
+
+FILESDIR= ${LIBEXECDIR}/dwatch
+FILES= chmod \
+ errno \
+ io \
+ ip \
+ kill \
+ nanosleep \
+ open \
+ proc \
+ rw \
+ sched \
+ sendrecv \
+ tcp \
+ udp \
+ vop_create \
+ vop_readdir \
+ vop_rename \
+ vop_symlink
+
+LINKS= ${LIBEXECDIR}/dwatch/chmod ${LIBEXECDIR}/dwatch/fchmodat
+LINKS+= ${LIBEXECDIR}/dwatch/chmod ${LIBEXECDIR}/dwatch/lchmod
+LINKS+= ${LIBEXECDIR}/dwatch/io ${LIBEXECDIR}/dwatch/io-done
+LINKS+= ${LIBEXECDIR}/dwatch/io ${LIBEXECDIR}/dwatch/io-start
+LINKS+= ${LIBEXECDIR}/dwatch/ip ${LIBEXECDIR}/dwatch/ip-receive
+LINKS+= ${LIBEXECDIR}/dwatch/ip ${LIBEXECDIR}/dwatch/ip-send
+LINKS+= ${LIBEXECDIR}/dwatch/open ${LIBEXECDIR}/dwatch/openat
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-create
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exec
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exec-failure
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exec-success
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-exit
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal-clear
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal-discard
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-signal-send
+LINKS+= ${LIBEXECDIR}/dwatch/proc ${LIBEXECDIR}/dwatch/proc-status
+LINKS+= ${LIBEXECDIR}/dwatch/rw ${LIBEXECDIR}/dwatch/read
+LINKS+= ${LIBEXECDIR}/dwatch/rw ${LIBEXECDIR}/dwatch/write
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-change-pri
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-cpu
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-dequeue
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-enqueue
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-exec
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-lend-pri
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-load-change
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-off-cpu
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-on-cpu
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-preempt
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-pri
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-queue
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-remain-cpu
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-sleep
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-surrender
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-tick
+LINKS+= ${LIBEXECDIR}/dwatch/sched ${LIBEXECDIR}/dwatch/sched-wakeup
+LINKS+= ${LIBEXECDIR}/dwatch/sendrecv ${LIBEXECDIR}/dwatch/recv
+LINKS+= ${LIBEXECDIR}/dwatch/sendrecv ${LIBEXECDIR}/dwatch/recvfrom
+LINKS+= ${LIBEXECDIR}/dwatch/sendrecv ${LIBEXECDIR}/dwatch/recvmsg
+LINKS+= ${LIBEXECDIR}/dwatch/sendrecv ${LIBEXECDIR}/dwatch/send
+LINKS+= ${LIBEXECDIR}/dwatch/sendrecv ${LIBEXECDIR}/dwatch/sendmsg
+LINKS+= ${LIBEXECDIR}/dwatch/sendrecv ${LIBEXECDIR}/dwatch/sendto
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-accept
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-accept-established
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-accept-refused
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect-established
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect-refused
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-connect-request
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-established
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-init
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-io
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-receive
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-refused
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-send
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-state-change
+LINKS+= ${LIBEXECDIR}/dwatch/tcp ${LIBEXECDIR}/dwatch/tcp-status
+LINKS+= ${LIBEXECDIR}/dwatch/udp ${LIBEXECDIR}/dwatch/udp-receive
+LINKS+= ${LIBEXECDIR}/dwatch/udp ${LIBEXECDIR}/dwatch/udp-send
+LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_lookup
+LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_mkdir
+LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_mknod
+LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_remove
+LINKS+= ${LIBEXECDIR}/dwatch/vop_create ${LIBEXECDIR}/dwatch/vop_rmdir
+
+.include <bsd.prog.mk>
Index: stable/11/cddl/usr.sbin/dwatch/libexec/chmod
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/chmod
+++ stable/11/cddl/usr.sbin/dwatch/libexec/chmod
@@ -0,0 +1,65 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for [l]chmod(2), fchmodat(2), or similar entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print mode/path being passed to chmod(2), lchmod(2), fchmodat(2), or similar
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+chmod)
+ : ${PROBE:=$( echo \
+ syscall::chmod:entry, \
+ syscall::lchmod:entry, \
+ syscall::fchmodat:entry )}
+ ;;
+*)
+ : ${PROBE:=syscall::$PROFILE:entry}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this mode_t mode;
+this string path;
+this u_char at;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /*
+ * Should we expect the first argument to be a file descriptor?
+ * NB: Based on probefunc ending in "at" (e.g., fchmodat(2))
+ */
+ this->at = strstr(probefunc, "at") ==
+ (probefunc + strlen(probefunc) - 2) ? 1 : 0;
+
+ this->mode = (mode_t)(this->at ? arg2 : arg1);
+ this->path = copyinstr(this->at ? arg1 : arg0);
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print mode/path details
+ */
+ printf("%04o %s", this->mode, this->path);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/errno
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/errno
+++ stable/11/cddl/usr.sbin/dwatch/libexec/errno
@@ -0,0 +1,37 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for syscall errno logging $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print when syscall returns with non-zero errno (default) or other condition.
+# To override the default test condition, use (for example) `-t errno==2' to
+# test for specific value or simply `-t 1' to unconditionally show all values.
+#
+############################################################ PROBE
+
+: ${PROBE:=syscall:::return}
+
+############################################################ EVENT ACTION
+
+[ "$CUSTOM_TEST" ] || EVENT_TEST="errno > 0"
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print errno details
+ */
+ printf("%s: %s (%i)", probefunc, strerror[errno], errno);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/io
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/io
+++ stable/11/cddl/usr.sbin/dwatch/libexec/io
@@ -0,0 +1,108 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_io(4) $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display activity related to disk I/O
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+io) : ${PROBE:=io:::start, io:::done} ;;
+ *) : ${PROBE:=io:::${PROFILE#io-}}
+esac
+
+############################################################ EVENT ACTION
+
+[ "$CUSTOM_TEST" ] || EVENT_TEST='this->devinfo.dev_name != ""'
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this bufinfo_t bufinfo;
+this devinfo_t devinfo;
+this int b_flags;
+this long bio_length;
+this string bio_cmd;
+this string bio_flags;
+this string device_entry;
+this string device_if;
+this string device_type;
+this string flow;
+
+inline string append_bio_flag[int flags, int flag] = this->bio_flags =
+ strjoin(this->bio_flags,
+ strjoin(this->bio_flags == "" ? "" : (flags & flag) == flag ? "|" : "",
+ bio_flag_string[flags & flag]));
+
+$PROBE /(struct bio *)args[0] != NULL/ /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /*
+ * dtrace_io(4)
+ */
+ this->flow = probefunc == "done" ? "<-" : "->";
+
+ /*
+ * struct bio *
+ */
+ this->bufinfo = xlate <bufinfo_t> ((struct bio *)args[0]);
+ this->bio_cmd = bio_cmd_string[(int)this->bufinfo.b_cmd];
+ this->b_flags = (int)this->bufinfo.b_flags;
+ this->bio_flags = bio_flag_string[this->b_flags & BIO_ERROR];
+ this->bio_flags = strjoin(this->bio_flags, this->bufinfo.b_error ?
+ strjoin(this->bio_flags == "" ?
+ bio_flag_string[BIO_ERROR] : "",
+ strjoin("#", lltostr(this->bufinfo.b_error))) :
+ "");
+ append_bio_flag[this->b_flags, BIO_DONE];
+ append_bio_flag[this->b_flags, BIO_ONQUEUE];
+ append_bio_flag[this->b_flags, BIO_ORDERED];
+ append_bio_flag[this->b_flags, BIO_UNMAPPED];
+ append_bio_flag[this->b_flags, BIO_TRANSIENT_MAPPING];
+ append_bio_flag[this->b_flags, BIO_VLIST];
+ this->bio_flags = this->bio_flags == "" ? "-" : this->bio_flags;
+ this->bio_length = (long)this->bufinfo.b_bcount;
+
+ /*
+ * struct devstat *
+ */
+ this->devinfo = xlate <devinfo_t> ((struct devstat *)args[1]);
+ this->device_type = device_type[(int)this->devinfo.dev_type];
+ this->device_if = device_if[(int)this->devinfo.dev_type];
+ this->device_entry = strjoin(this->devinfo.dev_name,
+ lltostr(this->devinfo.dev_minor));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print disk I/O details
+ */
+ printf("%s %s %s %s %s %s %d byte%s",
+ this->flow,
+ this->device_type,
+ this->device_if,
+ this->device_entry,
+ this->bio_cmd,
+ this->bio_flags,
+ this->bio_length,
+ this->bio_length == 1 ? "" : "s");
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/ip
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/ip
+++ stable/11/cddl/usr.sbin/dwatch/libexec/ip
@@ -0,0 +1,76 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_ip(4) $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display interface name and bytes sent/received when IP I/O occurs
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+ip) : ${PROBE:=ip:::send, ip:::receive} ;;
+ *) : ${PROBE:=ip:::${PROFILE#ip-}}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this string flow;
+this string if_name;
+this string local;
+this string remote;
+this u_char recv;
+this uint32_t length;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /*
+ * dtrace_ip(4)
+ */
+ this->recv = probename == "receive" ? 1 : 0;
+ this->flow = this->recv ? "<-" : "->";
+
+ /*
+ * ipinfo_t *
+ */
+ this->length = (uint32_t)args[2]->ip_plength;
+ this->local = this->recv ? args[2]->ip_daddr : args[2]->ip_saddr;
+ this->remote = this->recv ? args[2]->ip_saddr : args[2]->ip_daddr;
+
+ /*
+ * ifinfo_t *
+ */
+ this->if_name = args[3]->if_name;
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print network I/O details
+ */
+ printf("%s %s %s %s %u byte%s",
+ this->if_name,
+ this->local,
+ this->flow,
+ this->remote,
+ this->length,
+ this->length == 1 ? "" : "s");
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/kill
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/kill
+++ stable/11/cddl/usr.sbin/dwatch/libexec/kill
@@ -0,0 +1,47 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for kill(2) [or similar] entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to kill(2) [or similar]
+#
+############################################################ PROBE
+
+: ${PROBE:=syscall::$PROFILE:entry}
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this int sig;
+this pid_t pid;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->pid = (pid_t)arg0;
+ this->sig = (int)arg1;
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print signal/pid details
+ */
+ printf("signal %i to pid %d", this->sig, this->pid);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/nanosleep
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/nanosleep
+++ stable/11/cddl/usr.sbin/dwatch/libexec/nanosleep
@@ -0,0 +1,54 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for nanosleep(2) [or similar] entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print arguments being passed to nanosleep(2) [or similar]
+#
+############################################################ PROBE
+
+: ${PROBE:=syscall::$PROFILE:entry}
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this struct timespec * rqtp;
+this time_t requested_sec;
+this long requested_nsec;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ print("<$ID>");
+}
+ /*
+ * const struct timespec *
+ */
+ this->rqtp = (struct timespec *)copyin(arg0, sizeof(struct timespec));
+ this->requested_sec = (time_t)this->rqtp->tv_sec;
+ this->requested_nsec = (long)this->rqtp->tv_nsec;
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Dump nanosleep(2) arguments
+ */
+ printf("%d.%d seconds",
+ this->requested_sec, this->requested_nsec / 100000);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/open
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/open
+++ stable/11/cddl/usr.sbin/dwatch/libexec/open
@@ -0,0 +1,57 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for open[at](2) [or similar] entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print path being passed to open(2), openat(2), or similar
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+open) : ${PROBE:=syscall::open:entry, syscall::openat:entry} ;;
+ *) : ${PROBE:=syscall::$PROFILE:entry}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this string path;
+this u_char at;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /*
+ * Should we expect the first argument to be a file descriptor?
+ * NB: Based on probefunc ending in "at" (e.g., openat(2))
+ */
+ this->at = strstr(probefunc, "at") ==
+ (probefunc + strlen(probefunc) - 2) ? 1 : 0;
+
+ this->path = copyinstr(this->at ? arg1 : arg0);
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print path details
+ */
+ printf("%s", this->path);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/proc
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/proc
+++ stable/11/cddl/usr.sbin/dwatch/libexec/proc
@@ -0,0 +1,164 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_proc(4) activity $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display process activity
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+proc)
+ : ${PROBE:=$( echo \
+ proc:::create, \
+ proc:::exec, \
+ proc:::exec-failure, \
+ proc:::exec-success, \
+ proc:::exit, \
+ proc:::signal-clear, \
+ proc:::signal-discard, \
+ proc:::signal-send )}
+ ;;
+proc-signal)
+ : ${PROBE:=$( echo \
+ proc:::signal-clear, \
+ proc:::signal-discard, \
+ proc:::signal-send )}
+ ;;
+proc-status)
+ : ${PROBE:=$( echo \
+ proc:::create, \
+ proc:::exec, \
+ proc:::exec-failure, \
+ proc:::exec-success, \
+ proc:::exit )}
+ ;;
+*)
+ : ${PROBE:=proc:::${PROFILE#proc-}}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this int sig;
+this pid_t pid;
+this string details;
+this string exec_arg0;
+
+inline string probealias[string name] =
+ name == "create" ? "FORK" :
+ name == "exec" ? "EXEC" :
+ name == "exec-failure" ? "FAIL" :
+ name == "exec-success" ? "INIT" :
+ name == "exit" ? "EXIT" :
+ name == "signal-clear" ? "CLEAR" :
+ name == "signal-discard" ? "DISCARD" :
+ name == "signal-send" ? "SEND" :
+ name;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->details = "";
+}
+
+proc:::create /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");
+}
+ $( pproc -P _create "(struct proc *)args[0]" )
+
+ /* details = "pid <pid of args[0]> -- <proc args of args[0]>" */
+ this->details = strjoin(
+ strjoin("pid ", lltostr(this->pid_create)),
+ strjoin(" -- ", this->args_create));
+}
+
+proc:::exec /* probe ID $(( $ID + 2 )) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))");}
+ this->details = this->exec_arg0 = stringof(arg0);
+}
+
+proc:::exec-failure /* probe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");
+}
+ /* details = "<arg0 from proc:::exec>: <strerror of arg0> (<arg0>)" */
+ this->details = strjoin(
+ strjoin(this->exec_arg0, ": "),
+ strjoin(strerror[(int)arg0],
+ strjoin(" (", strjoin(lltostr((int)arg0), ")"))));
+}
+
+proc:::exec-success /* probe ID $(( $ID + 4 )) */
+{${TRACE:+
+ printf("<$(( $ID + 4 ))>");}
+ this->details = this->args0;
+}
+
+proc:::exit /* probe ID $(( $ID + 5 )) */
+{${TRACE:+
+ printf("<$(( $ID + 5 ))>");}
+ this->details = child_signal_string[(int)arg0];
+}
+
+proc:::signal-clear /* probe ID $(( $ID + 6 )) */
+{${TRACE:+
+ printf("<$(( $ID + 6 ))>");}
+ this->pid = (pid_t)((ksiginfo_t *)args[1])->ksi_info.si_pid;
+ this->sig = (int)arg0;
+}
+
+proc:::signal-discard, proc:::signal-send /* probe ID $(( $ID + 7 )) */
+{${TRACE:+
+ printf("<$(( $ID + 7 ))>");}
+ this->pid = (pid_t)((struct proc *)args[1])->p_pid;
+ this->sig = (int)arg2;
+}
+
+proc:::signal-clear,
+proc:::signal-discard,
+proc:::signal-send /* probe ID $(( $ID + 8 )) */
+{${TRACE:+
+ printf("<$(( $ID + 8 ))>");
+}
+ /* details = "<signal>[<num>] pid <pid>" */
+ this->details = strjoin(strjoin(signal_string[this->sig], "["),
+ strjoin(strjoin(lltostr(this->sig), "] pid "),
+ lltostr(this->pid)));
+}
+
+proc:::signal-send, proc:::signal-discard /* probe ID $(( $ID + 9 )) */
+{${TRACE:+
+ printf("<$(( $ID + 9 ))>");
+}
+ $( pproc -P _signal "(struct proc *)args[1]" )
+
+ this->details = strjoin(this->details,
+ strjoin(" -- ", this->args_signal));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 10 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print details
+ */
+ printf("%s %s", probealias[probename], this->details);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/rw
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/rw
+++ stable/11/cddl/usr.sbin/dwatch/libexec/rw
@@ -0,0 +1,74 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for read(2), write(2), or similar entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display data sent/received when read(2)/write(2) occurs
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+rw) : ${PROBE:=syscall::read:entry, syscall::write:entry} ;;
+ *) : ${PROBE:=syscall::$PROFILE:entry}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this size_t nbytes;
+this string bufstr;
+this string flow;
+this void * buf;
+this void * data;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /*
+ * R/W
+ */
+ this->flow = probefunc == "read" ? "<-" : "->";
+ this->buf = (void *)arg1;
+ this->nbytes = (size_t)arg2;
+
+ /*
+ * Allocate temporary memory for, copy, and NUL-terminate the data
+ */
+ this->data = alloca(this->nbytes + 1);
+ copyinto((uintptr_t)this->buf, this->nbytes, this->data);
+ bcopy("\0", (void *)((uintptr_t)this->data + this->nbytes), 1);
+
+ /*
+ * Extract string from temporary memory
+ */
+ this->bufstr = stringof(this->data);
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print read/write details
+ */
+ printf("%s \"%s\" %d byte%s",
+ this->flow,
+ this->bufstr,
+ this->nbytes,
+ this->nbytes == 1 ? "" : "s");
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/sched
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/sched
+++ stable/11/cddl/usr.sbin/dwatch/libexec/sched
@@ -0,0 +1,109 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_sched(4) $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display CPU scheduling activity
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+sched)
+ : ${PROBE:=sched:::} ;;
+sched-cpu)
+ : ${PROBE:=sched:::off-cpu, sched:::on-cpu, sched:::remain-cpu} ;;
+sched-exec)
+ : ${PROBE:=sched:::sleep, sched:::wakeup} ;;
+sched-pri)
+ : ${PROBE:=sched:::change-pri, sched:::lend-pri} ;;
+sched-queue)
+ : ${PROBE:=sched:::dequeue, sched:::enqueue, sched:::load-change} ;;
+*)
+ : ${PROBE:=sched:::${PROFILE#sched-}}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this pid_t pid;
+this string args;
+this string details;
+this u_char curprio;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->args = this->args0;
+ this->details = "";
+ this->pid = this->pid0;
+}
+
+sched:::change-pri, sched:::dequeue, sched:::enqueue,
+sched:::lend-pri, sched:::off-cpu, sched:::surrender,
+sched:::tick, sched:::wakeup /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");}
+ this->curprio = (u_char)((struct thread *)args[0])->td_priority;
+
+ $( pproc -P _sched "(struct proc *)args[1]" )
+
+ this->args = this->args_sched;
+ this->pid = this->pid_sched;
+}
+
+sched:::enqueue /* probe ID $(( $ID + 2 )) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");}
+ /* details = "head" or "tail" */
+ this->details = (int)arg3 == 0 ? "tail" : "head";
+}
+
+sched:::change-pri, sched:::lend-pri /* probe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ /* details = "<curprio> -> <arg2>" */
+ this->details = strjoin(lltostr(this->curprio),
+ strjoin("->", lltostr((uint8_t)arg2)));
+}
+
+sched:::load-change /* probe ID $(( $ID + 4 )) */
+{${TRACE:+
+ printf("<$(( $ID + 4 ))>");}
+ /* details = "CPU<arg0> queue <arg1>" */
+ this->details = strjoin(strjoin("CPU", lltostr((int)arg0)),
+ strjoin(" queue ", lltostr((int)arg1)));
+}
+
+$PROBE /* probe ID $(( $ID + 5 )) */
+{${TRACE:+
+ printf("<$(( $ID + 5 ))>");}
+ /* details += " pid <pid> -- <proc args of pid>" */
+ this->details = strjoin(this->details, this->details == "" ? "" : " ");
+ this->details = strjoin(this->details, strjoin(
+ strjoin("pid ", lltostr(this->pid)),
+ strjoin(" -- ", this->args)));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 6 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print scheduling details
+ */
+ printf("%s %s", probename, this->details);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/sendrecv
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/sendrecv
+++ stable/11/cddl/usr.sbin/dwatch/libexec/sendrecv
@@ -0,0 +1,229 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for send(2)/recv(2) $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print details from send(2)/recv(2)
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+sendrecv)
+ : ${PROBE:=$( echo \
+ syscall::recvfrom:return, \
+ syscall::recvmsg:return, \
+ syscall::sendmsg:entry, \
+ syscall::sendto:entry )} ;;
+send)
+ : ${PROBE:=$( echo \
+ syscall::sendmsg:entry, \
+ syscall::sendto:entry )} ;;
+recv)
+ : ${PROBE:=$( echo \
+ syscall::recvfrom:return, \
+ syscall::recvmsg:return )} ;;
+recv*)
+ : ${PROBE:=syscall::$PROFILE:return} ;;
+*)
+ : ${PROBE:=syscall::$PROFILE:entry}
+esac
+
+############################################################ EVENT ACTION
+
+#[ "$CUSTOM_TEST" ] || EVENT_TEST="this->from != NULL"
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+typedef struct sainfo {
+ sa_family_t sa_family;
+ uint16_t port;
+ string addr;
+ string family;
+} sainfo_t;
+
+/*
+ * Address families from <sys/socket.h>
+ */
+#pragma D binding "1.13" address_family_string
+inline string address_family_string[sa_family_t af] =
+ af == AF_UNSPEC ? "AF_UNSPEC" :
+ af == AF_LOCAL ? "AF_UNIX" :
+ af == AF_UNIX ? "AF_UNIX" :
+ af == AF_INET ? "AF_INET" :
+ af == AF_IMPLINK ? "AF_IMPLINK" :
+ af == AF_PUP ? "AF_PUP" :
+ af == AF_CHAOS ? "AF_CHAOS" :
+ af == AF_NETBIOS ? "AF_NETBIOS" :
+ af == AF_ISO ? "AF_ISO" :
+ af == AF_OSI ? "AF_ISO" :
+ af == AF_ECMA ? "AF_ECMA" :
+ af == AF_DATAKIT ? "AF_DATAKIT" :
+ af == AF_CCITT ? "AF_CCITT" :
+ af == AF_SNA ? "AF_SNA" :
+ af == AF_DECnet ? "AF_DECnet" :
+ af == AF_DLI ? "AF_DLI" :
+ af == AF_LAT ? "AF_LAT" :
+ af == AF_HYLINK ? "AF_HYLINK" :
+ af == AF_APPLETALK ? "AF_APPLETALK" :
+ af == AF_ROUTE ? "AF_ROUTE" :
+ af == AF_LINK ? "AF_LINK" :
+ af == pseudo_AF_XTP ? "pseudo_AF_XTP" :
+ af == AF_COIP ? "AF_COIP" :
+ af == AF_CNT ? "AF_CNT" :
+ af == pseudo_AF_RTIP ? "pseudo_AF_RTIP" :
+ af == AF_IPX ? "AF_IPX" :
+ af == AF_SIP ? "AF_SIP" :
+ af == pseudo_AF_PIP ? "pseudo_AF_PIP" :
+ af == AF_ISDN ? "AF_ISDN" :
+ af == AF_E164 ? "AF_ISDN" :
+ af == pseudo_AF_KEY ? "pseudo_AF_KEY" :
+ af == AF_INET6 ? "AF_INET6" :
+ af == AF_NATM ? "AF_NATM" :
+ af == AF_ATM ? "AF_ATM" :
+ af == pseudo_AF_HDRCMPLT ? "pseudo_AF_HDRCMPLT" :
+ af == AF_NETGRAPH ? "AF_NETGRAPH" :
+ af == AF_SLOW ? "AF_SLOW" :
+ af == AF_SCLUSTER ? "AF_SCLUSTER" :
+ af == AF_ARP ? "AF_ARP" :
+ af == AF_BLUETOOTH ? "AF_BLUETOOTH" :
+ af == AF_IEEE80211 ? "AF_IEEE80211" :
+ af == AF_INET_SDP ? "AF_INET_SDP" :
+ af == AF_INET6_SDP ? "AF_INET6_SDP" :
+ af == AF_MAX ? "AF_MAX" :
+ strjoin("AF_UNKNOWN(", strjoin(lltostr(af), ")"));
+
+#pragma D binding "1.13" sa_data_size
+inline int sa_data_size = 14;
+#pragma D binding "1.13" sa_dummy_data
+inline char *sa_dummy_data = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
+#pragma D binding "1.13" sa_data_addr
+inline string sa_data_addr[sa_family_t af, char data[sa_data_size]] =
+ af == AF_INET ? strjoin(
+ strjoin(strjoin(lltostr(data[2] & 0xFF), "."),
+ strjoin(lltostr(data[3] & 0xFF), ".")
+ ),
+ strjoin(strjoin(lltostr(data[4] & 0xFF), "."),
+ lltostr(data[5] & 0xFF))
+ ) :
+ "";
+
+#pragma D binding "1.13" sa_data_port
+inline uint16_t sa_data_port[sa_family_t af, char data[sa_data_size]] =
+ af == AF_INET ? (data[0] << 8) + data[1] :
+ 0;
+
+#pragma D binding "1.13" translator
+translator sainfo_t < struct sockaddr *SA > {
+ sa_family = SA == NULL ? 0 : SA->sa_family;
+ family = address_family_string[SA == NULL ? 0 : SA->sa_family];
+ addr = SA == NULL ?
+ sa_data_addr[0, sa_dummy_data] :
+ sa_data_addr[SA->sa_family, SA->sa_data];
+ port = SA == NULL ?
+ sa_data_port[0, sa_dummy_data] :
+ sa_data_port[SA->sa_family, SA->sa_data];
+};
+
+this sainfo_t sainfo;
+this ssize_t nbytes;
+this string details;
+this string flow;
+this struct msghdr * msghdr;
+this struct sockaddr * sa;
+
+inline string probeflow[string func] =
+ func == "recvfrom" ? "<-" :
+ func == "recvmsg" ? "<-" :
+ func == "recvmmsg" ? "<-" :
+ "->";
+
+inline string af_details[sa_family_t af, string addr, uint16_t port] =
+ af == AF_INET ? strjoin(addr, strjoin(":", lltostr(port))) :
+ "";
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->details = "";
+ this->flow = probeflow[probefunc];
+}
+
+syscall::recvfrom:entry /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");}
+ this->sainfo = xlate <sainfo_t> ((struct sockaddr *)(args[4] == NULL ?
+ NULL : copyin(arg4, sizeof(struct sockaddr))));
+}
+
+syscall::recvfrom:return /* probe ID $(( $ID + 2 )) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");}
+ this->nbytes = arg0;
+ this->details = strjoin("from ", strjoin(
+ strjoin(this->sainfo.family, " "),
+ af_details[this->sainfo.sa_family,
+ this->sainfo.addr, this->sainfo.port]));
+}
+
+syscall::recvmsg:entry /* probe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ this->sockaddr = (struct sockaddr *)arg1;
+}
+
+syscall::recvmsg:return /this->sockaddr != NULL/ /* probe ID $(( $ID + 4 )) */
+{${TRACE:+
+ printf("<$(( $ID + 4 ))>");}
+ this->nbytes = arg0;
+ this->sainfo = xlate <sainfo_t> ((struct sockaddr *)this->sockaddr);
+ this->details = strjoin("sainfo=[", "]");
+}
+
+syscall::sendmsg:entry /* probe ID $(( $ID + 5 )) */
+{${TRACE:+
+ printf("<$(( $ID + 5 ))>");}
+ this->nbytes = arg2;
+}
+
+syscall::sendto:entry /* probe ID $(( $ID + 6 )) */
+{${TRACE:+
+ printf("<$(( $ID + 6 ))>");}
+ this->nbytes = arg2;
+ this->sainfo = xlate <sainfo_t> ((struct sockaddr *)(arg4 == NULL ?
+ NULL : copyin(arg4, sizeof(struct sockaddr))));
+ this->details = strjoin("to ", strjoin(
+ strjoin(this->sainfo.family, " "),
+ af_details[this->sainfo.sa_family,
+ this->sainfo.addr, this->sainfo.port]));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 7 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print socket details
+ */
+ printf("%s %d byte%s%s%s",
+ this->flow,
+ this->nbytes,
+ this->nbytes != 1 ? "s" : "",
+ this->details != "" ? " " : "",
+ this->details);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/tcp
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/tcp
+++ stable/11/cddl/usr.sbin/dwatch/libexec/tcp
@@ -0,0 +1,210 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_tcp(4) connections $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display local/remote TCP addresses/ports and bytes sent/received for TCP I/O
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+tcp)
+ : ${PROBE:=$( echo \
+ tcp:::accept-established, \
+ tcp:::accept-refused, \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request, \
+ tcp:::receive, \
+ tcp:::send, \
+ tcp:::state-change )} ;;
+tcp-accept)
+ : ${PROBE:=tcp:::accept-established, tcp:::accept-refused} ;;
+tcp-connect)
+ : ${PROBE:=$( echo \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request )} ;;
+tcp-established)
+ : ${PROBE:=tcp:::accept-established, tcp:::connect-established} ;;
+tcp-init)
+ : ${PROBE:=$( echo \
+ tcp:::accept-established, \
+ tcp:::accept-refused, \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request )} ;;
+tcp-io)
+ : ${PROBE:=tcp:::send, tcp:::receive} ;;
+tcp-refused)
+ : ${PROBE:=tcp:::accept-refused, tcp:::connect-refused} ;;
+tcp-status)
+ : ${PROBE:=$( echo \
+ tcp:::accept-established, \
+ tcp:::accept-refused, \
+ tcp:::connect-established, \
+ tcp:::connect-refused, \
+ tcp:::connect-request, \
+ tcp:::state-change )} ;;
+*)
+ : ${PROBE:=tcp:::${PROFILE#tcp-}}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this int32_t from_state;
+this int32_t to_state;
+this string details;
+this string flow;
+this string local;
+this string remote;
+this u_char local6;
+this u_char remote6;
+this u_char slocal;
+this uint16_t lport;
+this uint16_t rport;
+this uint32_t length;
+
+inline string probeflow[string name] =
+ name == "accept-established" ? "<-" :
+ name == "accept-refused" ? "X-" :
+ name == "connect-refused" ? "-X" :
+ name == "connect-request" ? "-?" :
+ name == "receive" ? "<-" :
+ "->";
+
+inline u_char srclocal[string name] =
+ name == "accept-refused" ? 1 :
+ name == "connect-request" ? 1 :
+ name == "send" ? 1 :
+ 0;
+
+/*
+ * TCPSTATES from <sys/netinet/tcp_fsm.h> used by netstat(1)
+ */
+inline string tcpstate[int32_t state] =
+ state == TCPS_CLOSED ? "CLOSED" :
+ state == TCPS_LISTEN ? "LISTEN" :
+ state == TCPS_SYN_SENT ? "SYN_SENT" :
+ state == TCPS_SYN_RECEIVED ? "SYN_RCVD" :
+ state == TCPS_ESTABLISHED ? "ESTABLISHED" :
+ state == TCPS_CLOSE_WAIT ? "CLOSE_WAIT" :
+ state == TCPS_FIN_WAIT_1 ? "FIN_WAIT_1" :
+ state == TCPS_CLOSING ? "CLOSING" :
+ state == TCPS_LAST_ACK ? "LAST_ACK" :
+ state == TCPS_FIN_WAIT_2 ? "FIN_WAIT_2" :
+ state == TCPS_TIME_WAIT ? "TIME_WAIT" :
+ strjoin("UNKNOWN(", strjoin(lltostr(state), ")"));
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->details = "";
+
+ /*
+ * dtrace_tcp(4)
+ */
+ this->flow = probeflow[probename];
+}
+
+tcp:::accept-established,
+tcp:::accept-refused,
+tcp:::connect-established,
+tcp:::connect-refused,
+tcp:::connect-request,
+tcp:::receive,
+tcp:::send /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");
+}
+ /*
+ * dtrace_tcp(4)
+ */
+ this->slocal = srclocal[probename];
+
+ /*
+ * ipinfo_t *
+ */
+ this->local = this->slocal ? args[2]->ip_saddr : args[2]->ip_daddr;
+ this->remote = this->slocal ? args[2]->ip_daddr : args[2]->ip_saddr;
+
+ /*
+ * tcpinfo_t *
+ */
+ this->lport = this->slocal ? args[4]->tcp_sport : args[4]->tcp_dport;
+ this->rport = this->slocal ? args[4]->tcp_dport : args[4]->tcp_sport;
+
+ /*
+ * IPv6 support
+ */
+ this->local6 = strstr(this->local, ":") != NULL ? 1 : 0;
+ this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0;
+ this->local = strjoin(strjoin(this->local6 ? "[" : "",
+ this->local), this->local6 ? "]" : "");
+ this->remote = strjoin(strjoin(this->remote6 ? "[" : "",
+ this->remote), this->remote6 ? "]" : "");
+}
+
+tcp:::state-change /* probe ID $(( $ID + 2 )) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");
+}
+ /*
+ * tcpsinfo_t *
+ */
+ this->local = args[3]->tcps_laddr;
+ this->lport = (uint16_t)args[3]->tcps_lport;
+ this->remote = args[3]->tcps_raddr;
+ this->rport = (uint16_t)args[3]->tcps_rport;
+ this->to_state = (int32_t)args[3]->tcps_state;
+
+ /*
+ * tcplsinfo_t *
+ */
+ this->from_state = (int32_t)args[5]->tcps_state;
+
+ /* flow = "[from state]->[to state]" */
+ this->flow = strjoin(tcpstate[this->from_state],
+ strjoin("->", tcpstate[this->to_state]));
+}
+
+tcp:::send, tcp:::receive /* pribe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ this->length = (uint32_t)args[2]->ip_plength -
+ (uint8_t)args[4]->tcp_offset;
+
+ /* details = " <length> byte<s>" */
+ this->details = strjoin(
+ strjoin(" ", lltostr(this->length)),
+ strjoin(" byte", this->length == 1 ? "" : "s"));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 4 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print details
+ */
+ printf("%s:%u %s %s:%u%s",
+ this->local, this->lport,
+ this->flow,
+ this->remote, this->rport,
+ this->details);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/udp
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/udp
+++ stable/11/cddl/usr.sbin/dwatch/libexec/udp
@@ -0,0 +1,89 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for dtrace_udp(4) $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Display local/remote UDP addresses/ports and bytes sent/received for UDP I/O
+#
+############################################################ PROBE
+
+case "$PROFILE" in
+udp) : ${PROBE:=udp:::send, udp:::receive} ;;
+ *) : ${PROBE:=udp:::${PROFILE#udp-}}
+esac
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+this string flow;
+this string local;
+this string remote;
+this u_char local6;
+this u_char recv;
+this u_char remote6;
+this uint16_t length;
+this uint16_t lport;
+this uint16_t rport;
+
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");
+}
+ /*
+ * dtrace_udp(4)
+ */
+ this->recv = probename == "receive" ? 1 : 0;
+ this->flow = this->recv ? "<-" : "->";
+
+ /*
+ * ipinfo_t *
+ */
+ this->local = this->recv ? args[2]->ip_daddr : args[2]->ip_saddr;
+ this->remote = this->recv ? args[2]->ip_saddr : args[2]->ip_daddr;
+
+ /*
+ * udpinfo_t *
+ */
+ this->length = (uint16_t)args[4]->udp_length;
+ this->lport = this->recv ? args[4]->udp_dport : args[4]->udp_sport;
+ this->rport = this->recv ? args[4]->udp_sport : args[4]->udp_dport;
+
+ /*
+ * IPv6 support
+ */
+ this->local6 = strstr(this->local, ":") != NULL ? 1 : 0;
+ this->remote6 = strstr(this->remote, ":") != NULL ? 1 : 0;
+ this->local = strjoin(strjoin(this->local6 ? "[" : "",
+ this->local), this->local6 ? "]" : "");
+ this->remote = strjoin(strjoin(this->remote6 ? "[" : "",
+ this->remote), this->remote6 ? "]" : "");
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + 1 ))
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print network I/O details
+ */
+ printf("%s:%u %s %s:%u %d byte%s",
+ this->local, this->lport,
+ this->flow,
+ this->remote, this->rport,
+ this->length,
+ this->length == 1 ? "" : "s");
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/vop_create
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/vop_create
+++ stable/11/cddl/usr.sbin/dwatch/libexec/vop_create
@@ -0,0 +1,196 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_CREATE(9) [or similar] entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print filesystem paths being operated-on by VOP_CREATE(9) [or similar]
+# NB: All paths are shown even if error prevents operation.
+#
+############################################################ PROBE
+
+: ${PROBE:=vfs:vop:$PROFILE:entry}
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
+ gsub(/DEPTH/, DEPTH)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->nameDEPTH = "";
+ EOFDEPTH
+ )
+}
+
+$PROBE /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");}
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");}
+ this->dvp = this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH '
+ { buf = buf $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{${TRACE:+
+ printf("<IDNUM>");}
+ this->dvp = this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH + 3 ))>");}
+ this->dvp = this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? (
+ this->dvp->nc_dvp != NULL ? "..." : ""
+ ) : "";
+}
+
+/*
+ * END Pathname-depth iterators
+ */
+
+/*********************************************************/
+
+$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH + 4 ))>");
+}
+ /*
+ * Join full path
+ * NB: Up-to but not including the parent directory (joined below)
+ */
+ this->path = this->fi_mount;
+ this->path = strjoin(this->path, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (N = MAX_DEPTH + 1; N > 0; N--) {
+ gsub(/N/, N)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->path = strjoin(this->path,
+ \ strjoin(this->nameN, this->nameN != "" ? "/" : ""));
+ EOFDEPTH
+ )
+
+ /* Join the parent directory name */
+ this->path = strjoin(this->path, strjoin(this->name =
+ (this->d_name != 0 ? this->d_name : ""),
+ this->name != "" ? "/" : ""));
+
+ /* Join the entry name */
+ this->path = strjoin(this->path,
+ this->name = (this->fi_name != 0 ? this->fi_name : ""));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + $MAX_DEPTH + 5 ))
+
+############################################################ EVENT ACTION
+
+EVENT_TEST="this->fi_mount != 0"
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print full path
+ */
+ printf("%s", this->path);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/vop_readdir
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/vop_readdir
+++ stable/11/cddl/usr.sbin/dwatch/libexec/vop_readdir
@@ -0,0 +1,188 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_READDIR(9) [or similar] entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print directory paths being read by VOP_READDIR(9) [or similar]
+# NB: All paths are shown even if error prevents their reading.
+#
+############################################################ PROBE
+
+: ${PROBE:=vfs:vop:$PROFILE:entry}
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
+ gsub(/DEPTH/, DEPTH)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->nameDEPTH = "";
+ EOFDEPTH
+ )
+}
+
+$PROBE /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == ""/ /* probe ID $((
+ $ID + 1
+ )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");}
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");}
+ this->dvp = this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH '
+ { buf = buf $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{${TRACE:+
+ printf("<IDNUM>");}
+ this->dvp = this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH + 3 ))>");}
+ this->dvp = this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? (
+ this->dvp->nc_dvp != NULL ? "..." : ""
+ ) : "";
+}
+
+/*
+ * END Pathname-depth iterators
+ */
+
+/*********************************************************/
+
+$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH + 4 ))>");
+}
+ /*
+ * Join full path
+ * NB: Up-to but not including the parent directory (joined below)
+ */
+ this->path = this->fi_mount;
+ this->path = strjoin(this->path, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (N = MAX_DEPTH + 1; N > 0; N--) {
+ gsub(/N/, N)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->path = strjoin(this->path,
+ \ strjoin(this->nameN, this->nameN != "" ? "/" : ""));
+ EOFDEPTH
+ )
+
+ /* Join the parent directory name */
+ this->path = strjoin(this->path, strjoin(this->name =
+ (this->d_name != 0 ? this->d_name : ""),
+ this->name != "" ? "/" : ""));
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + $MAX_DEPTH + 5 ))
+
+############################################################ EVENT ACTION
+
+EVENT_TEST="this->fi_mount != 0"
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print full path
+ */
+ printf("%s", this->path);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/vop_rename
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/vop_rename
+++ stable/11/cddl/usr.sbin/dwatch/libexec/vop_rename
@@ -0,0 +1,302 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_RENAME(9) [or similar] entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print filesystem paths being renamed by VOP_RENAME(9) [or similar]
+# NB: All paths are shown even if error prevents their rename.
+#
+############################################################ PROBE
+
+: ${PROBE:=vfs:vop:$PROFILE:entry}
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->fvp = args[1] ? args[1]->a_fdvp : NULL;
+ this->fncp = this->fvp != NULL ?
+ this->fvp->v_cache_dst.tqh_first : 0;
+ this->ffi_name = args[1] ? (
+ args[1]->a_fcnp != NULL ?
+ stringof(args[1]->a_fcnp->cn_nameptr) : ""
+ ) : "";
+ this->fmount = this->fvp != NULL ?
+ this->fvp->v_mount : NULL; /* ptr to vfs we are in */
+ this->ffi_fs = this->fmount != NULL ?
+ stringof(this->fmount->mnt_stat.f_fstypename) : "";
+ this->ffi_mount = this->fmount != NULL ?
+ stringof(this->fmount->mnt_stat.f_mntonname) : "";
+ this->fd_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+
+ this->tvp = args[1] ? args[1]->a_tdvp : NULL;
+ this->tncp = this->tvp != NULL ?
+ this->tvp->v_cache_dst.tqh_first : 0;
+ this->tfi_name = args[1] ? (
+ args[1]->a_tcnp != NULL ?
+ stringof(args[1]->a_tcnp->cn_nameptr) : ""
+ ) : "";
+ this->tmount = this->tvp != NULL ?
+ this->tvp->v_mount : NULL; /* ptr to vfs we are in */
+ this->tfi_fs = this->tmount != NULL ?
+ stringof(this->tmount->mnt_stat.f_fstypename) : "";
+ this->tfi_mount = this->tmount != NULL ?
+ stringof(this->tmount->mnt_stat.f_mntonname) : "";
+ this->td_name = this->tvp != NULL ? (
+ this->tvp->v_cache_dd != NULL ?
+ stringof(this->tvp->v_cache_dd->nc_name) : ""
+ ) : "";
+
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
+ gsub(/DEPTH/, DEPTH)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->fnameDEPTH = this->tnameDEPTH = "";
+ EOFDEPTH
+ )
+}
+
+$PROBE /this->fvp == 0 || this->ffi_fs == 0 ||
+ this->ffi_fs == "devfs" || this->ffi_fs == "" ||
+ this->ffi_name == ""/ /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");}
+ this->fncp = 0;
+}
+
+$PROBE /this->tvp == 0 || this->tfi_fs == 0 ||
+ this->tfi_fs == "devfs" || this->tfi_fs == "" ||
+ this->tfi_name == ""/ /* probe ID $(( $ID + 2 )) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");}
+ this->tncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE /this->fncp/ /* probe ID $(( $ID + 3 )) (depth 1) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ this->fdvp = this->fncp->nc_dvp != NULL ?
+ this->fncp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->fname1 = this->fdvp != 0 ? (
+ this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE /this->tncp/ /* probe ID $(( $ID + 4 )) (depth 1) */
+{${TRACE:+
+ printf("<$(( $ID + 4 ))>");}
+ this->tdvp = this->tncp->nc_dvp != NULL ?
+ this->tncp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->tname1 = this->tdvp != 0 ? (
+ this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE /this->fname1 == 0 || this->ffi_fs == 0 ||
+ this->ffi_fs == "devfs" || this->ffi_fs == "" ||
+ this->fname1 == "/" || this->fname1 == ""/ /* probe ID $((
+ $ID + 5
+ )) */
+{${TRACE:+
+ printf("<$(( $ID + 5 ))>");}
+ this->fdvp = 0;
+}
+
+$PROBE /this->tname1 == 0 || this->tfi_fs == 0 ||
+ this->tfi_fs == "devfs" || this->tfi_fs == "" ||
+ this->tname1 == "/" || this->tname1 == ""/ /* probe ID $((
+ $ID + 6
+ )) */
+{${TRACE:+
+ printf("<$(( $ID + 6 ))>");}
+ this->tdvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=$(( $ID + 7 )) -v MAX_DEPTH=$MAX_DEPTH '
+ { buf = buf $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM1/, ID)
+ gsub(/IDNUM2/, ID + 1)
+ print
+ ID = ID + 2
+ }
+ }
+' <<EOFDEPTH
+$PROBE /this->fdvp/ /* probe ID IDNUM1 (depth DEPTH) */
+{${TRACE:+
+ printf("<IDNUM1>");}
+ this->fdvp = this->fdvp->nc_dvp != NULL ?
+ this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->fnameDEPTH = this->fdvp != 0 ? (
+ this->fdvp->nc_name != 0 ? stringof(this->fdvp->nc_name) : ""
+ ) : "";
+}
+$PROBE /this->tdvp/ /* probe ID IDNUM2 (depth DEPTH) */
+{${TRACE:+
+ printf("<IDNUM2>");}
+ this->tdvp = this->tdvp->nc_dvp != NULL ?
+ this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->tnameDEPTH = this->tdvp != 0 ? (
+ this->tdvp->nc_name != 0 ? stringof(this->tdvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+$PROBE /this->fdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 5 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH * 2 + 5 ))>");}
+ this->fdvp = this->fdvp->nc_dvp != NULL ?
+ this->fdvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->fname$(( $MAX_DEPTH + 1 )) = this->fdvp != 0 ? (
+ this->fdvp->nc_dvp != NULL ? "..." : ""
+ ) : "";
+}
+$PROBE /this->tdvp/ /* probe ID $(( $ID + $MAX_DEPTH * 2 + 6 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH * 2 + 6 ))>");}
+ this->tdvp = this->tdvp->nc_dvp != NULL ?
+ this->tdvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->tname$(( $MAX_DEPTH + 1 )) = this->tdvp != 0 ? (
+ this->tdvp->nc_dvp != NULL ? "..." : ""
+ ) : "";
+}
+
+/*
+ * END Pathname-depth iterators
+ */
+
+/*********************************************************/
+
+$PROBE /this->ffi_mount != 0 && this->tfi_mount != 0/ /* probe ID $((
+ $ID + $MAX_DEPTH * 2 + 7
+)) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH * 2 + 7 ))>");
+}
+ /*
+ * Join 'from' full path
+ * NB: Up-to but not including the parent directory (joined below)
+ */
+ this->fpath = this->ffi_mount;
+ this->fpath = strjoin(this->fpath, this->ffi_mount != 0 ? (
+ this->ffi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (N = MAX_DEPTH + 1; N > 0; N--) {
+ gsub(/N/, N)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->fpath = strjoin(this->fpath,
+ \ strjoin(this->fnameN, this->fnameN != "" ? "/" : ""));
+ EOFDEPTH
+ )
+
+ /* Join the 'from' parent directory name */
+ this->fpath = strjoin(this->fpath, strjoin(this->fname =
+ (this->fd_name != 0 ? this->fd_name : ""),
+ this->fname != "" ? "/" : ""));
+
+ /* Join the 'from' entry name */
+ this->fpath = strjoin(this->fpath,
+ this->fname = (this->ffi_name != 0 ? this->ffi_name : ""));
+
+ /*
+ * Join 'to' full path
+ * NB: Up-to but not including the parent directory (joined below)
+ */
+ this->tpath = this->tfi_mount;
+ this->tpath = strjoin(this->tpath, this->tfi_mount != 0 ? (
+ this->tfi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (N = MAX_DEPTH + 1; N > 0; N--) {
+ gsub(/N/, N)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->tpath = strjoin(this->tpath,
+ \ strjoin(this->tnameN, this->tnameN != "" ? "/" : ""));
+ EOFDEPTH
+ )
+
+ /* Join the 'to' parent directory name */
+ this->tpath = strjoin(this->tpath, strjoin(this->tname =
+ (this->td_name != 0 ? this->td_name : ""),
+ this->tname != "" ? "/" : ""));
+
+ /* Join the 'to' entry name */
+ this->tpath = strjoin(this->tpath,
+ this->tname = (this->tfi_name != 0 ? this->tfi_name : ""));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + $MAX_DEPTH * 2 + 8 ))
+
+############################################################ EVENT ACTION
+
+EVENT_TEST="this->ffi_mount != 0 && this->tfi_mount != 0"
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print 'from' and 'to' full paths
+ */
+ printf("%s -> %s", this->fpath, this->tpath);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/cddl/usr.sbin/dwatch/libexec/vop_symlink
===================================================================
--- stable/11/cddl/usr.sbin/dwatch/libexec/vop_symlink
+++ stable/11/cddl/usr.sbin/dwatch/libexec/vop_symlink
@@ -0,0 +1,197 @@
+# -*- tab-width: 4 -*- ;; Emacs
+# vi: set filetype=sh tabstop=8 shiftwidth=8 noexpandtab :: Vi/ViM
+############################################################ IDENT(1)
+#
+# $Title: dwatch(8) module for VOP_SYMLINK(9) [or similar] entry $
+# $Copyright: 2014-2018 Devin Teske. All rights reserved. $
+# $FreeBSD$
+#
+############################################################ DESCRIPTION
+#
+# Print symlink paths being created by VOP_SYMLINK(9) [or similar]
+# NB: All paths are shown even if error prevents their creation.
+#
+############################################################ PROBE
+
+: ${PROBE:=vfs:vop:$PROFILE:entry}
+
+############################################################ ACTIONS
+
+exec 9<<EOF
+$PROBE /* probe ID $ID */
+{${TRACE:+
+ printf("<$ID>");}
+ this->vp = (struct vnode *)arg0;
+ this->ncp = this->vp != NULL ?
+ this->vp->v_cache_dst.tqh_first : 0;
+ this->target = args[1] ? args[1]->a_target : "";
+ this->fi_name = args[1] ? (
+ args[1]->a_cnp != NULL ?
+ stringof(args[1]->a_cnp->cn_nameptr) : ""
+ ) : "";
+ this->mount = this->vp != NULL ?
+ this->vp->v_mount : NULL; /* ptr to vfs we are in */
+ this->fi_fs = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_fstypename) : "";
+ this->fi_mount = this->mount != NULL ?
+ stringof(this->mount->mnt_stat.f_mntonname) : "";
+ this->d_name = args[0]->v_cache_dd != NULL ?
+ stringof(args[0]->v_cache_dd->nc_name) : "";
+
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (DEPTH = 1; DEPTH <= MAX_DEPTH + 1; DEPTH++) {
+ gsub(/DEPTH/, DEPTH)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->nameDEPTH = "";
+ EOFDEPTH
+ )
+}
+
+$PROBE /this->vp == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->fi_name == ""/ /* probe ID $(( $ID + 1 )) */
+{${TRACE:+
+ printf("<$(( $ID + 1 ))>");}
+ this->ncp = 0;
+}
+
+/*********************************************************/
+
+$PROBE /this->ncp/ /* probe ID $(( $ID + 2 )) (depth 1) */
+{${TRACE:+
+ printf("<$(( $ID + 2 ))>");}
+ this->dvp = this->ncp->nc_dvp != NULL ?
+ this->ncp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->name1 = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+$PROBE /this->name1 == 0 || this->fi_fs == 0 ||
+ this->fi_fs == "devfs" || this->fi_fs == "" ||
+ this->name1 == "/" || this->name1 == ""/ /* probe ID $(( $ID + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + 3 ))>");}
+ this->dvp = 0;
+}
+
+/*********************************************************/
+
+/*
+ * BEGIN Pathname-depth iterators
+ */
+
+$( awk -v ID=$(( $ID + 4 )) -v MAX_DEPTH=$MAX_DEPTH '
+ { buf = buf $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ for (DEPTH = 2; DEPTH <= MAX_DEPTH; DEPTH++) {
+ $0 = buf
+ gsub(/DEPTH/, DEPTH)
+ gsub(/IDNUM/, ID++)
+ print
+ }
+ }
+' <<EOFDEPTH
+$PROBE /this->dvp/ /* probe ID IDNUM (depth DEPTH) */
+{${TRACE:+
+ printf("<IDNUM>");}
+ this->dvp = this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->nameDEPTH = this->dvp != 0 ? (
+ this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
+ ) : "";
+}
+
+EOFDEPTH
+)
+
+$PROBE /this->dvp/ /* probe ID $(( $ID + $MAX_DEPTH + 3 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH + 3 ))>");}
+ this->dvp = this->dvp->nc_dvp != NULL ?
+ this->dvp->nc_dvp->v_cache_dst.tqh_first : 0;
+ this->name$(( $MAX_DEPTH + 1 )) = this->dvp != 0 ? (
+ this->dvp->nc_dvp != NULL ? "..." : ""
+ ) : "";
+}
+
+/*
+ * END Pathname-depth iterators
+ */
+
+/*********************************************************/
+
+$PROBE /this->fi_mount != 0/ /* probe ID $(( $ID + $MAX_DEPTH + 4 )) */
+{${TRACE:+
+ printf("<$(( $ID + $MAX_DEPTH + 4 ))>");
+}
+ /*
+ * Join full path
+ * NB: Up-to but not including the parent directory (joined below)
+ */
+ this->path = this->fi_mount;
+ this->path = strjoin(this->path, this->fi_mount != 0 ? (
+ this->fi_mount == "/" ? "" : "/"
+ ) : "/");
+ $( awk -v MAX_DEPTH=$MAX_DEPTH '
+ { sub(/^\\\t/, "\t") }
+ { buf = buf "\t" $0 "\n" }
+ END {
+ sub(/\n$/, "", buf)
+ $0 = buf
+ sub(/^[[:space:]]*/, "")
+ for (N = MAX_DEPTH + 1; N > 0; N--) {
+ gsub(/N/, N)
+ print
+ $0 = buf
+ }
+ }
+ ' <<-EOFDEPTH
+ this->path = strjoin(this->path,
+ \ strjoin(this->nameN, this->nameN != "" ? "/" : ""));
+ EOFDEPTH
+ )
+
+ /* Join the parent directory name */
+ this->path = strjoin(this->path, strjoin(this->name =
+ (this->d_name != 0 ? this->d_name : ""),
+ this->name != "" ? "/" : ""));
+
+ /* Join the entry name */
+ this->path = strjoin(this->path,
+ this->name = (this->fi_name != 0 ? this->fi_name : ""));
+}
+EOF
+ACTIONS=$( cat <&9 )
+ID=$(( $ID + $MAX_DEPTH + 5 ))
+
+############################################################ EVENT ACTION
+
+EVENT_TEST="this->fi_mount != 0"
+
+############################################################ EVENT DETAILS
+
+if [ ! "$CUSTOM_DETAILS" ]; then
+exec 9<<EOF
+ /*
+ * Print full path and target
+ */
+ printf("%s -> %s", this->path, this->target);
+EOF
+EVENT_DETAILS=$( cat <&9 )
+fi
+
+################################################################################
+# END
+################################################################################
Index: stable/11/etc/mtree/BSD.usr.dist
===================================================================
--- stable/11/etc/mtree/BSD.usr.dist
+++ stable/11/etc/mtree/BSD.usr.dist
@@ -118,6 +118,8 @@
..
bsdinstall
..
+ dwatch
+ ..
hyperv
..
lpr
@@ -330,6 +332,8 @@
dma
..
drivers
+ ..
+ dwatch
..
etc
defaults
Index: stable/11/share/dtrace/Makefile
===================================================================
--- stable/11/share/dtrace/Makefile
+++ stable/11/share/dtrace/Makefile
@@ -17,10 +17,7 @@
tcpdebug \
tcpstate \
tcptrack \
- udptrack \
- watch_execve \
- watch_kill \
- watch_vop_remove
+ udptrack
SCRIPTSDIR= ${SHAREDIR}/dtrace
Index: stable/11/share/dtrace/watch_execve
===================================================================
--- stable/11/share/dtrace/watch_execve
+++ stable/11/share/dtrace/watch_execve
@@ -1,227 +0,0 @@
-#!/usr/sbin/dtrace -s
-/* -
- * Copyright (c) 2014 Devin Teske <dteske@FreeBSD.org>
- * All rights reserved.
- * 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.
- *
- * $Title: dtrace(1) script to log process(es) entering syscall::execve $
- * $FreeBSD$
- */
-
-#pragma D option quiet
-#pragma D option dynvarsize=16m
-#pragma D option switchrate=10hz
-
-/*********************************************************/
-
-syscall::execve:entry /* probe ID 1 */
-{
- this->caller_execname = execname;
-}
-
-/*********************************************************/
-
-syscall::execve:return /execname != this->caller_execname/ /* probe ID 2 */
-{
- /*
- * Examine process, parent process, and grandparent process details
- */
-
- /******************* CURPROC *******************/
-
- this->proc = curthread->td_proc;
- this->pid0 = this->proc->p_pid;
- this->uid0 = this->proc->p_ucred->cr_uid;
- this->gid0 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc->p_args;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg0_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* PPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid1 = this->proc->p_pid;
- this->uid1 = this->proc->p_ucred->cr_uid;
- this->gid1 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg1_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* GPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid2 = this->proc->p_pid;
- this->uid2 = this->proc->p_ucred->cr_uid;
- this->gid2 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg2_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* APARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid3 = this->proc->p_pid;
- this->uid3 = this->proc->p_ucred->cr_uid;
- this->gid3 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg3_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_4 = this->ar_length > 0 ? "..." : "";
-
- /***********************************************/
-
- /*
- * Print process, parent, and grandparent details
- */
-
- printf("%Y %s[%d]: ", timestamp + 1406598400000000000,
- this->caller_execname, this->pid1);
- printf("%s", this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("\n");
-
- printf(" -+= %05d %d.%d %s",
- this->pid3, this->uid3, this->gid3, this->arg3_0);
- printf("%s%s", this->arg3_1 != "" ? " " : "", this->arg3_1);
- printf("%s%s", this->arg3_2 != "" ? " " : "", this->arg3_2);
- printf("%s%s", this->arg3_3 != "" ? " " : "", this->arg3_3);
- printf("%s%s", this->arg3_4 != "" ? " " : "", this->arg3_4);
- printf("%s", this->arg3_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid2, this->uid2, this->gid2, this->arg2_0);
- printf("%s%s", this->arg2_1 != "" ? " " : "", this->arg2_1);
- printf("%s%s", this->arg2_2 != "" ? " " : "", this->arg2_2);
- printf("%s%s", this->arg2_3 != "" ? " " : "", this->arg2_3);
- printf("%s%s", this->arg2_4 != "" ? " " : "", this->arg2_4);
- printf("%s", this->arg2_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid1, this->uid1, this->gid1, this->arg1_0);
- printf("%s%s", this->arg1_1 != "" ? " " : "", this->arg1_1);
- printf("%s%s", this->arg1_2 != "" ? " " : "", this->arg1_2);
- printf("%s%s", this->arg1_3 != "" ? " " : "", this->arg1_3);
- printf("%s%s", this->arg1_4 != "" ? " " : "", this->arg1_4);
- printf("%s", this->arg1_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid0, this->uid0, this->gid0, this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("%s", this->arg0_0 != "" ? "\n" : "");
-}
Index: stable/11/share/dtrace/watch_kill
===================================================================
--- stable/11/share/dtrace/watch_kill
+++ stable/11/share/dtrace/watch_kill
@@ -1,232 +0,0 @@
-#!/usr/sbin/dtrace -s
-/* -
- * Copyright (c) 2014-2016 Devin Teske <dteske@FreeBSD.org>
- * All rights reserved.
- * 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.
- *
- * $Title: dtrace(1) script to log process(es) entering syscall::kill $
- * $FreeBSD$
- */
-
-#pragma D option quiet
-#pragma D option dynvarsize=16m
-#pragma D option switchrate=10hz
-
-/*********************************************************/
-
-syscall::execve:entry /* probe ID 1 */
-{
- this->caller_execname = execname;
-}
-
-/*********************************************************/
-
-syscall::kill:entry /* probe ID 2 */
-{
- this->pid_to_kill = (pid_t)arg0;
- this->kill_signal = (int)arg1;
-
- /*
- * Examine process, parent process, and grandparent process details
- */
-
- /******************* CURPROC *******************/
-
- this->proc = curthread->td_proc;
- this->pid0 = this->proc->p_pid;
- this->uid0 = this->proc->p_ucred->cr_uid;
- this->gid0 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc->p_args;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg0_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* PPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid1 = this->proc->p_pid;
- this->uid1 = this->proc->p_ucred->cr_uid;
- this->gid1 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg1_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* GPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid2 = this->proc->p_pid;
- this->uid2 = this->proc->p_ucred->cr_uid;
- this->gid2 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg2_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* APARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid3 = this->proc->p_pid;
- this->uid3 = this->proc->p_ucred->cr_uid;
- this->gid3 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg3_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg3_4 = this->ar_length > 0 ? "..." : "";
-
- /***********************************************/
-
- /*
- * Print process, parent, and grandparent details
- */
-
- printf("%Y %s[%d]: ", timestamp + 1406598400000000000,
- this->caller_execname, this->pid1);
- printf("%s", this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf(" (sending signal %u to pid %u)",
- this->kill_signal, this->pid_to_kill);
- printf("\n");
-
- printf(" -+= %05d %d.%d %s",
- this->pid3, this->uid3, this->gid3, this->arg3_0);
- printf("%s%s", this->arg3_1 != "" ? " " : "", this->arg3_1);
- printf("%s%s", this->arg3_2 != "" ? " " : "", this->arg3_2);
- printf("%s%s", this->arg3_3 != "" ? " " : "", this->arg3_3);
- printf("%s%s", this->arg3_4 != "" ? " " : "", this->arg3_4);
- printf("%s", this->arg3_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid2, this->uid2, this->gid2, this->arg2_0);
- printf("%s%s", this->arg2_1 != "" ? " " : "", this->arg2_1);
- printf("%s%s", this->arg2_2 != "" ? " " : "", this->arg2_2);
- printf("%s%s", this->arg2_3 != "" ? " " : "", this->arg2_3);
- printf("%s%s", this->arg2_4 != "" ? " " : "", this->arg2_4);
- printf("%s", this->arg2_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid1, this->uid1, this->gid1, this->arg1_0);
- printf("%s%s", this->arg1_1 != "" ? " " : "", this->arg1_1);
- printf("%s%s", this->arg1_2 != "" ? " " : "", this->arg1_2);
- printf("%s%s", this->arg1_3 != "" ? " " : "", this->arg1_3);
- printf("%s%s", this->arg1_4 != "" ? " " : "", this->arg1_4);
- printf("%s", this->arg1_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid0, this->uid0, this->gid0, this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("%s", this->arg0_0 != "" ? "\n" : "");
-}
Index: stable/11/share/dtrace/watch_vop_remove
===================================================================
--- stable/11/share/dtrace/watch_vop_remove
+++ stable/11/share/dtrace/watch_vop_remove
@@ -1,476 +0,0 @@
-#!/usr/sbin/dtrace -s
-/* -
- * Copyright (c) 2014 Devin Teske <dteske@FreeBSD.org>
- * All rights reserved.
- * 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.
- *
- * $Title: dtrace(1) script to log process(es) entering vfs::vop_remove $
- * $FreeBSD$
- */
-
-#pragma D option quiet
-#pragma D option dynvarsize=16m
-#pragma D option switchrate=10hz
-
-/*********************************************************/
-
-vfs::vop_remove:entry /* probe ID 1 */
-{
- this->vp = (struct vnode *)arg0;
- this->ncp = &(this->vp->v_cache_dst) != NULL ?
- this->vp->v_cache_dst.tqh_first : 0;
- this->fi_name = args[1] ? (
- args[1]->a_cnp != NULL ?
- stringof(args[1]->a_cnp->cn_nameptr) : ""
- ) : "";
- this->mount = this->vp->v_mount; /* ptr to vfs we are in */
- this->fi_fs = this->mount != 0 ?
- stringof(this->mount->mnt_stat.f_fstypename) : "";
- this->fi_mount = this->mount != 0 ?
- stringof(this->mount->mnt_stat.f_mntonname) : "";
- this->d_name = args[0]->v_cache_dd != NULL ?
- stringof(args[0]->v_cache_dd->nc_name) : "";
-}
-
-vfs::vop_remove:entry /this->vp == 0 || this->fi_fs == 0 ||
- this->fi_fs == "devfs" || this->fi_fs == "" ||
- this->fi_name == ""/ /* probe ID 2 */
-{
- this->ncp = 0;
-}
-
-/*********************************************************/
-
-vfs::vop_remove:entry /this->ncp/ /* probe ID 3 (depth 1) */
-{
- this->dvp = this->ncp->nc_dvp != NULL ? (
- &(this->ncp->nc_dvp->v_cache_dst) != NULL ?
- this->ncp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name1 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->name1 == 0 || this->fi_fs == 0 ||
- this->fi_fs == "devfs" || this->fi_fs == "" ||
- this->name1 == "/" || this->name1 == ""/ /* probe ID 4 */
-{
- this->dvp = 0;
-}
-
-/*********************************************************/
-
-/*
- * BEGIN Pathname-depth iterators (copy/paste as many times as-desired)
- */
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 5 (depth 2) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name2 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 6 (depth 3) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name3 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 7 (depth 4) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name4 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 8 (depth 5) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name5 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 9 (depth 6) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name6 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 10 (depth 7) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name7 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 11 (depth 8) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name8 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 12 (depth 9) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name9 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 13 (depth 10) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name10 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 14 (depth 11) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name11 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 15 (depth 12) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name12 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 16 (depth 13) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name13 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 17 (depth 14) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name14 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 18 (depth 15) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name15 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 19 (depth 16) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name16 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 20 (depth 17) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name17 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 21 (depth 18) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name18 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 22 (depth 19) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name19 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-vfs::vop_remove:entry /this->dvp/ /* probe ID 23 (depth 20) */
-{
- this->dvp = this->dvp->nc_dvp != NULL ? (
- &(this->dvp->nc_dvp->v_cache_dst) != NULL ?
- this->dvp->nc_dvp->v_cache_dst.tqh_first : 0
- ) : 0;
- this->name20 = this->dvp != 0 ? (
- this->dvp->nc_name != 0 ? stringof(this->dvp->nc_name) : ""
- ) : "";
-}
-
-/*
- * END Pathname-depth iterators
- */
-
-/*********************************************************/
-
-vfs::vop_remove:entry /this->fi_mount != 0/ /* probe ID 24 */
-{
- printf("%Y %s[%d]: ", timestamp + 1406598400000000000, execname, pid);
-
- /*
- * Print full path of file to delete
- * NB: Up-to but not including the parent directory (printed below)
- */
- printf("%s%s", this->fi_mount, this->fi_mount != 0 ? (
- this->fi_mount == "/" ? "" : "/"
- ) : "/");
- printf("%s%s", this->name = this->name20, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name19, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name18, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name17, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name16, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name15, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name14, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name13, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name12, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name11, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name10, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name9, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name8, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name7, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name6, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name5, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name4, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name3, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name2, this->name != "" ? "/" : "");
- printf("%s%s", this->name = this->name1, this->name != "" ? "/" : "");
-
- /* Print the parent directory name */
- this->name = this->d_name != 0 ? this->d_name : "";
- printf("%s%s", this->name, this->name != "" ? "/" : "");
-
- /* Print the entry name */
- this->name = this->fi_name != 0 ? this->fi_name : "";
- printf("%s", this->name);
-
- printf("\n");
-
- /*
- * Examine process, parent process, and grandparent process details
- */
-
- /******************* CURPROC *******************/
-
- this->proc = curthread->td_proc;
- this->pid0 = this->proc->p_pid;
- this->uid0 = this->proc->p_ucred->cr_uid;
- this->gid0 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc->p_args;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg0_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg0_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* PPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid1 = this->proc->p_pid;
- this->uid1 = this->proc->p_ucred->cr_uid;
- this->gid1 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg1_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg1_4 = this->ar_length > 0 ? "..." : "";
-
- /******************* GPARENT *******************/
-
- this->proc = this->proc->p_pptr;
- this->pid2 = this->proc->p_pid;
- this->uid2 = this->proc->p_ucred->cr_uid;
- this->gid2 = this->proc->p_ucred->cr_rgid;
- this->p_args = this->proc ? this->proc->p_args : 0;
- this->ar_length = this->p_args ? this->p_args->ar_length : 0;
- this->ar_args = (char *)(this->p_args ? this->p_args->ar_args : 0);
-
- this->arg2_0 = this->ar_length > 0 ?
- this->ar_args : stringof(this->proc->p_comm);
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_1 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_2 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_3 = this->ar_length > 0 ? this->ar_args : "";
- this->len = this->ar_length > 0 ? strlen(this->ar_args) + 1 : 0;
- this->ar_args += this->len;
- this->ar_length -= this->len;
-
- this->arg2_4 = this->ar_length > 0 ? "..." : "";
-
- /***********************************************/
-
- /*
- * Print process, parent, and grandparent details
- */
-
- printf(" -+= %05d %d.%d %s",
- this->pid2, this->uid2, this->gid2, this->arg2_0);
- printf("%s%s", this->arg2_1 != "" ? " " : "", this->arg2_1);
- printf("%s%s", this->arg2_2 != "" ? " " : "", this->arg2_2);
- printf("%s%s", this->arg2_3 != "" ? " " : "", this->arg2_3);
- printf("%s%s", this->arg2_4 != "" ? " " : "", this->arg2_4);
- printf("%s", this->arg2_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid1, this->uid1, this->gid1, this->arg1_0);
- printf("%s%s", this->arg1_1 != "" ? " " : "", this->arg1_1);
- printf("%s%s", this->arg1_2 != "" ? " " : "", this->arg1_2);
- printf("%s%s", this->arg1_3 != "" ? " " : "", this->arg1_3);
- printf("%s%s", this->arg1_4 != "" ? " " : "", this->arg1_4);
- printf("%s", this->arg1_0 != "" ? "\n" : "");
-
- printf(" \-+= %05d %d.%d %s",
- this->pid0, this->uid0, this->gid0, this->arg0_0);
- printf("%s%s", this->arg0_1 != "" ? " " : "", this->arg0_1);
- printf("%s%s", this->arg0_2 != "" ? " " : "", this->arg0_2);
- printf("%s%s", this->arg0_3 != "" ? " " : "", this->arg0_3);
- printf("%s%s", this->arg0_4 != "" ? " " : "", this->arg0_4);
- printf("%s", this->arg0_0 != "" ? "\n" : "");
-}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 22, 5:15 AM (19 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28932774
Default Alt Text
D15418.id42555.diff (190 KB)
Attached To
Mode
D15418: MFC DTrace Enhancements and dwatch(1)
Attached
Detach File
Event Timeline
Log In to Comment