static VALUE load_ustack_helper(VALUE klass, VALUE path) { dtrace_hdl_t *dtp; dtrace_prog_t *helper; int err; void *dof; int argc = 1; char *argv[1] = { "ruby" }; printf("c land: I am trying to load %s", RSTRING_PTR(path)); puts(""); FILE *fp = fopen(RSTRING_PTR(path), "r"); if (fp == NULL) { rb_raise(rb_eFatal, "failed to open '%s', errno %d: %s", path, errno, strerror(errno)); } dtp = dtrace_open(DTRACE_VERSION, DTRACE_O_NODEV, &err); if (dtp == NULL) { dtrace_close(dtp); rb_raise(rb_eFatal, "dtrace_open failed: %s", dtrace_errmsg(dtp, err)); } (void) dtrace_setopt(dtp, "linkmode", "dynamic"); (void) dtrace_setopt(dtp, "unodefs", NULL); if ((helper = dtrace_program_fcompile(dtp, fp, DTRACE_C_ZDEFS, argc, argv)) == NULL) { dtrace_close(dtp); rb_raise(rb_eFatal, "compile failed: errno %d: %s", dtrace_errno(dtp), dtrace_errmsg(dtp, dtrace_errno(dtp))); } (void) fclose(fp); if ((dof = dtrace_dof_create(dtp, helper, 0)) == NULL) { dtrace_close(dtp); rb_raise(rb_eFatal, "DOF create failed: %s", dtrace_errmsg(dtp, dtrace_errno(dtp))); } if (load_dof(dof) != 0) { dtrace_close(dtp); rb_raise(rb_eFatal, "DOF load failed: %s", strerror(err)); } dtrace_close(dtp); return Qnil; }
NTSTATUS DtraceClose(PDEVICE_OBJECT DevObj, PIRP Irp) { PIO_STACK_LOCATION Pio; dtrace_state_t *state; Pio = IoGetCurrentIrpStackLocation(Irp); state = Pio->FileObject->FsContext; if (state != NULL) dtrace_close(state); if (InterlockedDecrement(&dtrace_ref) == 0) { free_thread_list(); free_proc_exiting(); } #if defined(__amd64__) winos_free_user_modules(); #endif ExFreePoolWithTag(Pio->FileObject->FsContext, 'Tag1'); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
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; }
/*PRINTFLIKE1*/ static void fatal(const char *fmt, ...) { va_list ap; va_start(ap, fmt); verror(fmt, ap); va_end(ap); /* * Close the DTrace handle to ensure that any controlled processes are * correctly restored and continued. */ if (g_dtp) dtrace_close(g_dtp); exit(E_ERROR); }
static int find_probes(probefilter_t *filter) { int err, rc; int flags = 0; err = 0; /* get dtrace handle */ dtrace_hdl_t *dh = dtrace_open(DTRACE_VERSION, flags, &err); if (err) { fprintf(stderr, "%s: %s\n", strerror(errno), dtrace_errmsg(dh, err)); return err; } /* start iteration, results go to callback above */ rc = dtrace_probe_iter(dh, NULL, probeinfo, filter); dtrace_close(dh); return rc; }
/*PRINTFLIKE1*/ static void dfatal(const char *fmt, ...) { #if !defined(sun) && defined(NEED_ERRLOC) char *p_errfile = NULL; int errline = 0; #endif va_list ap; va_start(ap, fmt); (void) fprintf(stderr, "%s: ", g_pname); if (fmt != NULL) (void) vfprintf(stderr, fmt, ap); va_end(ap); if (fmt != NULL && fmt[strlen(fmt) - 1] != '\n') { (void) fprintf(stderr, ": %s\n", dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); } else if (fmt == NULL) { (void) fprintf(stderr, "%s\n", dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); } #if !defined(sun) && defined(NEED_ERRLOC) dt_get_errloc(g_dtp, &p_errfile, &errline); if (p_errfile != NULL) printf("File '%s', line %d\n", p_errfile, errline); #endif /* * Close the DTrace handle to ensure that any controlled processes are * correctly restored and continued. */ dtrace_close(g_dtp); exit(E_ERROR); }
int main(int argc, char *argv[]) { dtrace_probedesc_t pd, *pdp = NULL; dtrace_hdl_t *dtp; int err, c; char *p; g_progname = argv[0]; if ((dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) { (void) fprintf(stderr, "%s: failed to open dtrace: %s\n", g_progname, dtrace_errmsg(dtp, err)); return (1); } while ((c = getopt(argc, argv, "evx:")) != -1) { switch (c) { case 'e': g_errexit++; break; case 'v': g_verbose++; break; case 'x': if ((p = strchr(optarg, '=')) != NULL) *p++ = '\0'; if (dtrace_setopt(dtp, optarg, p) != 0) { (void) fprintf(stderr, "%s: failed to set " "option -x %s: %s\n", g_progname, optarg, dtrace_errmsg(dtp, dtrace_errno(dtp))); return (2); } break; default: (void) fprintf(stderr, "Usage: %s [-ev] " "[-x opt[=arg]] [probedesc]\n", g_progname); return (2); } } argv += optind; argc -= optind; if (argc > 0) { if (dtrace_str2desc(dtp, DTRACE_PROBESPEC_NAME, argv[0], &pd)) { (void) fprintf(stderr, "%s: invalid probe description " "%s: %s\n", g_progname, argv[0], dtrace_errmsg(dtp, dtrace_errno(dtp))); return (2); } pdp = &pd; } g_fd = dtrace_ctlfd(dtp); (void) dtrace_probe_iter(dtp, pdp, probe, NULL); dtrace_close(dtp); (void) printf("\nTotal probes: %d\n", g_count); (void) printf("Total errors: %d\n\n", g_errs); return (g_errs != 0); }
int main(int argc, char **argv) { int err; int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0; char c, *p, *end; struct sigaction act; int done = 0; g_pname = basename(argv[0]); argv[0] = g_pname; /* rewrite argv[0] for getopt errors */ while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) { switch (c) { case 'n': errno = 0; g_nent = strtoul(optarg, &end, 10); if (*end != '\0' || errno != 0) { (void) fprintf(stderr, "%s: invalid count " "'%s'\n", g_pname, optarg); usage(); } break; case 'p': opt_p = 1; break; case 'v': opt_v = 1; break; case 'A': opt_C = opt_H = 1; break; case 'C': opt_C = 1; break; case 'H': opt_H = 1; break; case 'V': g_opt_V = 1; break; default: if (strchr(PLOCKSTAT_OPTSTR, c) == NULL) usage(); } } /* * We need a command or at least one pid. */ if (argc == optind) usage(); if (opt_C == 0 && opt_H == 0) opt_C = 1; if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) fatal("failed to initialize dtrace: %s\n", dtrace_errmsg(NULL, err)); /* * The longest string we trace is 23 bytes long -- so 32 is plenty. */ if (dtrace_setopt(g_dtp, "strsize", "32") == -1) dfatal("failed to set 'strsize'"); /* * 1k should be more than enough for all trace() and printa() actions. */ if (dtrace_setopt(g_dtp, "bufsize", "1k") == -1) dfatal("failed to set 'bufsize'"); /* * The table we produce has the hottest locks at the top. */ if (dtrace_setopt(g_dtp, "aggsortrev", NULL) == -1) dfatal("failed to set 'aggsortrev'"); /* * These are two reasonable defaults which should suffice. */ if (dtrace_setopt(g_dtp, "aggsize", "256k") == -1) dfatal("failed to set 'aggsize'"); if (dtrace_setopt(g_dtp, "aggrate", "1sec") == -1) dfatal("failed to set 'aggrate'"); /* * Take a second pass through to look for options that set options now * that we have an open dtrace handle. */ optind = 1; while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) { switch (c) { case 's': g_opt_s = 1; if (dtrace_setopt(g_dtp, "ustackframes", optarg) == -1) dfatal("failed to set 'ustackframes'"); break; case 'x': if ((p = strchr(optarg, '=')) != NULL) *p++ = '\0'; if (dtrace_setopt(g_dtp, optarg, p) != 0) dfatal("failed to set -x %s", optarg); break; case 'e': errno = 0; (void) strtoul(optarg, &end, 10); if (*optarg == '-' || *end != '\0' || errno != 0) { (void) fprintf(stderr, "%s: invalid timeout " "'%s'\n", g_pname, optarg); usage(); } /* * Construct a DTrace enabling that will exit after * the specified number of seconds. */ dprog_add("BEGIN\n{\n\tend = timestamp + "); dprog_add(optarg); dprog_add(" * 1000000000;\n}\n"); dprog_add("tick-10hz\n/timestamp >= end/\n"); dprog_add("{\n\texit(0);\n}\n"); break; } } argc -= optind; argv += optind; if (opt_H) { dprog_add(g_hold_init); if (g_opt_s == NULL) dprog_add(g_hold_times); else dprog_add(g_hold_histogram); } if (opt_C) { dprog_add(g_ctnd_init); if (g_opt_s == NULL) dprog_add(g_ctnd_times); else dprog_add(g_ctnd_histogram); } if (opt_p) { ulong_t pid; if (argc > 1) { (void) fprintf(stderr, "%s: only one pid is allowed\n", g_pname); usage(); } errno = 0; pid = strtoul(argv[0], &end, 10); if (*end != '\0' || errno != 0 || (pid_t)pid != pid) { (void) fprintf(stderr, "%s: invalid pid '%s'\n", g_pname, argv[0]); usage(); } if ((g_pr = dtrace_proc_grab(g_dtp, (pid_t)pid, 0)) == NULL) dfatal(NULL); } else { if ((g_pr = dtrace_proc_create(g_dtp, argv[0], argv)) == NULL) dfatal(NULL); } dprog_compile(); if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1) dfatal("failed to establish proc handler"); (void) sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = intr; (void) sigaction(SIGINT, &act, NULL); (void) sigaction(SIGTERM, &act, NULL); if (dtrace_go(g_dtp) != 0) dfatal("dtrace_go()"); if (dtrace_getopt(g_dtp, "ustackframes", &g_nframes) != 0) dfatal("failed to get 'ustackframes'"); dtrace_proc_continue(g_dtp, g_pr); if (opt_v) (void) printf("%s: tracing enabled for pid %d\n", g_pname, (int)Pstatus(g_pr)->pr_pid); do { if (!g_intr && !done) dtrace_sleep(g_dtp); if (done || g_intr || g_exited) { done = 1; if (dtrace_stop(g_dtp) == -1) dfatal("couldn't stop tracing"); } switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) { case DTRACE_WORKSTATUS_DONE: done = 1; break; case DTRACE_WORKSTATUS_OKAY: break; default: dfatal("processing aborted"); } } while (!done); dtrace_close(g_dtp); return (0); }