14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * CDDL HEADER START
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * The contents of this file are subject to the terms of the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Common Development and Distribution License (the "License").
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * You may not use this file except in compliance with the License.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * See the License for the specific language governing permissions
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * and limitations under the License.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * When distributing Covered Code, include this CDDL HEADER in each
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If applicable, add the following below this CDDL HEADER, with the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * fields enclosed by brackets "[]" replaced with your own identifying
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * information: Portions Copyright [yyyy] [name of copyright owner]
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * CDDL HEADER END
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Use is subject to license terms.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#pragma ident "%Z%%M% %I% %E% SMI"
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync# pragma warning(disable:4267) /* size_t conversion warnings */
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync# pragma warning(disable:4018) /* signed/unsigned mismatch */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync void (*dc_func)(struct dtrace_cmd *); /* function to compile arg */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_probespec_t dc_spec; /* probe specifier context */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_prog_t *dc_prog; /* program compiled from arg */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync char dc_ofile[PATH_MAX]; /* derived output file name */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define DMODE_VERS 0 /* display version information and exit (-V) */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define DMODE_EXEC 1 /* compile program for enabling (-a/e/E) */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define DMODE_ANON 2 /* compile program for anonymous tracing (-A) */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define DMODE_LINK 3 /* compile program for linking with ELF (-G) */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define DMODE_LIST 4 /* compile program and list probes (-l) */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync#define DMODE_HEADER 5 /* compile program for headergen (-h) */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "3:6:aAb:Bc:CD:ef:FGhHi:I:lL:m:n:o:p:P:qs:SU:vVwx:X:Z";
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync#endif /* VBOX */
e3c0207b236896a903ef328bfa74ee97e61bd38bvboxsync#ifndef VBOX /* stdout isn't a necessarily constant usable like this in C code. */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic const char *g_etcbegin = "* vvvv Added by DTrace";
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic const char *g_etcend = "* ^^^^ Added by DTrace";
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync"* The following forceload directives were added by dtrace(1M) to allow for",
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync"* tracing during boot. If these directives are removed, the system will",
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync"* continue to function, but tracing will not occur during boot as desired.",
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync"* To remove these directives (and this block comment) automatically, run",
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync"* \"dtrace -A\" without additional arguments. See the \"Anonymous Tracing\"",
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync"* chapter of the Solaris Dynamic Tracing Guide for details.",
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync static const char predact[] = "[[ predicate ] action ]";
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(fp, "Usage: %s [-32|-64] [-aACeFGhHlqSvVwZ] "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "[-b bufsz] [-c cmd] [-D name[=def]]\n\t[-I path] [-L path] "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "[-o output] [-p pid] [-s script] [-U name]\n\t"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "[-x opt[=val]] [-X a|c|s|t]\n\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t[-P provider %s]\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t[-m [ provider: ] module %s]\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t[-f [[ provider: ] module: ] func %s]\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t[-n [[[ provider: ] module: ] func: ] name %s]\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(fp, "\tpredicate -> '/' D-expression '/'\n");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(fp, "\t action -> '{' D-statements '}'\n");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-32 generate 32-bit D programs and ELF files\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-64 generate 64-bit D programs and ELF files\n\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-a claim anonymous tracing state\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-A generate driver.conf(4) directives for anonymous tracing\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-b set trace buffer size\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-c run specified command and exit upon its completion\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-C run cpp(1) preprocessor on script files\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-D define symbol when invoking preprocessor\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-e exit after compiling request but prior to enabling probes\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-f enable or list probes matching the specified function name\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-F coalesce trace output by function\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-G generate an ELF file containing embedded dtrace program\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-h generate a header file with definitions for static probes\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-H print included files when invoking preprocessor\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-i enable or list probes matching the specified probe id\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-I add include directory to preprocessor search path\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-l list probes matching specified criteria\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-L add library directory to library search path\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-m enable or list probes matching the specified module name\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-n enable or list probes matching the specified probe name\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-o set output file\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-p grab specified process-ID and cache its symbol tables\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-P enable or list probes matching the specified provider name\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-q set quiet mode (only output explicitly traced data)\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-s enable or list probes according to the specified D script\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-S print D compiler intermediate code\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-U undefine symbol when invoking preprocessor\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-v set verbose mode (report stability attributes, arguments)\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-V report DTrace API version\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-w permit destructive actions\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-x enable or modify compiler and tracing options\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-X specify ISO C conformance settings for preprocessor\n"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "\t-Z permit probe descriptions that match zero probes\n");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*PRINTFLIKE1*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*PRINTFLIKE1*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Close the DTrace handle to ensure that any controlled processes are
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * correctly restored and continued.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*PRINTFLIKE1*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*PRINTFLIKE1*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return; /* -q or quiet pragma suppresses notice()s */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*PRINTFLIKE1*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (n < 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncstatic char **
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync char **argv = malloc(sizeof (char *) * (strlen(s) / 2 + 1));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync char *p = s;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (p = strtok(s, ws); p != NULL; p = strtok(NULL, ws))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * This is okay only if the file doesn't exist at all.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((buf = malloc((sz = sbuf.st_size) + 1)) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * This is only a match if it's in the 0th column.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (msg++ == 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * We have a match. First write out our data up until now.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (i != mark) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Now scan forward until we scan past a newline.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Reset our mark.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((buf = malloc((sz = sbuf.st_size) + 1)) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("embedded nul byte in %s; manual repair of %s "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("multiple start sentinels in %s; manual repair of %s "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("missing end sentinel in %s; manual repair of %s "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("end sentinel preceeds start sentinel in %s; manual "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) snprintf(tmpname, sz, "%s.dtrace.%d", fname, getpid());
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (chown(tmpname, sbuf.st_uid, sbuf.st_gid) != 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("failed to chown(2) %s to uid %d, gid %d", tmpname,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("rename of %s to %s failed", tmpname, fname);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync error("cleaned up forceload directives in %s\n", fname);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((g_ofp = fopen(g_ofile = g_etcfile, "a")) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("failed to close output file '%s'", g_ofile);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync error("added forceload directives to %s\n", g_ofile);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < p->dtp_argc; i++) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync p->dtp_argv[i].dtt_type, buf, sizeof (buf)) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (p->dtp_argc == 0)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync pdp->dtpd_provider, pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Execute the specified program by enabling the corresponding instrumentation.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If -e has been specified, we get the program info but do not enable it. If
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * -v has been specified, we print a stability report for the program.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } else if (dtrace_program_exec(g_dtp, dcp->dc_prog, &dpi) == -1) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync oprintf("\n\tMinimum Probe Description Attributes\n");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_stability_name(dpi.dpi_descattr.dtat_name));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_stability_name(dpi.dpi_descattr.dtat_data));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_stability_name(dpi.dpi_stmtattr.dtat_name));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_stability_name(dpi.dpi_stmtattr.dtat_data));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Print out the specified DOF buffer as a set of ASCII bytes appropriate for
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * storing in a driver.conf(4) file associated with the dtrace driver.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncanon_prog(const dtrace_cmd_t *dcp, dof_hdr_t *dof, int n)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync const uchar_t *p, *q;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dfatal("failed to create DOF image for '%s'", dcp->dc_name);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync while (p < q)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Link the specified D program in DOF form into an ELF file for use in either
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * helpers, userland provider definitions, or both. If -o was specified, that
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * path is used as the output file name. If -o wasn't specified and the input
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * program is from a script whose name is %.d, use basename(%.o) as the output
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * file name. Otherwise we use "d.out" as the default output file name.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) strlcpy(dcp->dc_ofile, g_ofile, sizeof (dcp->dc_ofile));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } else if ((p = strrchr(dcp->dc_arg, '.')) != NULL &&
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) snprintf(dcp->dc_ofile, sizeof (dcp->dc_ofile),
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) snprintf(dcp->dc_ofile, sizeof (dcp->dc_ofile),
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync g_cmdc > 1 ? "%s.%d" : "%s", "d.out", (int)(dcp - g_cmdv));
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_program_link(g_dtp, dcp->dc_prog, DTRACE_D_PROBES,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dfatal("failed to link %s %s", dcp->dc_desc, dcp->dc_name);
e3c0207b236896a903ef328bfa74ee97e61bd38bvboxsync#endif /* !VBOX */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsynclist_probe(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *arg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync pdp->dtpd_provider, pdp->dtpd_mod, pdp->dtpd_func, pdp->dtpd_name);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (g_verbose && dtrace_probe_info(dtp, pdp, &p) == 0)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_probe_iter(g_dtp, &edp->dted_probe, list_probe, NULL) != 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync edp->dted_probe.dtpd_provider, edp->dted_probe.dtpd_mod,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync edp->dted_probe.dtpd_func, edp->dted_probe.dtpd_name,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * List the probes corresponding to the specified program by iterating over
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * each statement and then matching probes to the statement probe descriptions.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((dcp->dc_prog = dtrace_program_fcompile(g_dtp, fp,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dfatal("failed to compile script %s", dcp->dc_arg);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((dcp->dc_prog = dtrace_program_strcompile(g_dtp, dcp->dc_arg,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dcp->dc_spec, g_cflags | DTRACE_C_PSPEC, g_argc, g_argv)) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncprochandler(struct ps_prochandle *P, const char *msg, void *arg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (Pstate(P)) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Ideally we would like to always report pr_wstat here, but it
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * isn't possible given current /proc semantics. If we grabbed
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * the process, Ppsinfo() will either fail or return a zeroed
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * psinfo_t depending on how far the parent is in reaping it.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * When /proc provides a stable pr_wstat in the status file,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * this code can be improved by examining this new pr_wstat.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync notice("pid %d exec'd a set-id or unobservable program\n", pid);
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync#endif /* !VBOX */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncdrophandler(const dtrace_dropdata_t *data, void *arg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncsetopthandler(const dtrace_setoptdata_t *data, void *arg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync g_flowindent = data->dtsda_newval != DTRACEOPT_UNSET;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) printf("%s: %s%s\n", g_pname, hdr, strlen(hdr) > 0 ? ":" : "");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (*c == '\n') { \
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync continue; \
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } while (*c++ != '\0'); \
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) printf("%s: %20s => %s\n", g_pname, #field, str);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) printf("%s: %20s => %lld\n", g_pname, #field, \
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) printf("%s: %20s => %s\n", g_pname, #field, \
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncbufhandler(const dtrace_bufdata_t *bufdata, void *arg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync const dtrace_aggdata_t *agg = bufdata->dtbda_aggdata;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync const dtrace_recdesc_t *rec = bufdata->dtbda_recdesc;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) snprintf(c, end - c, "0x%x ", bufdata->dtbda_flags);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0, printed = 0; flagnames[i].name != NULL; i++) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "%s%s", printed++ ? " | " : "(", flagnames[i].name);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) sprintf(buf, "%d (data: ", rec->dtrd_offset);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync data = (uint8_t *)agg->dtada_data + rec->dtrd_offset;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < lim; i++) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsyncchewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * We have processed the final record; output the newline if
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * we're not in quiet mode.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync char name[DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 2];
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync len = indent + DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 5;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) snprintf(name, len, "%*s%s%s:%s", indent, "",
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_getopt(g_dtp, bufs[i].optname, &bufs[i].val) == -1)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_getopt(g_dtp, rates[i].optname, &rates[i].val) == -1)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) dtrace_getopt(g_dtp, bufs[i].optname, &nsize);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (; (INT64_C(1) << mul) <= nsize; j++, mul += 10)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (long long)nsize);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) dtrace_getopt(g_dtp, rates[i].optname, &nval);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dir = nval > rates[i].val ? "reduced" : "increased";
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync/*ARGSUSED*/
57a7aeb014cdd1900c8bfecb0f9dcc7b96a61cc9vboxsyncDECLEXPORT(int) RTCALL VBoxDTraceMain(int argc, char **argv)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync char c, *p, **v;
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((g_argv = malloc(sizeof (char *) * argc)) == NULL ||
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (g_cmdv = malloc(sizeof (dtrace_cmd_t) * argc)) == NULL ||
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (g_psv = malloc(sizeof (struct ps_prochandle *) * argc)) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync g_argv[g_argc++] = argv[0]; /* propagate argv[0] to D as $0/$$0 */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync argv[0] = g_pname; /* rewrite argv[0] for getopt errors */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Make an initial pass through argv[] processing any arguments that
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * affect our behavior mode (g_mode) and flags used for dtrace_open().
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * We also accumulate arguments that are not affiliated with getopt
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * options into g_argv[], and abort if any invalid options are found.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != EOF) {
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, 0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (c) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "%s: illegal option -- 3%s\n",
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync case 10032:
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "%s: illegal option -- 6%s\n",
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync case 10064:
dfd08267d2958ae1cd559dd7dc2f36bf5461648dvboxsync fprintf(stderr, "%s: -%c is not supported\n", g_pname, c);
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync if (c < 0) { /* Note: Not all options are handled. */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(stderr, "%s: only one of the [-AGhlV] options "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync return (printf("%s: %s\n", g_pname, _dtrace_version) <= 0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If we're in linker mode and the data model hasn't been specified,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * we try to guess the appropriate setting by examining the object
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * files. We ignore certain errors since we'll catch them later when
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * we actually process the object files.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (g_oflags & (DTRACE_O_ILP32 | DTRACE_O_LP64)) == 0 &&
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "object files\n");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "object files\n");
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync#endif /* !VBOX */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Open libdtrace. If we are not actually going to be enabling any
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * instrumentation attempt to reopen libdtrace using DTRACE_O_NODEV.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync while ((g_dtp = dtrace_open(DTRACE_VERSION, g_oflags, &err)) == NULL) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (!(g_oflags & DTRACE_O_NODEV) && !g_exec && !g_grabanon) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If -G is specified, enable -xlink=dynamic and -xunodefs to permit
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * references to undefined symbols to remain as unresolved relocations.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If -A is specified, enable -xlink=primary to permit static linking
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * only to kernel symbols that are defined in a primary kernel module.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) dtrace_setopt(g_dtp, "linkmode", "dynamic");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Use the remaining arguments as the list of object files
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * when in linker mode.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * We still use g_argv[0], the name of the executable.
e3c0207b236896a903ef328bfa74ee97e61bd38bvboxsync#else /* VBOX */
e3c0207b236896a903ef328bfa74ee97e61bd38bvboxsync#endif /* VBOX */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) dtrace_setopt(g_dtp, "linkmode", "primary");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Now that we have libdtrace open, make a second pass through argv[]
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * to perform any dtrace_setopt() calls and change any compiler flags.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * We also accumulate any program specifications into our g_cmdv[] at
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * this time; these will compiled as part of the fourth processing pass.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != EOF) {
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, 0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (c) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync *p++ = '\0';
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync if (c < 0) { /* Note: Not all options are handled. */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(stderr, "%s: -B not valid in combination"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(stderr, "%s: -B not valid in combination"
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * In our third pass we handle any command-line options related to
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * grabbing or creating victim processes. The behavior of these calls
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * may been affected by any library options set by the second pass.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != EOF) {
ed2a9def43e38be9ed1ee10cdc35307de992a165vboxsync RTGetOptInit(&GetState, argc, argv, g_aOptions, RT_ELEMENTS(g_aOptions), 1, 0);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (c) {
dfd08267d2958ae1cd559dd7dc2f36bf5461648dvboxsync#endif /* !VBOX */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * In our fourth pass we finish g_cmdv[] by calling dc_func to convert
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * each string or file specification into a compiled program structure.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < g_cmdc; i++)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_handle_err(g_dtp, &errhandler, NULL) == -1)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_handle_drop(g_dtp, &drophandler, NULL) == -1)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_handle_setopt(g_dtp, &setopthandler, NULL) == -1)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_handle_buffered(g_dtp, &bufhandler, NULL) == -1)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Now make a fifth and final pass over the options that have been
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * turned into programs and saved in g_cmdv[], performing any mode-
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * specific processing. If g_mode is DMODE_EXEC, we will break out
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * of the switch() and continue on to the data processing loop. For
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * other modes, we will exit dtrace once mode-specific work is done.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (g_ofile != NULL && (g_ofp = fopen(g_ofile, "a")) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < g_cmdc; i++)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dof_prune(g_ofile); /* strip out any old DOF directives */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync etcsystem_prune(); /* string out any forceload directives */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < g_cmdc; i++) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dtrace_dof_create(g_dtp, g_cmdv[i].dc_prog, 0), i);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Dump out the DOF corresponding to the error handler and the
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * current options as the final DOF property in the .conf file.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync fatal("failed to close output file '%s'", g_ofile);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * These messages would use notice() rather than error(), but
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * we don't want them suppressed when -A is run on a D program
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * that itself contains a #pragma D option quiet.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync error("saved anonymous enabling in %s\n", g_ofile);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync error("run update_drv(1M) or reboot to enable changes\n");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(stderr, "%s: -G requires one or more "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < g_cmdc; i++)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < g_cmdc; i++)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_program_link(g_dtp, NULL, DTRACE_D_PROBES,
e3c0207b236896a903ef328bfa74ee97e61bd38bvboxsync#else /* VBOX */
e3c0207b236896a903ef328bfa74ee97e61bd38bvboxsync#endif /* VBOX */
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (g_ofile != NULL && (g_ofp = fopen(g_ofile, "a")) == NULL)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < g_cmdc; i++)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) dtrace_probe_iter(g_dtp, NULL, list_probe, NULL);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync (void) fprintf(stderr, "%s: -h requires one or more "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "output file if multiple scripts are "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if ((p = strrchr(g_cmdv[0].dc_arg, '.')) == NULL ||
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync "output file if no scripts are "
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync oprintf("/*\n * Generated by dtrace(1M).\n */\n\n");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (dtrace_program_header(g_dtp, g_ofp, g_ofile) != 0 ||
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dfatal("failed to create header file %s", g_ofile);
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * If -a and -Z were not specified and no probes have been matched, no
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * probe criteria was specified on the command line and we abort.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (g_total == 0 && !g_grabanon && !(g_cflags & DTRACE_C_ZDEFS))
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync dfatal("no probes %s\n", g_cmdc ? "matched" : "specified");
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Start tracing. Once we dtrace_go(), reload any options that affect
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * our globals in case consuming anonymous state has changed them.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (sigaction(SIGINT, NULL, &oact) == 0 && oact.sa_handler != SIG_IGN)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (sigaction(SIGTERM, NULL, &oact) == 0 && oact.sa_handler != SIG_IGN)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Now that tracing is active and we are ready to consume trace data,
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * continue any grabbed or created processes, setting them running
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * using the /proc control mechanism inside of libdtrace.
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync for (i = 0; i < g_psc; i++)
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * Output a newline just to make the output look
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * slightly cleaner. Note that we do this even in
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync * "quiet" mode...
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync if (done || g_intr || (g_psc != 0 && g_pslive == 0)) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync switch (dtrace_work(g_dtp, g_ofp, chew, chewrec, NULL)) {
14ea49401f3c8c61422aefbda43809e275f60c6cvboxsync } while (!done);