dt_open.c

来自「Sun Solaris 10 中的 DTrace 组件的源代码。请参看: htt」· C语言 代码 · 共 1,315 行 · 第 1/4 页

C
1,315
字号
    const dtrace_vector_t *vector, void *arg){	dtrace_hdl_t *dtp = NULL;	int dtfd = -1, ftfd = -1, fterr = 0;	dtrace_prog_t *pgp;	dt_module_t *dmp;	dt_provmod_t *provmod = NULL;	int i, err;	const dt_intrinsic_t *dinp;	const dt_typedef_t *dtyp;	const dt_ident_t *idp;	dtrace_typeinfo_t dtt;	ctf_funcinfo_t ctc;	ctf_arinfo_t ctr;	dt_fdlist_t df = { NULL, 0, 0 };	char *p, *q, *path = NULL;	const char *isadir = NULL;	int pathlen;	char isadef[32], utsdef[32];	char s1[64], s2[64];	if (version <= 0)		return (set_open_errno(dtp, errp, EINVAL));	if (version > DTRACE_VERSION)		return (set_open_errno(dtp, errp, EDT_VERSION));	if (flags & ~DTRACE_O_MASK)		return (set_open_errno(dtp, errp, EINVAL));	if ((flags & DTRACE_O_LP64) && (flags & DTRACE_O_ILP32))		return (set_open_errno(dtp, errp, EINVAL));	if (vector == NULL && arg != NULL)		return (set_open_errno(dtp, errp, EINVAL));	if (elf_version(EV_CURRENT) == EV_NONE)		return (set_open_errno(dtp, errp, EDT_ELFVERSION));	if (vector != NULL || (flags & DTRACE_O_NODEV))		goto alloc; /* do not attempt to open dtrace device */	/*	 * For each directory in the kernel's module path, build the name of	 * the corresponding dtrace provider subdirectory and attempt to open a	 * pseudo-driver whose name matches the name of each provider therein.	 * We hold them open in the df.df_fds list until we open the DTrace	 * driver itself, allowing us to see all of the probes provided on this	 * system.  Once we have the DTrace driver open, we can safely close	 * all the providers now that they have registered with the framework.	 */	if (sysinfo(SI_ISALIST, isadef, sizeof (isadef)) > 0) {		if (strstr(isadef, "sparcv9") != NULL)			isadir = "sparcv9";		else if (strstr(isadef, "amd64") != NULL)			isadir = "amd64";	}	if (modctl(MODGETPATHLEN, NULL, &pathlen) == 0 &&	    (path = malloc(pathlen + 1)) != NULL &&	    modctl(MODGETPATH, NULL, path) == 0) {		for (p = path; *p != '\0'; p = q) {			if ((q = strchr(p, ' ')) != NULL)				*q++ = '\0';			else				q = p + strlen(p);			dt_provmod_open(&provmod, &df, p,			    _dtrace_moddir, isadir);		}	}	dtfd = open("/devices/pseudo/dtrace@0:dtrace", O_RDWR);	err = errno; /* save errno from opening dtfd */	ftfd = open("/devices/pseudo/fasttrap@0:fasttrap", O_RDWR);	fterr = ftfd == -1 ? errno : 0; /* save errno from open ftfd */	while (df.df_ents-- != 0)		(void) close(df.df_fds[df.df_ents]);	free(df.df_fds);	free(path);	/*	 * If we failed to open the dtrace device, fail dtrace_open().	 * We convert some kernel errnos to custom libdtrace errnos to	 * improve the resulting message from the usual strerror().	 */	if (dtfd == -1) {		dt_provmod_destroy(&provmod);		switch (err) {		case ENOENT:			if (getzoneid() != GLOBAL_ZONEID)				err = EDT_ZNOENT;			else				err = EDT_GNOENT;			break;		case EBUSY:			err = EDT_BUSY;			break;		case EACCES:			err = EDT_ACCESS;			break;		}		return (set_open_errno(dtp, errp, err));	}	(void) fcntl(dtfd, F_SETFD, FD_CLOEXEC);	(void) fcntl(ftfd, F_SETFD, FD_CLOEXEC);alloc:	if ((dtp = malloc(sizeof (dtrace_hdl_t))) == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));	bzero(dtp, sizeof (dtrace_hdl_t));	dtp->dt_oflags = flags;	dtp->dt_prcmode = DT_PROC_STOP_PREINIT;	dtp->dt_linkmode = DT_LINK_KERNEL;	dtp->dt_stdcmode = DT_STDC_XA;	dtp->dt_version = version;	dtp->dt_fd = dtfd;	dtp->dt_ftfd = ftfd;	dtp->dt_fterr = fterr;	dtp->dt_cdefs_fd = -1;	dtp->dt_ddefs_fd = -1;	dtp->dt_modbuckets = _dtrace_strbuckets;	dtp->dt_mods = calloc(dtp->dt_modbuckets, sizeof (dt_module_t *));	dtp->dt_provbuckets = _dtrace_strbuckets;	dtp->dt_provs = calloc(dtp->dt_provbuckets, sizeof (dt_provider_t *));	dt_proc_hash_create(dtp);	dtp->dt_vmax = DT_VERS_LATEST;	dtp->dt_cpp_path = strdup(_dtrace_defcpp);	dtp->dt_cpp_argv = malloc(sizeof (char *));	dtp->dt_cpp_argc = 1;	dtp->dt_cpp_args = 1;	dtp->dt_ld_path = strdup(_dtrace_defld);	dtp->dt_provmod = provmod;	dtp->dt_vector = vector;	dtp->dt_varg = arg;	if (dtp->dt_mods == NULL || dtp->dt_provs == NULL ||	    dtp->dt_procs == NULL || dtp->dt_ld_path == NULL ||	    dtp->dt_cpp_path == NULL || dtp->dt_cpp_argv == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));	for (i = 0; i < DTRACEOPT_MAX; i++)		dtp->dt_options[i] = DTRACEOPT_UNSET;	dtp->dt_cpp_argv[0] = (char *)strbasename(dtp->dt_cpp_path);	(void) snprintf(isadef, sizeof (isadef), "-D__SUNW_D_%u",	    (uint_t)(sizeof (void *) * NBBY));	(void) snprintf(utsdef, sizeof (utsdef), "-D__%s_%s",	    dt_get_sysinfo(SI_SYSNAME, s1, sizeof (s1)),	    dt_get_sysinfo(SI_RELEASE, s2, sizeof (s2)));	if (dt_cpp_add_arg(dtp, "-D__sun") == NULL ||	    dt_cpp_add_arg(dtp, "-D__unix") == NULL ||	    dt_cpp_add_arg(dtp, "-D__SVR4") == NULL ||	    dt_cpp_add_arg(dtp, "-D__SUNW_D=1") == NULL ||	    dt_cpp_add_arg(dtp, isadef) == NULL ||	    dt_cpp_add_arg(dtp, utsdef) == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));	if (flags & DTRACE_O_NODEV)		bcopy(&_dtrace_conf, &dtp->dt_conf, sizeof (_dtrace_conf));	else if (dt_ioctl(dtp, DTRACEIOC_CONF, &dtp->dt_conf) != 0)		return (set_open_errno(dtp, errp, errno));	if (flags & DTRACE_O_LP64)		dtp->dt_conf.dtc_ctfmodel = CTF_MODEL_LP64;	else if (flags & DTRACE_O_ILP32)		dtp->dt_conf.dtc_ctfmodel = CTF_MODEL_ILP32;#ifdef __sparc	/*	 * On SPARC systems, __sparc is always defined for <sys/isa_defs.h>	 * and __sparcv9 is defined if we are doing a 64-bit compile.	 */	if (dt_cpp_add_arg(dtp, "-D__sparc") == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64 &&	    dt_cpp_add_arg(dtp, "-D__sparcv9") == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));#endif#ifdef __x86	/*	 * On x86 systems, __i386 is defined for <sys/isa_defs.h> for 32-bit	 * compiles and __amd64 is defined for 64-bit compiles.  Unlike SPARC,	 * they are defined exclusive of one another (see PSARC 2004/619).	 */	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_LP64)		p = dt_cpp_add_arg(dtp, "-D__amd64");	else		p = dt_cpp_add_arg(dtp, "-D__i386");	if (p == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));#endif	if (dtp->dt_conf.dtc_difversion < DIF_VERSION)		return (set_open_errno(dtp, errp, EDT_DIFVERS));	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_ILP32)		bcopy(_dtrace_ints_32, dtp->dt_ints, sizeof (_dtrace_ints_32));	else		bcopy(_dtrace_ints_64, dtp->dt_ints, sizeof (_dtrace_ints_64));	dtp->dt_macros = dt_idhash_create("macro", NULL, 0, UINT_MAX);	dtp->dt_aggs = dt_idhash_create("aggregation", NULL, 0, UINT_MAX);	dtp->dt_globals = dt_idhash_create("global", _dtrace_globals,	    DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);	dtp->dt_tls = dt_idhash_create("thread local", NULL,	    DIF_VAR_OTHER_UBASE, DIF_VAR_OTHER_MAX);	if (dtp->dt_macros == NULL || dtp->dt_aggs == NULL ||	    dtp->dt_globals == NULL || dtp->dt_tls == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));	/*	 * Populate the dt_macros identifier hash table by hand: we can't use	 * the dt_idhash_populate() mechanism because we're not yet compiling	 * and dtrace_update() needs to immediately reference these idents.	 */	for (idp = _dtrace_macros; idp->di_name != NULL; idp++) {		if (dt_idhash_insert(dtp->dt_macros, idp->di_name,		    idp->di_kind, idp->di_flags, idp->di_id, idp->di_attr,		    idp->di_vers, idp->di_ops ? idp->di_ops : &dt_idops_thaw,		    idp->di_iarg, 0) == NULL)			return (set_open_errno(dtp, errp, EDT_NOMEM));	}	/*	 * Update the module list using /system/object and load the values for	 * the macro variable definitions according to the current process.	 */	dtrace_update(dtp);	/*	 * Select the intrinsics and typedefs we want based on the data model.	 * The intrinsics are under "C".  The typedefs are added under "D".	 */	if (dtp->dt_conf.dtc_ctfmodel == CTF_MODEL_ILP32) {		dinp = _dtrace_intrinsics_32;		dtyp = _dtrace_typedefs_32;	} else {		dinp = _dtrace_intrinsics_64;		dtyp = _dtrace_typedefs_64;	}	/*	 * Create a dynamic CTF container under the "C" scope for intrinsic	 * types and types defined in ANSI-C header files that are included.	 */	if ((dmp = dtp->dt_cdefs = dt_module_create(dtp, "C")) == NULL)		return (set_open_errno(dtp, errp, EDT_NOMEM));	if ((dmp->dm_ctfp = ctf_create(&dtp->dt_ctferr)) == NULL)		return (set_open_errno(dtp, errp, EDT_CTF));	dt_dprintf("created CTF container for %s (%p)\n",	    dmp->dm_name, (void *)dmp->dm_ctfp);	(void) ctf_setmodel(dmp->dm_ctfp, dtp->dt_conf.dtc_ctfmodel);	dmp->dm_flags = DT_DM_LOADED; /* fake up loaded bit */	dmp->dm_modid = -1; /* no module ID */	/*	 * Fill the dynamic "C" CTF container with all of the intrinsic	 * integer and floating-point types appropriate for this data model.	 */	for (; dinp->din_name != NULL; dinp++) {		if (dinp->din_kind == CTF_K_INTEGER) {			err = ctf_add_integer(dmp->dm_ctfp, CTF_ADD_ROOT,			    dinp->din_name, &dinp->din_data);		} else {			err = ctf_add_float(dmp->dm_ctfp, CTF_ADD_ROOT,			    dinp->din_name, &dinp->din_data);		}		if (err == CTF_ERR) {			dt_dprintf("failed to add %s to C container: %s\n",			    dinp->din_name, ctf_errmsg(			    ctf_errno(dmp->dm_ctfp)));			return (set_open_errno(dtp, errp, EDT_CTF));		}	}	if (ctf_update(dmp->dm_ctfp) != 0) {		dt_dprintf("failed to update C container: %s\n",		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));		return (set_open_errno(dtp, errp, EDT_CTF));	}	/*	 * Add intrinsic pointer types that are needed to initialize printf	 * format dictionary types (see table in dt_printf.c).	 */	(void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,	    ctf_lookup_by_name(dmp->dm_ctfp, "void"));	(void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,	    ctf_lookup_by_name(dmp->dm_ctfp, "char"));	(void) ctf_add_pointer(dmp->dm_ctfp, CTF_ADD_ROOT,	    ctf_lookup_by_name(dmp->dm_ctfp, "int"));	if (ctf_update(dmp->dm_ctfp) != 0) {		dt_dprintf("failed to update C container: %s\n",		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));		return (set_open_errno(dtp, errp, EDT_CTF));	}	/*	 * Create a dynamic CTF container under the "D" scope for types that	 * are defined by the D program itself or on-the-fly by the D compiler.	 * The "D" CTF container is a child of the "C" CTF container.	 */	if ((dmp = dtp->dt_ddefs = dt_module_create(dtp, "D")) == NULL)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?