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 + -
显示快捷键?