FreeBSD/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c
/*
 * 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.
 */
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.
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;
	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_unlock(dtp, p);
		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 = calloc(arg.dpa_count, sizeof (ctf_file_t *));
	if (dmp->dm_libctfp == NULL) {
		dt_proc_unlock(dtp, p);
		dt_proc_release(dtp, p);
		return (dt_set_errno(dtp, EDT_NOMEM));
	}
	dmp->dm_libctfn = calloc(arg.dpa_count, sizeof (char *));
	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));
	}
	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);
}
static int dt_module_load_proc ( dtrace_hdl_t * dtp , dt_module_t * dmp ) { struct ps_prochandle * p ; dt_module_cb_arg_t arg ; p = dt_proc_grab ( dtp , dmp -> dm_pid , 0 , PGRAB_RDONLY | PGRAB_FORCE ) ; if ( p == NULL ) { dt_dprintf ( " \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 ( " \n " ) ; dt_proc_unlock ( dtp , p ) ; dt_proc_release ( dtp , p ) ; return ( dt_set_errno ( dtp , EDT_CANTLOAD ) ) ; } if ( arg . dpa_count == 0 ) { dt_dprintf ( " \n " ) ; dt_proc_unlock ( dtp , p ) ; dt_proc_release ( dtp , p ) ; return ( dt_set_errno ( dtp , EDT_CANTLOAD ) ) ; } dmp -> dm_libctfp = calloc ( arg . dpa_count , sizeof ( ctf_file_t * ) ) ; if ( dmp -> dm_libctfp == NULL ) { dt_proc_unlock ( dtp , p ) ; dt_proc_release ( dtp , p ) ; return ( dt_set_errno ( dtp , EDT_NOMEM ) ) ; } dmp -> dm_libctfn = calloc ( arg . dpa_count , sizeof ( char * ) ) ; 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 ) ) ; } 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 ( " \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 ) ; }
We've been asked to load data that belongs to another process.
We ' ve been asked to load data that belongs to another process .
/*
	 * Note that on success we do not release this hold. We must hold this
	 * for our life time.
	 */