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)); }
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; }
/* * 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; }
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"); }