dt_open.c

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

C
1,315
字号
		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 */	if (ctf_import(dmp->dm_ctfp, dtp->dt_cdefs->dm_ctfp) == CTF_ERR) {		dt_dprintf("failed to import D parent container: %s\n",		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));		return (set_open_errno(dtp, errp, EDT_CTF));	}	/*	 * Fill the dynamic "D" CTF container with all of the built-in typedefs	 * that we need to use for our D variable and function definitions.	 * This ensures that basic inttypes.h names are always available to us.	 */	for (; dtyp->dty_src != NULL; dtyp++) {		if (ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,		    dtyp->dty_dst, ctf_lookup_by_name(dmp->dm_ctfp,		    dtyp->dty_src)) == CTF_ERR) {			dt_dprintf("failed to add typedef %s %s to D "			    "container: %s", dtyp->dty_src, dtyp->dty_dst,			    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));			return (set_open_errno(dtp, errp, EDT_CTF));		}	}	/*	 * Insert a CTF ID corresponding to a pointer to a type of kind	 * CTF_K_FUNCTION we can use in the compiler for function pointers.	 * CTF treats all function pointers as "int (*)()" so we only need one.	 */	ctc.ctc_return = ctf_lookup_by_name(dmp->dm_ctfp, "int");	ctc.ctc_argc = 0;	ctc.ctc_flags = 0;	dtp->dt_type_func = ctf_add_function(dmp->dm_ctfp,	    CTF_ADD_ROOT, &ctc, NULL);	dtp->dt_type_fptr = ctf_add_pointer(dmp->dm_ctfp,	    CTF_ADD_ROOT, dtp->dt_type_func);	/*	 * We also insert CTF definitions for the special D intrinsic types	 * string and <DYN> into the D container.  The string type is added	 * as a typedef of char[n].  The <DYN> type is an alias for void.	 * We compare types to these special CTF ids throughout the compiler.	 */	ctr.ctr_contents = ctf_lookup_by_name(dmp->dm_ctfp, "char");	ctr.ctr_index = ctf_lookup_by_name(dmp->dm_ctfp, "long");	ctr.ctr_nelems = _dtrace_strsize;	dtp->dt_type_str = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,	    "string", ctf_add_array(dmp->dm_ctfp, CTF_ADD_ROOT, &ctr));	dtp->dt_type_dyn = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,	    "<DYN>", ctf_lookup_by_name(dmp->dm_ctfp, "void"));	dtp->dt_type_stack = ctf_add_typedef(dmp->dm_ctfp, CTF_ADD_ROOT,	    "stack", ctf_lookup_by_name(dmp->dm_ctfp, "void"));	if (dtp->dt_type_func == CTF_ERR || dtp->dt_type_fptr == CTF_ERR ||	    dtp->dt_type_str == CTF_ERR || dtp->dt_type_dyn == CTF_ERR ||	    dtp->dt_type_stack == CTF_ERR) {		dt_dprintf("failed to add intrinsic to D container: %s\n",		    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 update D container: %s\n",		    ctf_errmsg(ctf_errno(dmp->dm_ctfp)));		return (set_open_errno(dtp, errp, EDT_CTF));	}	/*	 * Initialize the integer description table used to convert integer	 * constants to the appropriate types.  Refer to the comments above	 * dt_node_int() for a complete description of how this table is used.	 */	for (i = 0; i < sizeof (dtp->dt_ints) / sizeof (dtp->dt_ints[0]); i++) {		if (dtrace_lookup_by_type(dtp, DTRACE_OBJ_EVERY,		    dtp->dt_ints[i].did_name, &dtt) != 0) {			dt_dprintf("failed to lookup integer type %s: %s\n",			    dtp->dt_ints[i].did_name,			    dtrace_errmsg(dtp, dtrace_errno(dtp)));			return (set_open_errno(dtp, errp, dtp->dt_errno));		}		dtp->dt_ints[i].did_ctfp = dtt.dtt_ctfp;		dtp->dt_ints[i].did_type = dtt.dtt_type;	}	/*	 * Now that we've created the "C" and "D" containers, move them to the	 * start of the module list so that these types and symbols are found	 * first (for stability) when iterating through the module list.	 */	dt_list_delete(&dtp->dt_modlist, dtp->dt_ddefs);	dt_list_prepend(&dtp->dt_modlist, dtp->dt_ddefs);	dt_list_delete(&dtp->dt_modlist, dtp->dt_cdefs);	dt_list_prepend(&dtp->dt_modlist, dtp->dt_cdefs);	if (dt_pfdict_create(dtp) == -1)		return (set_open_errno(dtp, errp, dtp->dt_errno));	/*	 * If we are opening libdtrace DTRACE_O_NODEV enable C_ZDEFS by default	 * because without /dev/dtrace open, we will not be able to load the	 * names and attributes of any providers or probes from the kernel.	 */	if (flags & DTRACE_O_NODEV)		dtp->dt_cflags |= DTRACE_C_ZDEFS;	/*	 * Load hard-wired inlines into the definition cache by calling the	 * compiler on the raw definition string defined above.	 */	if ((pgp = dtrace_program_strcompile(dtp, _dtrace_hardwire,	    DTRACE_PROBESPEC_NONE, DTRACE_C_EMPTY, 0, NULL)) == NULL) {		dt_dprintf("failed to load hard-wired definitions: %s\n",		    dtrace_errmsg(dtp, dtrace_errno(dtp)));		return (set_open_errno(dtp, errp, EDT_HARDWIRE));	}	dtrace_program_destroy(dtp, pgp);	/*	 * Set up the default DTrace library path.  Once set, the next call to	 * dt_compile() will compile all the libraries.  We intentionally defer	 * library processing to improve overhead for clients that don't ever	 * compile, and to provide better error reporting (because the full	 * reporting of compiler errors requires dtrace_open() to succeed).	 */	if (dtrace_setopt(dtp, "libdir", _dtrace_libdir) != 0)		return (set_open_errno(dtp, errp, dtp->dt_errno));	return (dtp);}dtrace_hdl_t *dtrace_open(int version, int flags, int *errp){	return (dt_vopen(version, flags, errp, NULL, NULL));}dtrace_hdl_t *dtrace_vopen(int version, int flags, int *errp,    const dtrace_vector_t *vector, void *arg){	return (dt_vopen(version, flags, errp, vector, arg));}voiddtrace_close(dtrace_hdl_t *dtp){	dt_ident_t *idp, *ndp;	dt_module_t *dmp;	dt_provider_t *pvp;	dtrace_prog_t *pgp;	dt_xlator_t *dxp;	dt_dirpath_t *dirp;	int i;	while ((pgp = dt_list_next(&dtp->dt_programs)) != NULL)		dtrace_program_destroy(dtp, pgp);	while ((dxp = dt_list_next(&dtp->dt_xlators)) != NULL)		dt_xlator_destroy(dtp, dxp);	for (idp = dtp->dt_externs; idp != NULL; idp = ndp) {		ndp = idp->di_next;		dt_ident_destroy(idp);	}	if (dtp->dt_macros != NULL)		dt_idhash_destroy(dtp->dt_macros);	if (dtp->dt_aggs != NULL)		dt_idhash_destroy(dtp->dt_aggs);	if (dtp->dt_globals != NULL)		dt_idhash_destroy(dtp->dt_globals);	if (dtp->dt_tls != NULL)		dt_idhash_destroy(dtp->dt_tls);	while ((dmp = dt_list_next(&dtp->dt_modlist)) != NULL)		dt_module_destroy(dtp, dmp);	while ((pvp = dt_list_next(&dtp->dt_provlist)) != NULL)		dt_provider_destroy(dtp, pvp);	if (dtp->dt_procs != NULL)		dt_proc_hash_destroy(dtp);	if (dtp->dt_fd != -1)		(void) close(dtp->dt_fd);	if (dtp->dt_ftfd != -1)		(void) close(dtp->dt_ftfd);	if (dtp->dt_cdefs_fd != -1)		(void) close(dtp->dt_cdefs_fd);	if (dtp->dt_ddefs_fd != -1)		(void) close(dtp->dt_ddefs_fd);	dt_epid_destroy(dtp);	dt_aggid_destroy(dtp);	dt_format_destroy(dtp);	dt_buffered_destroy(dtp);	dt_aggregate_destroy(dtp);	free(dtp->dt_buf.dtbd_data);	dt_pfdict_destroy(dtp);	dt_provmod_destroy(&dtp->dt_provmod);	for (i = 1; i < dtp->dt_cpp_argc; i++)		free(dtp->dt_cpp_argv[i]);	while ((dirp = dt_list_next(&dtp->dt_lib_path)) != NULL) {		dt_list_delete(&dtp->dt_lib_path, dirp);		free(dirp->dir_path);		free(dirp);	}	free(dtp->dt_cpp_argv);	free(dtp->dt_cpp_path);	free(dtp->dt_ld_path);	free(dtp->dt_mods);	free(dtp->dt_provs);	free(dtp);}intdtrace_go(dtrace_hdl_t *dtp){	void *dof;	int err;	if (dtp->dt_active)		return (dt_set_errno(dtp, EINVAL));	/*	 * If a dtrace:::ERROR program and callback are registered, enable the	 * program before we start tracing.  If this fails for a vector open	 * with ENOTTY, we permit dtrace_go() to succeed so that vector clients	 * such as mdb's dtrace module can execute the rest of dtrace_go() even	 * though they do not provide support for the DTRACEIOC_ENABLE ioctl.	 */	if (dtp->dt_errprog != NULL &&	    dtrace_program_exec(dtp, dtp->dt_errprog, NULL) == -1 && (	    dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL))		return (-1); /* dt_errno has been set for us */	if ((dof = dtrace_getopt_dof(dtp)) == NULL)		return (-1); /* dt_errno has been set for us */	err = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof);	dtrace_dof_destroy(dof);	if (err == -1 && (errno != ENOTTY || dtp->dt_vector == NULL))		return (dt_set_errno(dtp, errno));	if (dt_ioctl(dtp, DTRACEIOC_GO, &dtp->dt_beganon) == -1) {		if (errno == EACCES)			return (dt_set_errno(dtp, EDT_DESTRUCTIVE));		if (errno == EALREADY)			return (dt_set_errno(dtp, EDT_ISANON));		if (errno == ENOENT)			return (dt_set_errno(dtp, EDT_NOANON));		if (errno == E2BIG)			return (dt_set_errno(dtp, EDT_ENDTOOBIG));		if (errno == ENOSPC)			return (dt_set_errno(dtp, EDT_BUFTOOSMALL));		return (dt_set_errno(dtp, errno));	}	dtp->dt_active = 1;	if (dt_options_load(dtp) == -1)		return (dt_set_errno(dtp, errno));	return (dt_aggregate_go(dtp));}intdtrace_stop(dtrace_hdl_t *dtp){	if (dtp->dt_stopped)		return (0);	if (dt_ioctl(dtp, DTRACEIOC_STOP, &dtp->dt_endedon) == -1)		return (dt_set_errno(dtp, errno));	dtp->dt_stopped = 1;	return (0);}intdtrace_provider_modules(dtrace_hdl_t *dtp, const char **mods, int nmods){	dt_provmod_t *prov;	int i = 0;	for (prov = dtp->dt_provmod; prov != NULL; prov = prov->dp_next, i++) {		if (i < nmods)			mods[i] = prov->dp_name;	}	return (i);}intdtrace_ctlfd(dtrace_hdl_t *dtp){	return (dtp->dt_fd);}

⌨️ 快捷键说明

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