⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dtrace.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 3 页
字号:
exec_prog(const dtrace_cmd_t *dcp){	dtrace_proginfo_t dpi;	if (!g_exec) {		dtrace_program_info(g_dtp, dcp->dc_prog, &dpi);	} else if (dtrace_program_exec(g_dtp, dcp->dc_prog, &dpi) == -1) {		dfatal("failed to enable '%s'", dcp->dc_name);	} else {		notice("%s '%s' matched %u probe%s\n",		    dcp->dc_desc, dcp->dc_name,		    dpi.dpi_matches, dpi.dpi_matches == 1 ? "" : "s");	}	if (g_verbose) {		oprintf("Stability data for %s %s:\n",		    dcp->dc_desc, dcp->dc_name);		oprintf("\tMinimum probe description attributes\n");		oprintf("\t\tIdentifier Names: %s\n",		    dtrace_stability_name(dpi.dpi_descattr.dtat_name));		oprintf("\t\tData Semantics:   %s\n",		    dtrace_stability_name(dpi.dpi_descattr.dtat_data));		oprintf("\t\tDependency Class: %s\n",		    dtrace_class_name(dpi.dpi_descattr.dtat_class));		oprintf("\tMinimum probe statement attributes\n");		oprintf("\t\tIdentifier Names: %s\n",		    dtrace_stability_name(dpi.dpi_stmtattr.dtat_name));		oprintf("\t\tData Semantics:   %s\n",		    dtrace_stability_name(dpi.dpi_stmtattr.dtat_data));		oprintf("\t\tDependency Class: %s\n",		    dtrace_class_name(dpi.dpi_stmtattr.dtat_class));	}	g_total += dpi.dpi_matches;}/* * Print out the specified DOF buffer as a set of ASCII bytes appropriate for * storing in a driver.conf(4) file associated with the dtrace driver. */static voidanon_prog(const dtrace_cmd_t *dcp, dof_hdr_t *dof, int n){	const uchar_t *p, *q;	if (dof == NULL)		dfatal("failed to create DOF image for '%s'", dcp->dc_name);	p = (uchar_t *)dof;	q = p + dof->dofh_loadsz;	oprintf("dof-data-%d=0x%x", n, *p++);	while (p < q)		oprintf(",0x%x", *p++);	oprintf(";\n");	dtrace_dof_destroy(dof);}/* * Link the specified D program in DOF form into an ELF file for use in either * helpers, userland provider definitions, or both.  If -o was specified, that * path is used as the output file name.  If -o wasn't specified and the input * program is from a script whose name is %.d, use basename(%.o) as the output * file name.  Otherwise we use "d.out" as the default output file name. */static voidlink_prog(const dtrace_cmd_t *dcp){	char file[PATH_MAX], *p;	if (g_ofile != NULL) {		(void) snprintf(file, sizeof (file), g_cmdc > 1 ?		    "%s.%d" : "%s", g_ofile, (int)(dcp - g_cmdv));	} else if ((p = strrchr(dcp->dc_arg, '.')) != NULL &&	    strcmp(p, ".d") == 0) {		p[0] = '\0'; /* strip .d suffix */		(void) snprintf(file, sizeof (file),		    "%s.o", basename(dcp->dc_arg));	} else {		(void) snprintf(file, sizeof (file), g_cmdc > 1 ?		    "%s.%d" : "%s", "d.out", (int)(dcp - g_cmdv));	}	if (dtrace_program_link(g_dtp, dcp->dc_prog, 0,	    file, g_objc - 1, g_objv + 1) != 0)		dfatal("failed to link %s %s", dcp->dc_desc, dcp->dc_name);}/*ARGSUSED*/static intlist_stmt(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,    dtrace_stmtdesc_t *stp, dtrace_ecbdesc_t **last){	dtrace_ecbdesc_t *edp = stp->dtsd_ecbdesc;	dtrace_probedesc_t probe;	dtrace_id_t id = 0;	if (edp == *last)		return (0);	for (;;) {		bcopy(&edp->dted_probe, &probe, sizeof (dtrace_probedesc_t));		probe.dtpd_id = id;		if (ioctl(g_fd, DTRACEIOC_PROBEMATCH, &probe) == -1)			break;		oprintf("%5d %10s %17s %33s %s\n", probe.dtpd_id,		    probe.dtpd_provider, probe.dtpd_mod,		    probe.dtpd_func, probe.dtpd_name);		id = probe.dtpd_id + 1;	}	if (errno == EINVAL) {		error("%s:%s:%s:%s contains too many glob meta-characters\n",		    edp->dted_probe.dtpd_provider, edp->dted_probe.dtpd_mod,		    edp->dted_probe.dtpd_func, edp->dted_probe.dtpd_name);	}	*last = edp;	return (0);}/* * List the probes corresponding to the specified program by iterating over * each statement and then matching probes to the statement probe descriptions. */static voidlist_prog(const dtrace_cmd_t *dcp){	dtrace_ecbdesc_t *last = NULL;	(void) dtrace_stmt_iter(g_dtp, dcp->dc_prog,	    (dtrace_stmt_f *)list_stmt, &last);}static voidcompile_file(dtrace_cmd_t *dcp){	char *arg0;	FILE *fp;	if ((fp = fopen(dcp->dc_arg, "r")) == NULL)		fatal("failed to open %s", dcp->dc_arg);	arg0 = g_argv[0];	g_argv[0] = dcp->dc_arg;	if ((dcp->dc_prog = dtrace_program_fcompile(g_dtp, fp,	    g_cflags, g_argc, g_argv)) == NULL)		dfatal("failed to compile script %s", dcp->dc_arg);	g_argv[0] = arg0;	(void) fclose(fp);	dcp->dc_desc = "script";	dcp->dc_name = dcp->dc_arg;}static voidcompile_str(dtrace_cmd_t *dcp){	char *p;	if ((dcp->dc_prog = dtrace_program_strcompile(g_dtp, dcp->dc_arg,	    dcp->dc_spec, g_cflags | DTRACE_C_PSPEC, g_argc, g_argv)) == NULL)		dfatal("invalid probe specifier %s", dcp->dc_arg);	if ((p = strpbrk(dcp->dc_arg, "{/;")) != NULL)		*p = '\0'; /* crop name for reporting */	dcp->dc_desc = "description";	dcp->dc_name = dcp->dc_arg;}/*ARGSUSED*/static voidprochandler(struct ps_prochandle *P, void *arg){	const psinfo_t *prp = Ppsinfo(P);	int pid = Pstatus(P)->pr_pid;	char name[SIG2STR_MAX];	switch (Pstate(P)) {	case PS_UNDEAD:		/*		 * Ideally we would like to always report pr_wstat here, but it		 * isn't possible given current /proc semantics.  If we grabbed		 * the process, Ppsinfo() will either fail or return a zeroed		 * psinfo_t depending on how far the parent is in reaping it.		 * When /proc provides a stable pr_wstat in the status file,		 * this code can be improved by examining this new pr_wstat.		 */		if (prp != NULL && WIFSIGNALED(prp->pr_wstat)) {			notice("pid %d terminated by %s\n", pid,			    proc_signame(WTERMSIG(prp->pr_wstat),			    name, sizeof (name)));		} else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) {			notice("pid %d exited with status %d\n",			    pid, WEXITSTATUS(prp->pr_wstat));		} else {			notice("pid %d has exited\n", pid);		}		g_pslive--;		break;	case PS_LOST:		notice("pid %d exec'd a set-id or unobservable program\n", pid);		g_pslive--;		break;	}}/*ARGSUSED*/static interrhandler(dtrace_errdata_t *data, void *arg){	error(data->dteda_msg);	return (DTRACE_HANDLE_OK);}/*ARGSUSED*/static intdrophandler(dtrace_dropdata_t *data, void *arg){	error(data->dtdda_msg);	return (DTRACE_HANDLE_OK);}/*ARGSUSED*/static intchewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg){	dtrace_actkind_t act;	uintptr_t addr;	if (rec == NULL) {		/*		 * We have processed the final record; output the newline if		 * we're not in quiet mode.		 */		if (!g_quiet)			oprintf("\n");		return (DTRACE_CONSUME_NEXT);	}	act = rec->dtrd_action;	addr = (uintptr_t)data->dtpda_data;	if (act == DTRACEACT_EXIT) {		g_status = *((uint32_t *)addr);		return (DTRACE_CONSUME_NEXT);	}	return (DTRACE_CONSUME_THIS);}/*ARGSUSED*/static intchew(const dtrace_probedata_t *data, void *arg){	dtrace_probedesc_t *pd = data->dtpda_pdesc;	processorid_t cpu = data->dtpda_cpu;	static int heading;	if (g_impatient) {		g_newline = 0;		return (DTRACE_CONSUME_ABORT);	}	if (heading == 0) {		if (!g_flowindent) {			if (!g_quiet) {				oprintf("%3s %6s %32s\n",				    "CPU", "ID", "FUNCTION:NAME");			}		} else {			oprintf("%3s %-41s\n", "CPU", "FUNCTION");		}		heading = 1;	}	if (!g_flowindent) {		if (!g_quiet) {			char name[DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 2];			(void) snprintf(name, sizeof (name), "%s:%s",			    pd->dtpd_func, pd->dtpd_name);			oprintf("%3d %6d %32s ", cpu, pd->dtpd_id, name);		}	} else {		int indent = data->dtpda_indent;		char *name;		size_t len;		if (data->dtpda_flow == DTRACEFLOW_NONE) {			len = indent + DTRACE_FUNCNAMELEN + DTRACE_NAMELEN + 5;			name = alloca(len);			(void) snprintf(name, len, "%*s%s%s:%s", indent, "",			    data->dtpda_prefix, pd->dtpd_func,			    pd->dtpd_name);		} else {			len = indent + DTRACE_FUNCNAMELEN + 5;			name = alloca(len);			(void) snprintf(name, len, "%*s%s%s", indent, "",			    data->dtpda_prefix, pd->dtpd_func);		}		oprintf("%3d %-41s ", cpu, name);	}	return (DTRACE_CONSUME_THIS);}static voidgo(void){	int i;	struct {		char *name;		char *optname;		dtrace_optval_t val;	} bufs[] = {		{ "buffer size", "bufsize" },		{ "aggregation size", "aggsize" },		{ "speculation size", "specsize" },		{ "dynamic variable size", "dynvarsize" },		{ NULL }	}, rates[] = {		{ "cleaning rate", "cleanrate" },		{ "status rate", "statusrate" },		{ NULL }	};	for (i = 0; bufs[i].name != NULL; i++) {		if (dtrace_getopt(g_dtp, bufs[i].optname, &bufs[i].val) == -1)			fatal("couldn't get option %s", bufs[i].optname);	}	for (i = 0; rates[i].name != NULL; i++) {		if (dtrace_getopt(g_dtp, rates[i].optname, &rates[i].val) == -1)			fatal("couldn't get option %s", rates[i].optname);	}	if (dtrace_go(g_dtp) == -1)		dfatal("could not enable tracing");	for (i = 0; bufs[i].name != NULL; i++) {		dtrace_optval_t j = 0, mul = 10;		dtrace_optval_t nsize;		if (bufs[i].val == DTRACEOPT_UNSET)			continue;		(void) dtrace_getopt(g_dtp, bufs[i].optname, &nsize);		if (nsize == DTRACEOPT_UNSET || nsize == 0)			continue;		if (nsize >= bufs[i].val - sizeof (uint64_t))			continue;		for (; (INT64_C(1) << mul) <= nsize; j++, mul += 10)			continue;		if (!(nsize & ((INT64_C(1) << (mul - 10)) - 1))) {			error("%s lowered to %lld%c\n", bufs[i].name,			    (long long)nsize >> (mul - 10), " kmgtpe"[j]);		} else {			error("%s lowered to %lld bytes\n", bufs[i].name,			    (long long)nsize);		}	}	for (i = 0; rates[i].name != NULL; i++) {		dtrace_optval_t nval;		char *dir;		if (rates[i].val == DTRACEOPT_UNSET)			continue;		(void) dtrace_getopt(g_dtp, rates[i].optname, &nval);		if (nval == DTRACEOPT_UNSET || nval == 0)			continue;		if (rates[i].val == nval)			continue;		dir = nval > rates[i].val ? "reduced" : "increased";		if (nval <= NANOSEC && (NANOSEC % nval) == 0) {			error("%s %s to %lld hz\n", rates[i].name, dir,			    (long long)NANOSEC / (long long)nval);			continue;		}		if ((nval % NANOSEC) == 0) {			error("%s %s to once every %lld seconds\n",			    rates[i].name, dir,			    (long long)nval / (long long)NANOSEC);			continue;		}		error("%s %s to once every %lld nanoseconds\n",		    rates[i].name, dir, (long long)nval);	}}/*ARGSUSED*/static voidintr(int signo){	if (!g_intr)		g_newline = 1;	if (g_intr++)		g_impatient = 1;}intmain(int argc, char *argv[]){	dtrace_bufdesc_t buf;	struct sigaction act;	dtrace_status_t status[2];	dtrace_optval_t opt;	dtrace_cmd_t *dcp;	int done = 0, mode = 0;	int err, i;	char c, *p, **v;	struct ps_prochandle *P;	pid_t pid;	g_pname = basename(argv[0]);	if (argc == 1)		return (usage(stderr));	if ((g_argv = malloc(sizeof (char *) * argc)) == NULL ||	    (g_cmdv = malloc(sizeof (dtrace_cmd_t) * argc)) == NULL ||	    (g_psv = malloc(sizeof (struct ps_prochandle *) * argc)) == NULL)		fatal("failed to allocate memory for arguments");	g_argv[g_argc++] = argv[0];	/* propagate argv[0] to D as $0/$$0 */	argv[0] = g_pname;		/* rewrite argv[0] for getopt errors */	bzero(status, sizeof (status));	bzero(&buf, sizeof (buf));	/*	 * Make an initial pass through argv[] processing any arguments that	 * affect our behavior mode (g_mode) and flags used for dtrace_open().	 * We also accumulate arguments that are not affiliated with getopt	 * options into g_argv[], and abort if any invalid options are found.	 */	for (optind = 1; optind < argc; optind++) {		while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != EOF) {			switch (c) {			case '3':				if (strcmp(optarg, "2") != 0) {					(void) fprintf(stderr,					    "%s: illegal option -- 3%s\n",					    argv[0], optarg);					return (usage(stderr));				}				g_oflags &= ~DTRACE_O_LP64;				g_oflags |= DTRACE_O_ILP32;				break;			case '6':

⌨️ 快捷键说明

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