예제 #1
0
int
dtrace_go(dtrace_hdl_t *dtp)
{
	dtrace_enable_io_t args;
	void *dof;
	int error, r;

	if (dtp->dt_active)
		return (dt_set_errno(dtp, EINVAL));

	/*
	 * If a dtrace:::ERROR program and callback are registered, enable the
	 * program before we start tracing.  If this fails for a vector open
	 * with ENOTTY, we permit dtrace_go() to succeed so that vector clients
	 * such as mdb's dtrace module can execute the rest of dtrace_go() even
	 * though they do not provide support for the DTRACEIOC_ENABLE ioctl.
	 */
	if (dtp->dt_errprog != NULL &&
	    dtrace_program_exec(dtp, dtp->dt_errprog, NULL) == -1 && (
	    dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL))
		return (-1); /* dt_errno has been set for us */

	if ((dof = dtrace_getopt_dof(dtp)) == NULL)
		return (-1); /* dt_errno has been set for us */

	args.dof = dof;
	args.n_matched = 0;
	r = dt_ioctl(dtp, DTRACEIOC_ENABLE, &args);
	error = errno;
	dtrace_dof_destroy(dtp, dof);

	if (r == -1 && (error != ENOTTY || dtp->dt_vector == NULL))
		return (dt_set_errno(dtp, error));

	if (dt_ioctl(dtp, DTRACEIOC_GO, &dtp->dt_beganon) == -1) {
		if (errno == EACCES)
			return (dt_set_errno(dtp, EDT_DESTRUCTIVE));

		if (errno == EALREADY)
			return (dt_set_errno(dtp, EDT_ISANON));

		if (errno == ENOENT)
			return (dt_set_errno(dtp, EDT_NOANON));

		if (errno == E2BIG)
			return (dt_set_errno(dtp, EDT_ENDTOOBIG));

		if (errno == ENOSPC)
			return (dt_set_errno(dtp, EDT_BUFTOOSMALL));

		return (dt_set_errno(dtp, errno));
	}

	dtp->dt_active = 1;

	if (dt_options_load(dtp) == -1)
		return (dt_set_errno(dtp, errno));

	return (dt_aggregate_go(dtp));
}
예제 #2
0
int main( void ) {
    int err;
    dtrace_hdl_t * dh = dtrace_open(DTRACE_VERSION, 0, &err);
    
    if (dh == NULL) {
        printf("Cannot open dtrace library: %s\n", dtrace_errmsg(dh, err));
        return -1;
    }
    
    // Set a few necessary options
    dtrace_setopt(dh, "strsize", "4096");
    dtrace_setopt(dh, "bufsize", "4m");
    
    // Compile my program
    const char * script = "syscall::*exit*:entry { printf(\"%s %d\\n\", execname, curpsinfo->pr_pid); }";
    dtrace_prog_t *prog = dtrace_program_strcompile(dh, script, DTRACE_PROBESPEC_NAME, 0, 0, NULL);
    if( prog == NULL ) {
        printf("Cannot compile program: %s\n", dtrace_errmsg(dh, err));
        return -1;
    }
    
    // Add buffered output handler, as this is the only way I can get data out of Dtrace?
    if (dtrace_handle_buffered(dh, dtrace_dcmdbuffered, NULL) == -1) {
        printf("Couldn't add buffered handler");
        return -1;
    }

    dtrace_proginfo_t info;
    if( dtrace_program_exec(dh, prog, &info) == -1 ) {
        printf("Cannot exec program: %s\n", dtrace_errmsg(dh, err));
        return -1;
    }
    
    if( dtrace_go(dh) == -1 ) {
        printf("Cannot go: %s\n", dtrace_errmsg(NULL, err));
        return -1;
    }
    
    while(1) {
        dtrace_sleep(dh);
        switch (dtrace_work(dh, NULL, chew, chewrec, NULL)) {
            case DTRACE_WORKSTATUS_DONE:
                if (dtrace_stop(dh) == -1)
                    printf("couldn't stop tracing");
                break;
                break;
            case DTRACE_WORKSTATUS_OKAY:
                break;
            case DTRACE_WORKSTATUS_ERROR:
                printf("WARNING: DTRACE_WORKSTATUS_ERROR!\n");
                break;
            default:
                printf("Unknown return value from dtrace_work()\n");
        }
    }
    
    dtrace_close(dh);
    return 0;
}
예제 #3
0
파일: dtrace.c 프로젝트: 0xbda2d2f8/freebsd
/*
 * Execute the specified program by enabling the corresponding instrumentation.
 * If -e has been specified, we get the program info but do not enable it.  If
 * -v has been specified, we print a stability report for the program.
 */
static void
exec_prog(const dtrace_cmd_t *dcp)
{
	dtrace_ecbdesc_t *last = NULL;
	dtrace_proginfo_t dpi;

	if (!g_exec) {
		dtrace_program_info(g_dtp, dcp->dc_prog, &dpi);
	} else if (dtrace_program_exec(g_dtp, dcp->dc_prog, &dpi) == -1) {
		dfatal("failed to enable '%s'", dcp->dc_name);
	} else {
		notice("%s '%s' matched %u probe%s\n",
		    dcp->dc_desc, dcp->dc_name,
		    dpi.dpi_matches, dpi.dpi_matches == 1 ? "" : "s");
	}

	if (g_verbose) {
		oprintf("\nStability attributes for %s %s:\n",
		    dcp->dc_desc, dcp->dc_name);

		oprintf("\n\tMinimum Probe Description Attributes\n");
		oprintf("\t\tIdentifier Names: %s\n",
		    dtrace_stability_name(dpi.dpi_descattr.dtat_name));
		oprintf("\t\tData Semantics:   %s\n",
		    dtrace_stability_name(dpi.dpi_descattr.dtat_data));
		oprintf("\t\tDependency Class: %s\n",
		    dtrace_class_name(dpi.dpi_descattr.dtat_class));

		oprintf("\n\tMinimum Statement Attributes\n");

		oprintf("\t\tIdentifier Names: %s\n",
		    dtrace_stability_name(dpi.dpi_stmtattr.dtat_name));
		oprintf("\t\tData Semantics:   %s\n",
		    dtrace_stability_name(dpi.dpi_stmtattr.dtat_data));
		oprintf("\t\tDependency Class: %s\n",
		    dtrace_class_name(dpi.dpi_stmtattr.dtat_class));

		if (!g_exec) {
			(void) dtrace_stmt_iter(g_dtp, dcp->dc_prog,
			    (dtrace_stmt_f *)info_stmt, &last);
		} else
			oprintf("\n");
	}

	g_total += dpi.dpi_matches;
}
예제 #4
0
static void
dprog_compile(void)
{
	dtrace_prog_t *prog;
	dtrace_proginfo_t info;

	if (g_opt_V) {
		(void) fprintf(stderr, "%s: vvvv D program vvvv\n", g_pname);
		(void) fputs(g_prog, stderr);
		(void) fprintf(stderr, "%s: ^^^^ D program ^^^^\n", g_pname);
	}

	if ((prog = dtrace_program_strcompile(g_dtp, g_prog,
	    DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL)
		dfatal("failed to compile program");

	if (dtrace_program_exec(g_dtp, prog, &info) == -1)
		dfatal("failed to enable probes");
}