Example #1
0
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;
}
Example #2
0
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;
}
Example #3
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;
}
Example #4
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);
}
Example #5
0
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;
}
Example #6
0
/*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);
}
Example #7
0
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);
}
Example #8
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);
}