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

📄 dtrace.c

📁 Sun Solaris 10 中的 DTrace 组件的源代码。请参看: http://www.sun.com/software/solaris/observability.jsp
💻 C
📖 第 1 页 / 共 3 页
字号:
				if (strcmp(optarg, "4") != 0) {					(void) fprintf(stderr,					    "%s: illegal option -- 6%s\n",					    argv[0], optarg);					return (usage(stderr));				}				g_oflags &= ~DTRACE_O_ILP32;				g_oflags |= DTRACE_O_LP64;				break;			case 'a':				g_grabanon++; /* also checked in pass 2 below */				break;			case 'A':				g_mode = DMODE_ANON;				g_exec = 0;				mode++;				break;			case 'e':				g_exec = 0;				done = 1;				break;			case 'G':				g_mode = DMODE_LINK;				g_oflags |= DTRACE_O_NODEV;				g_cflags |= DTRACE_C_ZDEFS; /* -G implies -Z */				g_exec = 0;				mode++;				break;			case 'l':				g_mode = DMODE_LIST;				g_cflags |= DTRACE_C_ZDEFS; /* -l implies -Z */				mode++;				break;			case 'V':				g_mode = DMODE_VERS;				mode++;				break;			default:				if (strchr(DTRACE_OPTSTR, c) == NULL)					return (usage(stderr));			}		}		if (optind < argc)			g_argv[g_argc++] = argv[optind];	}	if (mode > 1) {		(void) fprintf(stderr, "%s: only one of the [-AGlV] options "		    "can be specified at a time\n", g_pname);		return (E_USAGE);	}	if (g_mode == DMODE_VERS)		return (printf("%s: %s\n", g_pname, _dtrace_version) <= 0);	/*	 * Open libdtrace.  If we are not actually going to be enabling any	 * instrumentation attempt to reopen libdtrace using DTRACE_O_NODEV.	 */	while ((g_dtp = dtrace_open(DTRACE_VERSION, g_oflags, &err)) == NULL) {		if (!(g_oflags & DTRACE_O_NODEV) && !g_exec && !g_grabanon) {			g_oflags |= DTRACE_O_NODEV;			continue;		}		fatal("failed to initialize dtrace: %s\n",		    dtrace_errmsg(NULL, err));	}	g_fd = dtrace_ctlfd(g_dtp); /* save a copy of the control fd */	(void) dtrace_setopt(g_dtp, "bufsize", "4m");	(void) dtrace_setopt(g_dtp, "aggsize", "4m");	/*	 * If -G is specified, enable -xlink=dynamic and -xunodefs to permit	 * references to undefined symbols to remain as unresolved relocations,	 * and enable -xprdefs to permit userland static provider definitions.	 * If -A is specified, enable -xlink=primary to permit static linking	 * only to kernel symbols that are defined in a primary kernel module.	 */	if (g_mode == DMODE_LINK) {		(void) dtrace_setopt(g_dtp, "link", "dynamic");		(void) dtrace_setopt(g_dtp, "unodefs", NULL);		(void) dtrace_setopt(g_dtp, "prdefs", NULL);		g_objc = g_argc;		g_objv = g_argv;		/*		 * We still use g_argv[0], the name of the executable.		 */		g_argc = 1;	} else if (g_mode == DMODE_ANON)		(void) dtrace_setopt(g_dtp, "link", "primary");	/*	 * Now that we have libdtrace open, make a second pass through argv[]	 * to perform any dtrace_setopt() calls and change any compiler flags.	 * We also accumulate any program specifications into our g_cmdv[] at	 * this time; these will compiled as part of the fourth processing pass.	 */	for (optind = 1; optind < argc; optind++) {		while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != EOF) {			switch (c) {			case 'a':				if (dtrace_setopt(g_dtp, "grabanon", 0) != 0)					dfatal("failed to set -a");				break;			case 'b':				if (dtrace_setopt(g_dtp,				    "bufsize", optarg) != 0)					dfatal("failed to set -b %s", optarg);				break;			case 'C':				g_cflags |= DTRACE_C_CPP;				break;			case 'D':				if (dtrace_setopt(g_dtp, "define", optarg) != 0)					dfatal("failed to set -D %s", optarg);				break;			case 'f':				dcp = &g_cmdv[g_cmdc++];				dcp->dc_func = compile_str;				dcp->dc_spec = DTRACE_PROBESPEC_FUNC;				dcp->dc_arg = optarg;				break;			case 'F':				if (dtrace_setopt(g_dtp, "flowindent", 0) != 0)					dfatal("failed to set -F");				break;			case 'H':				if (dtrace_setopt(g_dtp, "cpphdrs", 0) != 0)					dfatal("failed to set -H");				break;			case 'i':				dcp = &g_cmdv[g_cmdc++];				dcp->dc_func = compile_str;				dcp->dc_spec = DTRACE_PROBESPEC_NAME;				dcp->dc_arg = optarg;				break;			case 'I':				if (dtrace_setopt(g_dtp, "incdir", optarg) != 0)					dfatal("failed to set -I %s", optarg);				break;			case 'L':				if (dtrace_setopt(g_dtp, "libdir", optarg) != 0)					dfatal("failed to set -L %s", optarg);				break;			case 'm':				dcp = &g_cmdv[g_cmdc++];				dcp->dc_func = compile_str;				dcp->dc_spec = DTRACE_PROBESPEC_MOD;				dcp->dc_arg = optarg;				break;			case 'n':				dcp = &g_cmdv[g_cmdc++];				dcp->dc_func = compile_str;				dcp->dc_spec = DTRACE_PROBESPEC_NAME;				dcp->dc_arg = optarg;				break;			case 'P':				dcp = &g_cmdv[g_cmdc++];				dcp->dc_func = compile_str;				dcp->dc_spec = DTRACE_PROBESPEC_PROVIDER;				dcp->dc_arg = optarg;				break;			case 'q':				if (dtrace_setopt(g_dtp, "quiet", 0) != 0)					dfatal("failed to set -q");				break;			case 'o':				g_ofile = optarg;				break;			case 's':				dcp = &g_cmdv[g_cmdc++];				dcp->dc_func = compile_file;				dcp->dc_spec = DTRACE_PROBESPEC_NONE;				dcp->dc_arg = optarg;				break;			case 'S':				g_cflags |= DTRACE_C_DIFV;				break;			case 'U':				if (dtrace_setopt(g_dtp, "undef", optarg) != 0)					dfatal("failed to set -U %s", optarg);				break;			case 'v':				g_verbose++;				break;			case 'w':				if (dtrace_setopt(g_dtp, "destructive", 0) != 0)					dfatal("failed to set -w");				break;			case 'x':				if ((p = strchr(optarg, '=')) != NULL)					*p++ = '\0';				if (dtrace_setopt(g_dtp, optarg, p) != 0)					dfatal("failed to set -x %s", optarg);				break;			case 'X':				if (dtrace_setopt(g_dtp, "stdc", optarg) != 0)					dfatal("failed to set -X %s", optarg);				break;			case 'Z':				g_cflags |= DTRACE_C_ZDEFS;				break;			default:				if (strchr(DTRACE_OPTSTR, c) == NULL)					return (usage(stderr));			}		}	}	/*	 * In our third pass we handle any command-line options related to	 * grabbing or creating victim processes.  The behavior of these calls	 * may been affected by any library options set by the second pass.	 */	for (optind = 1; optind < argc; optind++) {		while ((c = getopt(argc, argv, DTRACE_OPTSTR)) != EOF) {			switch (c) {			case 'c':				if ((v = make_argv(optarg)) == NULL)					fatal("failed to allocate memory");				P = dtrace_proc_create(g_dtp, v[0], v);				if (P == NULL)					dfatal(NULL); /* dtrace_errmsg() only */				g_psv[g_psc++] = P;				free(v);				break;			case 'p':				errno = 0;				pid = strtol(optarg, &p, 10);				if (errno != 0 || p == optarg || p[0] != '\0')					fatal("invalid pid: %s\n", optarg);				P = dtrace_proc_grab(g_dtp, pid, 0);				if (P == NULL)					dfatal(NULL); /* dtrace_errmsg() only */				g_psv[g_psc++] = P;				break;			}		}	}	/*	 * In our fourth pass we finish g_cmdv[] by calling dc_func to convert	 * each string or file specification into a compiled program structure.	 */	for (i = 0; i < g_cmdc; i++)		g_cmdv[i].dc_func(&g_cmdv[i]);	if (g_mode != DMODE_LIST) {		if (dtrace_handle_err(g_dtp, &errhandler, NULL) == -1)			dfatal("failed to establish error handler");		if (dtrace_handle_drop(g_dtp, &drophandler, NULL) == -1)			dfatal("failed to establish drop handler");		if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1)			dfatal("failed to establish proc handler");	}	(void) dtrace_getopt(g_dtp, "flowindent", &opt);	g_flowindent = opt != DTRACEOPT_UNSET;	(void) dtrace_getopt(g_dtp, "grabanon", &opt);	g_grabanon = opt != DTRACEOPT_UNSET;	(void) dtrace_getopt(g_dtp, "quiet", &opt);	g_quiet = opt != DTRACEOPT_UNSET;	/*	 * Now make a fifth and final pass over the options that have been	 * turned into programs and saved in g_cmdv[], performing any mode-	 * specific processing.  If g_mode is DMODE_EXEC, we will break out	 * of the switch() and continue on to the data processing loop.  For	 * other modes, we will exit dtrace once mode-specific work is done.	 */	switch (g_mode) {	case DMODE_EXEC:		if (g_ofile != NULL && (g_ofp = fopen(g_ofile, "a")) == NULL)			fatal("failed to open output file '%s'", g_ofile);		for (i = 0; i < g_cmdc; i++)			exec_prog(&g_cmdv[i]);		if (done && !g_grabanon)			return (g_status);		break;	case DMODE_ANON:		if (g_ofile == NULL)			g_ofile = "/kernel/drv/dtrace.conf";		dof_prune(g_ofile); /* strip out any old DOF directives */		etcsystem_prune(); /* string out any forceload directives */		if (g_cmdc == 0)			return (g_status);		if ((g_ofp = fopen(g_ofile, "a")) == NULL)			fatal("failed to open output file '%s'", g_ofile);		for (i = 0; i < g_cmdc; i++) {			anon_prog(&g_cmdv[i],			    dtrace_dof_create(g_dtp, g_cmdv[i].dc_prog, 0), i);		}		/*		 * Dump out the DOF corresponding to the error handler and the		 * current options as the final DOF property in the .conf file.		 */		anon_prog(NULL, dtrace_geterr_dof(g_dtp), i++);		anon_prog(NULL, dtrace_getopt_dof(g_dtp), i++);		if (fclose(g_ofp) == EOF)			fatal("failed to close output file '%s'", g_ofile);		/*		 * These messages would use notice() rather than error(), but		 * we don't want them suppressed when -A is run on a D program		 * that itself contains a #pragma D option quiet.		 */		error("saved anonymous enabling in %s\n", g_ofile);		etcsystem_add();		error("run update_drv(1M) or reboot to enable changes\n");		return (g_status);	case DMODE_LINK:		for (i = 0; i < g_cmdc; i++)			link_prog(&g_cmdv[i]);		return (g_status);	case DMODE_LIST:		if (g_ofile != NULL && (g_ofp = fopen(g_ofile, "a")) == NULL)			fatal("failed to open output file '%s'", g_ofile);		oprintf("%5s %10s %17s %33s %s\n",		    "ID", "PROVIDER", "MODULE", "FUNCTION", "NAME");		for (i = 0; i < g_cmdc; i++)			list_prog(&g_cmdv[i]);		if (g_cmdc == 0)			list_probes();		return (g_status);	}	/*	 * If -a and -Z were not specified and no probes have been matched, no	 * probe criteria was specified on the command line and we abort.	 */	if (g_total == 0 && !g_grabanon && !(g_cflags & DTRACE_C_ZDEFS))		dfatal("no probes %s\n", g_cmdc ? "matched" : "specified");	/*	 * Start tracing.  Once we dtrace_go(), reload any options that affect	 * our globals in case consuming anonymous state has changed them.	 */	go();	(void) dtrace_getopt(g_dtp, "flowindent", &opt);	g_flowindent = opt != DTRACEOPT_UNSET;	(void) dtrace_getopt(g_dtp, "grabanon", &opt);	g_grabanon = opt != DTRACEOPT_UNSET;	(void) dtrace_getopt(g_dtp, "quiet", &opt);	g_quiet = opt != DTRACEOPT_UNSET;	(void) dtrace_getopt(g_dtp, "destructive", &opt);	if (opt != DTRACEOPT_UNSET)		notice("allowing destructive actions\n");	(void) sigemptyset(&act.sa_mask);	act.sa_flags = 0;	act.sa_handler = intr;	(void) sigaction(SIGINT, &act, NULL);	(void) sigaction(SIGTERM, &act, NULL);	/*	 * Now that tracing is active and we are ready to consume trace data,	 * continue any grabbed or created processes, setting them running	 * using the /proc control mechanism inside of libdtrace.	 */	for (i = 0; i < g_psc; i++)		dtrace_proc_continue(g_dtp, g_psv[i]);	g_pslive = g_psc; /* count for prochandler() */	do {		if (!g_intr && !done)			dtrace_sleep(g_dtp);		if (g_newline) {			/*			 * Output a newline just to make the output look			 * slightly cleaner.  Note that we do this even in			 * "quiet" mode...			 */			oprintf("\n");			g_newline = 0;		}		if (done || g_intr || (g_psc != 0 && g_pslive == 0)) {			done = 1;			if (dtrace_stop(g_dtp) == -1)				dfatal("couldn't stop tracing");		}		switch (dtrace_work(g_dtp, g_ofp, chew, chewrec, NULL)) {		case DTRACE_WORKSTATUS_DONE:			done = 1;			break;		case DTRACE_WORKSTATUS_OKAY:			break;		default:			if (!g_impatient && dtrace_errno(g_dtp) != EINTR)				dfatal("processing aborted");		}		if (fflush(g_ofp) == EOF)			clearerr(g_ofp);	} while (!done);	oprintf("\n");	if (!g_impatient) {		if (dtrace_aggregate_print(g_dtp, g_ofp, NULL) == -1 &&		    dtrace_errno(g_dtp) != EINTR)			dfatal("failed to print aggregations");	}	dtrace_close(g_dtp);	return (g_status);}

⌨️ 快捷键说明

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