Пример #1
0
/*
 * We've been asked to load data that belongs to another process. As such we're
 * going to pgrab it at this instant, load everything that we might ever care
 * about, and then drive on. The reason for this is that the process that we're
 * interested in might be changing. As long as we have grabbed it, then this
 * can't be a problem for us.
 *
 * For now, we're actually going to punt on most things and just try to get CTF
 * data, nothing else. Basically this is only useful as a source of type
 * information, we can't go and do the stacktrace lookups, etc.
 */
static int
dt_module_load_proc(dtrace_hdl_t *dtp, dt_module_t *dmp)
{
	struct ps_prochandle *p;
	dt_module_cb_arg_t arg;

	/*
	 * Note that on success we do not release this hold. We must hold this
	 * for our life time.
	 */
	p = dt_proc_grab(dtp, dmp->dm_pid, 0, PGRAB_RDONLY | PGRAB_FORCE);
	if (p == NULL) {
		dt_dprintf("failed to grab pid: %d\n", (int)dmp->dm_pid);
		return (dt_set_errno(dtp, EDT_CANTLOAD));
	}
	dt_proc_lock(dtp, p);

	arg.dpa_proc = p;
	arg.dpa_dtp = dtp;
	arg.dpa_dmp = dmp;
	arg.dpa_count = 0;
	if (Pobject_iter_resolved(p, dt_module_load_proc_count, &arg) != 0) {
		dt_dprintf("failed to iterate objects\n");
		dt_proc_release(dtp, p);
		return (dt_set_errno(dtp, EDT_CANTLOAD));
	}

	if (arg.dpa_count == 0) {
		dt_dprintf("no ctf data present\n");
		dt_proc_unlock(dtp, p);
		dt_proc_release(dtp, p);
		return (dt_set_errno(dtp, EDT_CANTLOAD));
	}

	dmp->dm_libctfp = malloc(sizeof (ctf_file_t *) * arg.dpa_count);
	if (dmp->dm_libctfp == NULL) {
		dt_proc_unlock(dtp, p);
		dt_proc_release(dtp, p);
		return (dt_set_errno(dtp, EDT_NOMEM));
	}
	bzero(dmp->dm_libctfp, sizeof (ctf_file_t *) * arg.dpa_count);

	dmp->dm_libctfn = malloc(sizeof (char *) * arg.dpa_count);
	if (dmp->dm_libctfn == NULL) {
		free(dmp->dm_libctfp);
		dt_proc_unlock(dtp, p);
		dt_proc_release(dtp, p);
		return (dt_set_errno(dtp, EDT_NOMEM));
	}
	bzero(dmp->dm_libctfn, sizeof (char *) * arg.dpa_count);

	dmp->dm_nctflibs = arg.dpa_count;

	arg.dpa_count = 0;
	if (Pobject_iter_resolved(p, dt_module_load_proc_build, &arg) != 0) {
		dt_proc_unlock(dtp, p);
		dt_module_unload(dtp, dmp);
		dt_proc_release(dtp, p);
		return (dt_set_errno(dtp, EDT_CANTLOAD));
	}
	assert(arg.dpa_count == dmp->dm_nctflibs);
	dt_dprintf("loaded %d ctf modules for pid %d\n", arg.dpa_count,
	    (int)dmp->dm_pid);

	dt_proc_unlock(dtp, p);
	dt_proc_release(dtp, p);
	dmp->dm_flags |= DT_DM_LOADED;

	return (0);
}
Пример #2
0
void
dtrace_proc_release(dtrace_hdl_t *dtp, struct ps_prochandle *P)
{
	dt_proc_release(dtp, P);
}
Пример #3
0
int
dt_pid_create_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, dt_pcb_t *pcb)
{
	char provname[DTRACE_PROVNAMELEN];
	struct ps_prochandle *P;
	dt_proc_t *dpr;
	pid_t pid;
	int err = 0;

	assert(pcb != NULL);

	if ((pid = dt_pid_get_pid(pdp, dtp, pcb, NULL)) == -1)
		return (-1);

	if (dtp->dt_ftfd == -1) {
		if (dtp->dt_fterr == ENOENT) {
			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV,
			    "pid provider is not installed on this system");
		} else {
			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_NODEV,
			    "pid provider is not available: %s",
			    strerror(dtp->dt_fterr));
		}

		return (-1);
	}

	(void) snprintf(provname, sizeof (provname), "pid%d", (int)pid);

	if (gmatch(provname, pdp->dtpd_provider) != 0) {
		if ((P = dt_proc_grab(dtp, pid, PGRAB_RDONLY | PGRAB_FORCE,
		    0)) == NULL) {
			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB,
			    "failed to grab process %d", (int)pid);
			return (-1);
		}

		dpr = dt_proc_lookup(dtp, P, 0);
		assert(dpr != NULL);
		(void) pthread_mutex_lock(&dpr->dpr_lock);

		if ((err = dt_pid_create_pid_probes(pdp, dtp, pcb, dpr)) == 0) {
			/*
			 * Alert other retained enablings which may match
			 * against the newly created probes.
			 */
			(void) dt_ioctl(dtp, DTRACEIOC_ENABLE, NULL);
		}

		(void) pthread_mutex_unlock(&dpr->dpr_lock);
		dt_proc_release(dtp, P);
	}

	/*
	 * If it's not strictly a pid provider, we might match a USDT provider.
	 */
	if (strcmp(provname, pdp->dtpd_provider) != 0) {
		if ((P = dt_proc_grab(dtp, pid, 0, 1)) == NULL) {
			(void) dt_pid_error(dtp, pcb, NULL, NULL, D_PROC_GRAB,
			    "failed to grab process %d", (int)pid);
			return (-1);
		}

		dpr = dt_proc_lookup(dtp, P, 0);
		assert(dpr != NULL);
		(void) pthread_mutex_lock(&dpr->dpr_lock);

		if (!dpr->dpr_usdt) {
			err = dt_pid_create_usdt_probes(pdp, dtp, pcb, dpr);
			dpr->dpr_usdt = B_TRUE;
		}

		(void) pthread_mutex_unlock(&dpr->dpr_lock);
		dt_proc_release(dtp, P);
	}

	return (err ? -1 : 0);
}