dt_options.c

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

C
837
字号
}static intdt_opt_runtime(dtrace_hdl_t *dtp, const char *arg, uintptr_t option){	char *end;	dtrace_optval_t val = 0;	if (arg != NULL) {		errno = 0;		val = strtoull(arg, &end, 0);		if (*end != '\0' || errno != 0 || val < 0)			return (dt_set_errno(dtp, EDT_BADOPTVAL));	}	dtp->dt_options[option] = val;	return (0);}static intdt_opt_size(dtrace_hdl_t *dtp, const char *arg, uintptr_t option){	char *end;	int len;	dtrace_optval_t mul = 1, val = 0;	if (arg != NULL) {		len = strlen(arg);		errno = 0;		switch (arg[len - 1]) {		case 't':		case 'T':			mul *= 1024;			/*FALLTHRU*/		case 'g':		case 'G':			mul *= 1024;			/*FALLTHRU*/		case 'm':		case 'M':			mul *= 1024;			/*FALLTHRU*/		case 'k':		case 'K':			mul *= 1024;			/*FALLTHRU*/		default:			break;		}		val = strtoull(arg, &end, 0) * mul;		if ((mul > 1 && end != &arg[len - 1]) ||		    (mul == 1 && *end != '\0') || val < 0 ||		    errno != 0 || val == DTRACEOPT_UNSET)			return (dt_set_errno(dtp, EDT_BADOPTVAL));	}	dtp->dt_options[option] = val;	return (0);}static intdt_opt_rate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option){	char *end;	int i;	dtrace_optval_t mul = 1, val = 0;	const struct {		char *name;		hrtime_t mul;	} suffix[] = {		{ "ns", 	NANOSEC / NANOSEC },		{ "nsec",	NANOSEC / NANOSEC },		{ "us",		NANOSEC / MICROSEC },		{ "usec",	NANOSEC / MICROSEC },		{ "ms",		NANOSEC / MILLISEC },		{ "msec",	NANOSEC / MILLISEC },		{ "s",		NANOSEC / SEC },		{ "sec",	NANOSEC / SEC },		{ "m",		NANOSEC * (hrtime_t)60 },		{ "min",	NANOSEC * (hrtime_t)60 },		{ "h",		NANOSEC * (hrtime_t)60 * (hrtime_t)60 },		{ "hour",	NANOSEC * (hrtime_t)60 * (hrtime_t)60 },		{ "d",		NANOSEC * (hrtime_t)(24 * 60 * 60) },		{ "day",	NANOSEC * (hrtime_t)(24 * 60 * 60) },		{ "hz",		0 },		{ NULL }	};	if (arg != NULL) {		errno = 0;		val = strtoull(arg, &end, 0);		for (i = 0; suffix[i].name != NULL; i++) {			if (strcasecmp(suffix[i].name, end) == 0) {				mul = suffix[i].mul;				break;			}		}		if (suffix[i].name == NULL && *end != '\0' || val < 0)			return (dt_set_errno(dtp, EDT_BADOPTVAL));		if (mul == 0) {			/*			 * The rate has been specified in frequency-per-second.			 */			if (val != 0)				val = NANOSEC / val;		} else {			val *= mul;		}	}	dtp->dt_options[option] = val;	return (0);}/* * When setting the strsize option, set the option in the dt_options array * using dt_opt_size() as usual, and then update the definition of the CTF * type for the D intrinsic "string" to be an array of the corresponding size. * If any errors occur, reset dt_options[option] to its previous value. */static intdt_opt_strsize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option){	dtrace_optval_t val = dtp->dt_options[option];	ctf_file_t *fp = DT_STR_CTFP(dtp);	ctf_id_t type = ctf_type_resolve(fp, DT_STR_TYPE(dtp));	ctf_arinfo_t r;	if (dt_opt_size(dtp, arg, option) != 0)		return (-1); /* dt_errno is set for us */	if (dtp->dt_options[option] > UINT_MAX) {		dtp->dt_options[option] = val;		return (dt_set_errno(dtp, EOVERFLOW));	}	if (ctf_array_info(fp, type, &r) == CTF_ERR) {		dtp->dt_options[option] = val;		dtp->dt_ctferr = ctf_errno(fp);		return (dt_set_errno(dtp, EDT_CTF));	}	r.ctr_nelems = (uint_t)dtp->dt_options[option];	if (ctf_set_array(fp, type, &r) == CTF_ERR ||	    ctf_update(fp) == CTF_ERR) {		dtp->dt_options[option] = val;		dtp->dt_ctferr = ctf_errno(fp);		return (dt_set_errno(dtp, EDT_CTF));	}	return (0);}static const struct {	const char *dtbp_name;	int dtbp_policy;} _dtrace_bufpolicies[] = {	{ "ring", DTRACEOPT_BUFPOLICY_RING },	{ "fill", DTRACEOPT_BUFPOLICY_FILL },	{ "switch", DTRACEOPT_BUFPOLICY_SWITCH },	{ NULL, 0 }};/*ARGSUSED*/static intdt_opt_bufpolicy(dtrace_hdl_t *dtp, const char *arg, uintptr_t option){	dtrace_optval_t policy = DTRACEOPT_UNSET;	int i;	if (arg == NULL)		return (dt_set_errno(dtp, EDT_BADOPTVAL));	for (i = 0; _dtrace_bufpolicies[i].dtbp_name != NULL; i++) {		if (strcmp(_dtrace_bufpolicies[i].dtbp_name, arg) == 0) {			policy = _dtrace_bufpolicies[i].dtbp_policy;			break;		}	}	if (policy == DTRACEOPT_UNSET)		return (dt_set_errno(dtp, EDT_BADOPTVAL));	dtp->dt_options[DTRACEOPT_BUFPOLICY] = policy;	return (0);}static const struct {	const char *dtbr_name;	int dtbr_policy;} _dtrace_bufresize[] = {	{ "auto", DTRACEOPT_BUFRESIZE_AUTO },	{ "manual", DTRACEOPT_BUFRESIZE_MANUAL },	{ NULL, 0 }};/*ARGSUSED*/static intdt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option){	dtrace_optval_t policy = DTRACEOPT_UNSET;	int i;	if (arg == NULL)		return (dt_set_errno(dtp, EDT_BADOPTVAL));	for (i = 0; _dtrace_bufresize[i].dtbr_name != NULL; i++) {		if (strcmp(_dtrace_bufresize[i].dtbr_name, arg) == 0) {			policy = _dtrace_bufresize[i].dtbr_policy;			break;		}	}	if (policy == DTRACEOPT_UNSET)		return (dt_set_errno(dtp, EDT_BADOPTVAL));	dtp->dt_options[DTRACEOPT_BUFRESIZE] = policy;	return (0);}intdt_options_load(dtrace_hdl_t *dtp){	dof_hdr_t hdr, *dof;	dof_sec_t *sec;	size_t offs;	int i;	/*	 * To load the option values, we need to ask the kernel to provide its	 * DOF, which we'll sift through to look for OPTDESC sections.	 */	bzero(&hdr, sizeof (dof_hdr_t));	hdr.dofh_loadsz = sizeof (dof_hdr_t);	if (dt_ioctl(dtp, DTRACEIOC_DOFGET, &hdr) == -1)		return (dt_set_errno(dtp, errno));	if (hdr.dofh_loadsz < sizeof (dof_hdr_t))		return (dt_set_errno(dtp, EINVAL));	dof = alloca(hdr.dofh_loadsz);	bzero(dof, sizeof (dof_hdr_t));	dof->dofh_loadsz = hdr.dofh_loadsz;	for (i = 0; i < DTRACEOPT_MAX; i++)		dtp->dt_options[i] = DTRACEOPT_UNSET;	if (dt_ioctl(dtp, DTRACEIOC_DOFGET, dof) == -1)		return (dt_set_errno(dtp, errno));	for (i = 0; i < dof->dofh_secnum; i++) {		sec = (dof_sec_t *)((uintptr_t)dof +		    dof->dofh_secoff + i * dof->dofh_secsize);		if (sec->dofs_type != DOF_SECT_OPTDESC)			continue;		break;	}	for (offs = 0; offs < sec->dofs_size; offs += sec->dofs_entsize) {		dof_optdesc_t *opt = (dof_optdesc_t *)((uintptr_t)dof +		    sec->dofs_offset + offs);		if (opt->dofo_strtab != DOF_SECIDX_NONE)			continue;		if (opt->dofo_option >= DTRACEOPT_MAX)			continue;		dtp->dt_options[opt->dofo_option] = opt->dofo_value;	}	return (0);}typedef struct dt_option {	const char *o_name;	int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);	uintptr_t o_option;} dt_option_t;/* * Compile-time options. */static const dt_option_t _dtrace_ctoptions[] = {	{ "aggpercpu", dt_opt_agg, DTRACE_A_PERCPU },	{ "amin", dt_opt_amin },	{ "argref", dt_opt_cflags, DTRACE_C_ARGREF },	{ "core", dt_opt_core },	{ "cpp", dt_opt_cflags, DTRACE_C_CPP },	{ "cpphdrs", dt_opt_cpp_hdrs },	{ "cpppath", dt_opt_cpp_path },	{ "ctypes", dt_opt_ctypes },	{ "defaultargs", dt_opt_cflags, DTRACE_C_DEFARG },	{ "dtypes", dt_opt_dtypes },	{ "debug", dt_opt_debug },	{ "define", dt_opt_cpp_opts, (uintptr_t)"-D" },	{ "empty", dt_opt_cflags, DTRACE_C_EMPTY },	{ "errtags", dt_opt_cflags, DTRACE_C_ETAGS },	{ "evaltime", dt_opt_evaltime },	{ "incdir", dt_opt_cpp_opts, (uintptr_t)"-I" },	{ "iregs", dt_opt_iregs },	{ "kdefs", dt_opt_invcflags, DTRACE_C_KNODEF },	{ "knodefs", dt_opt_cflags, DTRACE_C_KNODEF },	{ "lazyload", dt_opt_lazyload },	{ "ldpath", dt_opt_ld_path },	{ "libdir", dt_opt_libdir },	{ "link", dt_opt_link },	{ "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },	{ "pgmax", dt_opt_pgmax },	{ "pspec", dt_opt_cflags, DTRACE_C_PSPEC },	{ "prdefs", dt_opt_cflags, DTRACE_C_PRDEFS },	{ "stdc", dt_opt_stdc },	{ "tree", dt_opt_tree },	{ "tregs", dt_opt_tregs },	{ "udefs", dt_opt_invcflags, DTRACE_C_UNODEF },	{ "undef", dt_opt_cpp_opts, (uintptr_t)"-U" },	{ "unodefs", dt_opt_cflags, DTRACE_C_UNODEF },	{ "verbose", dt_opt_cflags, DTRACE_C_DIFV },	{ "version", dt_opt_version },	{ "zdefs", dt_opt_cflags, DTRACE_C_ZDEFS },	{ NULL }};/* * Run-time options. */static const dt_option_t _dtrace_rtoptions[] = {	{ "aggrate", dt_opt_rate, DTRACEOPT_AGGRATE },	{ "aggsize", dt_opt_size, DTRACEOPT_AGGSIZE },	{ "bufsize", dt_opt_size, DTRACEOPT_BUFSIZE },	{ "bufpolicy", dt_opt_bufpolicy, DTRACEOPT_BUFPOLICY },	{ "bufresize", dt_opt_bufresize, DTRACEOPT_BUFRESIZE },	{ "cleanrate", dt_opt_rate, DTRACEOPT_CLEANRATE },	{ "cpu", dt_opt_runtime, DTRACEOPT_CPU },	{ "destructive", dt_opt_runtime, DTRACEOPT_DESTRUCTIVE },	{ "dynvarsize", dt_opt_size, DTRACEOPT_DYNVARSIZE },	{ "flowindent", dt_opt_runtime, DTRACEOPT_FLOWINDENT },	{ "grabanon", dt_opt_runtime, DTRACEOPT_GRABANON },	{ "jstackframes", dt_opt_runtime, DTRACEOPT_JSTACKFRAMES },	{ "jstackstrsize", dt_opt_runtime, DTRACEOPT_JSTACKSTRSIZE },	{ "nspec", dt_opt_runtime, DTRACEOPT_NSPEC },	{ "quiet", dt_opt_runtime, DTRACEOPT_QUIET },	{ "rawbytes", dt_opt_runtime, DTRACEOPT_RAWBYTES },	{ "specsize", dt_opt_size, DTRACEOPT_SPECSIZE },	{ "stackframes", dt_opt_runtime, DTRACEOPT_STACKFRAMES },	{ "stackindent", dt_opt_runtime, DTRACEOPT_STACKINDENT },	{ "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE },	{ "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE },	{ "switchrate", dt_opt_rate, DTRACEOPT_SWITCHRATE },	{ "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES },	{ NULL }};intdtrace_getopt(dtrace_hdl_t *dtp, const char *opt, dtrace_optval_t *val){	const dt_option_t *op;	if (opt == NULL)		return (dt_set_errno(dtp, EINVAL));	/*	 * We only need to search the run-time options -- it's not legal	 * to get the values of compile-time options.	 */	for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {		if (strcmp(op->o_name, opt) == 0) {			*val = dtp->dt_options[op->o_option];			return (0);		}	}	return (dt_set_errno(dtp, EDT_BADOPTNAME));}intdtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val){	const dt_option_t *op;	if (opt == NULL)		return (dt_set_errno(dtp, EINVAL));	for (op = _dtrace_ctoptions; op->o_name != NULL; op++) {		if (strcmp(op->o_name, opt) == 0)			return (op->o_func(dtp, val, op->o_option));	}	for (op = _dtrace_rtoptions; op->o_name != NULL; op++) {		if (strcmp(op->o_name, opt) == 0) {			/*			 * Currently, no run-time option may be set while			 * tracing is active.			 */			if (dtp->dt_active)				return (dt_set_errno(dtp, EDT_ACTIVE));			return (op->o_func(dtp, val, op->o_option));		}	}	return (dt_set_errno(dtp, EDT_BADOPTNAME));}

⌨️ 快捷键说明

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