예제 #1
0
파일: dtrace.c 프로젝트: 0xbda2d2f8/freebsd
/*ARGSUSED*/
static int
list_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
    dtrace_stmtdesc_t *stp, dtrace_ecbdesc_t **last)
{
	dtrace_ecbdesc_t *edp = stp->dtsd_ecbdesc;

	if (edp == *last)
		return (0);

	if (dtrace_probe_iter(g_dtp, &edp->dted_probe, list_probe, NULL) != 0) {
		error("failed to match %s:%s:%s:%s: %s\n",
		    edp->dted_probe.dtpd_provider, edp->dted_probe.dtpd_mod,
		    edp->dted_probe.dtpd_func, edp->dted_probe.dtpd_name,
		    dtrace_errmsg(dtp, dtrace_errno(dtp)));
	}

	*last = edp;
	return (0);
}
예제 #2
0
파일: lsdtrace.c 프로젝트: gdawg/lsdtrace
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;
}
예제 #3
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);
}
예제 #4
0
dt_probe_t *
dt_probe_info(dtrace_hdl_t *dtp,
    const dtrace_probedesc_t *pdp, dtrace_probeinfo_t *pip)
{
	int m_is_glob = pdp->dtpd_mod[0] == '\0' || strisglob(pdp->dtpd_mod);
	int f_is_glob = pdp->dtpd_func[0] == '\0' || strisglob(pdp->dtpd_func);
	int n_is_glob = pdp->dtpd_name[0] == '\0' || strisglob(pdp->dtpd_name);

	dt_probe_t *prp = NULL;
	const dtrace_pattr_t *pap;
	dt_provider_t *pvp;
	dt_ident_t *idp;

	/*
	 * Attempt to lookup the probe in our existing cache for this provider.
	 * If none is found and an explicit probe ID was specified, discover
	 * that specific probe and cache its description and arguments.
	 */
	if ((pvp = dt_provider_lookup(dtp, pdp->dtpd_provider)) != NULL) {
		size_t keylen = dt_probe_keylen(pdp);
		char *key = dt_probe_key(pdp, alloca(keylen));

		if ((idp = dt_idhash_lookup(pvp->pv_probes, key)) != NULL)
			prp = idp->di_data;
		else if (pdp->dtpd_id != DTRACE_IDNONE)
			prp = dt_probe_discover(pvp, pdp);
	}

	/*
	 * If no probe was found in our cache, convert the caller's partial
	 * probe description into a fully-formed matching probe description by
	 * iterating over up to at most two probes that match 'pdp'.  We then
	 * call dt_probe_discover() on the resulting probe identifier.
	 */
	if (prp == NULL) {
		dtrace_probedesc_t pd;
		int m;

		bzero(&pd, sizeof (pd));
		pd.dtpd_id = DTRACE_IDNONE;

		/*
		 * Call dtrace_probe_iter() to find matching probes.  Our
		 * dt_probe_desc() callback will produce the following results:
		 *
		 * m < 0 dtrace_probe_iter() found zero matches (or failed).
		 * m > 0 dtrace_probe_iter() found more than one match.
		 * m = 0 dtrace_probe_iter() found exactly one match.
		 */
		if ((m = dtrace_probe_iter(dtp, pdp, dt_probe_desc, &pd)) < 0)
			return (NULL); /* dt_errno is set for us */

		if ((pvp = dt_provider_lookup(dtp, pd.dtpd_provider)) == NULL)
			return (NULL); /* dt_errno is set for us */

		/*
		 * If more than one probe was matched, then do not report probe
		 * information if either of the following conditions is true:
		 *
		 * (a) The Arguments Data stability of the matched provider is
		 *	less than Evolving.
		 *
		 * (b) Any description component that is at least Evolving is
		 *	empty or is specified using a globbing expression.
		 *
		 * These conditions imply that providers that provide Evolving
		 * or better Arguments Data stability must guarantee that all
		 * probes with identical field names in a field of Evolving or
		 * better Name stability have identical argument signatures.
		 */
		if (m > 0) {
			if (pvp->pv_desc.dtvd_attr.dtpa_args.dtat_data <
			    DTRACE_STABILITY_EVOLVING) {
				(void) dt_set_errno(dtp, EDT_UNSTABLE);
				return (NULL);
			}


			if (pvp->pv_desc.dtvd_attr.dtpa_mod.dtat_name >=
			    DTRACE_STABILITY_EVOLVING && m_is_glob) {
				(void) dt_set_errno(dtp, EDT_UNSTABLE);
				return (NULL);
			}

			if (pvp->pv_desc.dtvd_attr.dtpa_func.dtat_name >=
			    DTRACE_STABILITY_EVOLVING && f_is_glob) {
				(void) dt_set_errno(dtp, EDT_UNSTABLE);
				return (NULL);
			}

			if (pvp->pv_desc.dtvd_attr.dtpa_name.dtat_name >=
			    DTRACE_STABILITY_EVOLVING && n_is_glob) {
				(void) dt_set_errno(dtp, EDT_UNSTABLE);
				return (NULL);
			}
		}

		/*
		 * If we matched a probe exported by dtrace(7D), then discover
		 * the real attributes.  Otherwise grab the static declaration.
		 */
		if (pd.dtpd_id != DTRACE_IDNONE)
			prp = dt_probe_discover(pvp, &pd);
		else
			prp = dt_probe_lookup(pvp, pd.dtpd_name);

		if (prp == NULL)
			return (NULL); /* dt_errno is set for us */
	}

	assert(pvp != NULL && prp != NULL);

	/*
	 * Compute the probe description attributes by taking the minimum of
	 * the attributes of the specified fields.  If no provider is specified
	 * or a glob pattern is used for the provider, use Unstable attributes.
	 */
	if (pdp->dtpd_provider[0] == '\0' || strisglob(pdp->dtpd_provider))
		pap = &_dtrace_prvdesc;
	else
		pap = &pvp->pv_desc.dtvd_attr;

	pip->dtp_attr = pap->dtpa_provider;

	if (!m_is_glob)
		pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_mod);
	if (!f_is_glob)
		pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_func);
	if (!n_is_glob)
		pip->dtp_attr = dt_attr_min(pip->dtp_attr, pap->dtpa_name);

	pip->dtp_arga = pap->dtpa_args;
	pip->dtp_argv = prp->pr_argv;
	pip->dtp_argc = prp->pr_argc;

	return (prp);
}