Exemplo n.º 1
0
int main (int argc, char **argv)
{
	int c;

	errno = 0;

	if (argc < 2)
		usage(argv);

	if (strcmp(argv[1], "report") == 0) {
		trace_report(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "snapshot") == 0) {
		trace_snapshot(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "hist") == 0) {
		trace_hist(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "mem") == 0) {
		trace_mem(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "listen") == 0) {
		trace_listen(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "split") == 0) {
		trace_split(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "restore") == 0) {
		trace_restore(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "stack") == 0) {
		trace_stack(argc, argv);
		exit(0);
	} else if (strcmp(argv[1], "check-events") == 0) {
		const char *tracing;
		int ret;
		struct pevent *pevent = NULL;
		struct plugin_list *list = NULL;

		while ((c = getopt(argc-1, argv+1, "+hN")) >= 0) {
			switch (c) {
			case 'h':
			default:
				usage(argv);
				break;
			case 'N':
				tracecmd_disable_plugins = 1;
				break;
			}
		}
		tracing = tracecmd_get_tracing_dir();

		if (!tracing) {
			printf("Can not find or mount tracing directory!\n"
				"Either tracing is not configured for this "
				"kernel\n"
				"or you do not have the proper permissions to "
				"mount the directory");
			exit(EINVAL);
		}

		pevent = pevent_alloc();
		if (!pevent)
			exit(EINVAL);
		list = tracecmd_load_plugins(pevent);
		ret = tracecmd_fill_local_events(tracing, pevent);
		if (ret || pevent->parsing_failures)
			ret = EINVAL;
		tracecmd_unload_plugins(list, pevent);
		pevent_free(pevent);
		exit(ret);

	} else if (strcmp(argv[1], "record") == 0 ||
		   strcmp(argv[1], "start") == 0 ||
		   strcmp(argv[1], "extract") == 0 ||
		   strcmp(argv[1], "stop") == 0 ||
		   strcmp(argv[1], "stream") == 0 ||
		   strcmp(argv[1], "profile") == 0 ||
		   strcmp(argv[1], "restart") == 0 ||
		   strcmp(argv[1], "reset") == 0) {
		trace_record(argc, argv);
		exit(0);

	} else if (strcmp(argv[1], "stat") == 0) {
		trace_stat(argc, argv);
		exit(0);

	} else if (strcmp(argv[1], "options") == 0) {
		show_plugin_options();
		exit(0);
	} else if (strcmp(argv[1], "show") == 0) {
		const char *buffer = NULL;
		const char *file = "trace";
		const char *cpu = NULL;
		struct buffer_instance *instance = &top_instance;
		char cpu_path[128];
		char *path;
		int snap = 0;
		int pipe = 0;
		int show_name = 0;
		int option_index = 0;
		int stop = 0;
		static struct option long_options[] = {
			{"tracing_on", no_argument, NULL, OPT_tracing_on},
			{"current_tracer", no_argument, NULL, OPT_current_tracer},
			{"buffer_size", no_argument, NULL, OPT_buffer_size_kb},
			{"buffer_total_size", no_argument, NULL, OPT_buffer_total_size_kb},
			{"ftrace_filter", no_argument, NULL, OPT_ftrace_filter},
			{"ftrace_notrace", no_argument, NULL, OPT_ftrace_notrace},
			{"ftrace_pid", no_argument, NULL, OPT_ftrace_pid},
			{"graph_function", no_argument, NULL, OPT_graph_function},
			{"graph_notrace", no_argument, NULL, OPT_graph_notrace},
			{"cpumask", no_argument, NULL, OPT_cpumask},
			{"help", no_argument, NULL, '?'},
			{NULL, 0, NULL, 0}
		};

		while ((c = getopt_long(argc-1, argv+1, "B:c:fsp",
					long_options, &option_index)) >= 0) {
			switch (c) {
			case 'h':
				usage(argv);
				break;
			case 'B':
				if (buffer)
					die("Can only show one buffer at a time");
				buffer = optarg;
				instance = create_instance(optarg);
				if (!instance)
					die("Failed to create instance");
				break;
			case 'c':
				if (cpu)
					die("Can only show one CPU at a time");
				cpu = optarg;
				break;
			case 'f':
				show_name = 1;
				break;
			case 's':
				snap = 1;
				if (pipe)
					die("Can not have -s and -p together");
				break;
			case 'p':
				pipe = 1;
				if (snap)
					die("Can not have -s and -p together");
				break;
			case OPT_tracing_on:
				show_instance_file(instance, "tracing_on");
				stop = 1;
				break;
			case OPT_current_tracer:
				show_instance_file(instance, "current_tracer");
				stop = 1;
				break;
			case OPT_buffer_size_kb:
				show_instance_file(instance, "buffer_size_kb");
				stop = 1;
				break;
			case OPT_buffer_total_size_kb:
				show_instance_file(instance, "buffer_total_size_kb");
				stop = 1;
				break;
			case OPT_ftrace_filter:
				show_instance_file(instance, "set_ftrace_filter");
				stop = 1;
				break;
			case OPT_ftrace_notrace:
				show_instance_file(instance, "set_ftrace_notrace");
				stop = 1;
				break;
			case OPT_ftrace_pid:
				show_instance_file(instance, "set_ftrace_pid");
				stop = 1;
				break;
			case OPT_graph_function:
				show_instance_file(instance, "set_graph_function");
				stop = 1;
				break;
			case OPT_graph_notrace:
				show_instance_file(instance, "set_graph_notrace");
				stop = 1;
				break;
			case OPT_cpumask:
				show_instance_file(instance, "tracing_cpumask");
				stop = 1;
				break;
			default:
				usage(argv);
			}
		}
		if (stop)
			exit(0);
		if (pipe)
			file = "trace_pipe";
		else if (snap)
			file = "snapshot";

		if (cpu) {
			snprintf(cpu_path, 128, "per_cpu/cpu%d/%s", atoi(cpu), file);
			file = cpu_path;
		}
			
		if (buffer) {
			path = malloc(strlen(buffer) + strlen("instances//") +
				      strlen(file) + 1);
			if (path)
				die("Failed to allocate instance path %s", file);
			sprintf(path, "instances/%s/%s", buffer, file);
			file = path;
		}

		if (show_name) {
			char *name;
			name = tracecmd_get_tracing_file(file);
			printf("%s\n", name);
			tracecmd_put_tracing_file(name);
		}
		show_file(file);
		if (buffer)
			free(path);

		exit(0);
	} else if (strcmp(argv[1], "list") == 0) {
		int events = 0;
		int tracer = 0;
		int options = 0;
		int funcs = 0;
		int buffers = 0;
		int clocks = 0;
		int plug = 0;
		int plug_op = 0;
		int flags = 0;
		int show_all = 1;
		int i;
		const char *arg;
		const char *funcre = NULL;
		const char *eventre = NULL;

		for (i = 2; i < argc; i++) {
			arg = NULL;
			if (argv[i][0] == '-') {
				if (i < argc - 1) {
					if (argv[i+1][0] != '-')
						arg = argv[i+1];
				}
				switch (argv[i][1]) {
				case 'h':
					usage(argv);
					break;
				case 'e':
					events = 1;
					eventre = arg;
					show_all = 0;
					break;
				case 'B':
					buffers = 1;
					show_all = 0;
					break;
				case 'C':
					clocks = 1;
					show_all = 0;
					break;
				case 'F':
					flags |= SHOW_EVENT_FORMAT;
					break;
				case 'R':
					flags |= SHOW_EVENT_TRIGGER;
					break;
				case 'l':
					flags |= SHOW_EVENT_FILTER;
					break;
				case 'p':
				case 't':
					tracer = 1;
					show_all = 0;
					break;
				case 'P':
					plug = 1;
					show_all = 0;
					break;
				case 'O':
					plug_op = 1;
					show_all = 0;
					break;
				case 'o':
					options = 1;
					show_all = 0;
					break;
				case 'f':
					funcs = 1;
					funcre = arg;
					show_all = 0;
					break;
				default:
					fprintf(stderr, "list: invalid option -- '%c'\n",
						argv[optind][1]);
					usage(argv);
				}
			}
		}

		if (events)
			show_events(eventre, flags);

		if (tracer)
			show_tracers();

		if (options)
			show_options();

		if (plug)
			show_plugins();

		if (plug_op)
			show_plugin_options();

		if (funcs)
			show_functions(funcre);

		if (buffers)
			show_buffers();

		if (clocks)
			show_clocks();

		if (show_all) {
			printf("events:\n");
			show_events(NULL, 0);
			printf("\ntracers:\n");
			show_tracers();
			printf("\noptions:\n");
			show_options();
		}

		exit(0);

	} else if (strcmp(argv[1], "-h") == 0 ||
		   strcmp(argv[1], "help") == 0) {
		usage(argv);
	} else {
		fprintf(stderr, "unknown command: %s\n", argv[1]);
		usage(argv);
	}

	return 0;
}
Exemplo n.º 2
0
static int __cmd_trace(void)
{
	int ret, rc = EXIT_FAILURE;
	unsigned long offset = 0;
	unsigned long head = 0;
	struct stat perf_stat;
	event_t *event;
	uint32_t size;
	char *buf;

	trace_report();
	register_idle_thread(&threads, &last_match);

	input = open(input_name, O_RDONLY);
	if (input < 0) {
		perror("failed to open file");
		exit(-1);
	}

	ret = fstat(input, &perf_stat);
	if (ret < 0) {
		perror("failed to stat file");
		exit(-1);
	}

	if (!perf_stat.st_size) {
		fprintf(stderr, "zero-sized file, nothing to do!\n");
		exit(0);
	}
	header = perf_header__read(input);
	head = header->data_offset;
	sample_type = perf_header__sample_type(header);

	if (!(sample_type & PERF_SAMPLE_RAW))
		die("No trace sample to read. Did you call perf record "
		    "without -R?");

	if (load_kernel() < 0) {
		perror("failed to load kernel symbols");
		return EXIT_FAILURE;
	}

remap:
	buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
			   MAP_SHARED, input, offset);
	if (buf == MAP_FAILED) {
		perror("failed to mmap file");
		exit(-1);
	}

more:
	event = (event_t *)(buf + head);

	if (head + event->header.size >= page_size * mmap_window) {
		unsigned long shift = page_size * (head / page_size);
		int res;

		res = munmap(buf, page_size * mmap_window);
		assert(res == 0);

		offset += shift;
		head -= shift;
		goto remap;
	}

	size = event->header.size;

	if (!size || process_event(event, offset, head) < 0) {

		/*
		 * assume we lost track of the stream, check alignment, and
		 * increment a single u64 in the hope to catch on again 'soon'.
		 */

		if (unlikely(head & 7))
			head &= ~7ULL;

		size = 8;
	}

	head += size;

	if (offset + head < (unsigned long)perf_stat.st_size)
		goto more;

	rc = EXIT_SUCCESS;
	close(input);

	return rc;
}