Example #1
0
static void show_buffers(void)
{
	struct dirent *dent;
	DIR *dir;
	char *path;
	int printed = 0;

	path = tracecmd_get_tracing_file("instances");
	dir = opendir(path);
	tracecmd_put_tracing_file(path);
	if (!dir)
		die("Can not read instance directory");

	while ((dent = readdir(dir))) {
		const char *name = dent->d_name;

		if (strcmp(name, ".") == 0 ||
		    strcmp(name, "..") == 0)
			continue;

		printf("%s\n", name);
		printed = 1;
	}
	closedir(dir);

	if (!printed)
		printf("No buffer instances defined\n");
}
Example #2
0
static void report_event_triggers(struct buffer_instance *instance)
{
	struct event_iter *iter;
	char *path;
	char *system;
	enum event_iter_type type;
	enum event_process processed = PROCESSED_NONE;

	path = get_instance_file(instance, "events");
	if (!path)
		die("malloc");

	iter = trace_event_iter_alloc(path);

	processed = PROCESSED_NONE;
	system = NULL;
	while ((type = trace_event_iter_next(iter, path, system))) {

		if (type == EVENT_ITER_SYSTEM) {
			system = iter->system_dent->d_name;
			continue;
		}

		process_event_trigger(path, iter, &processed);
	}

	trace_event_iter_free(iter);

	tracecmd_put_tracing_file(path);
}
Example #3
0
static char *get_event_file(const char *type, char *buf, int len)
{
	char *system;
	char *event;
	char *path;
	char *file;

	if (buf[len-1] == '\n')
		buf[len-1] = '\0';

	system = strtok(buf, ":");
	if (!system)
		die("no system found in %s", buf);

	event = strtok(NULL, ":");
	if (!event)
		die("no event found in %s\n", buf);

	path = tracecmd_get_tracing_file("events");
	file = malloc(strlen(path) + strlen(system) + strlen(event) +
		      strlen(type) + strlen("///") + 1);
	if (!file)
		die("Failed to allocate event file %s %s", system, event);
	sprintf(file, "%s/%s/%s/%s", path, system, event, type);
	tracecmd_put_tracing_file(path);

	return file;
}
Example #4
0
static void read_trace(void)
{
	FILE *fp;
	char *path;
	char *buf = NULL;
	size_t n;
	int r;

	if (read_proc() == '1')
		printf("(stack tracer running)\n");
	else
		printf("(stack tracer not running)\n");

	path = tracecmd_get_tracing_file("stack_trace");
	fp = fopen(path, "r");
	if (!fp)
		die("reading to '%s'", path);
	tracecmd_put_tracing_file(path);

	while ((r = getline(&buf, &n, fp)) >= 0) {
		/*
		 * Skip any line that starts with a '#'.
		 * Those talk about how to enable stack tracing
		 * within the debugfs system. We don't care about that.
		 */
		if (buf[0] != '#')
			printf("%s", buf);

		free(buf);
		buf = NULL;
	}

	fclose(fp);
}
Example #5
0
void show_file(const char *name)
{
	char *path;

	path = tracecmd_get_tracing_file(name);
	dump_file_content(path);
	tracecmd_put_tracing_file(path);
}
Example #6
0
void show_instance_file(struct buffer_instance *instance, const char *name)
{
	char *path;

	path = get_instance_file(instance, name);
	dump_file_content(path);
	tracecmd_put_tracing_file(path);
}
Example #7
0
static void report_ftrace_filters(struct buffer_instance *instance)
{
	char *path;

	path = get_instance_file(instance, "set_ftrace_filter");
	if (!path)
		die("malloc");

	list_functions(path, "Function Filter");
	
	tracecmd_put_tracing_file(path);

	path = get_instance_file(instance, "set_ftrace_notrace");
	if (!path)
		die("malloc");

	list_functions(path, "Function No Trace");
	
	tracecmd_put_tracing_file(path);
}
Example #8
0
static int get_instance_file_fd(struct buffer_instance *instance,
				const char *file)
{
	char *path;
	int fd;

	path = get_instance_file(instance, file);
	fd = open(path, O_RDONLY);
	tracecmd_put_tracing_file(path);

	return fd;
}
Example #9
0
static void process_file_re(process_file_func func,
			    const char *name, const char *re)
{
	regex_t reg;
	char *path;
	char *buf = NULL;
	char *str;
	FILE *fp;
	ssize_t n;
	size_t l = strlen(re);

	/* Just in case :-p */
	if (!re || l == 0) {
		show_file(name);
		return;
	}

	/* Handle the newline at end of names for the user */
	str = malloc(l + 3);
	if (!str)
		die("Failed to allocate reg ex %s", re);
	strcpy(str, re);
	if (re[l-1] == '$')
		strcpy(&str[l-1], "\n*$");
		
	if (regcomp(&reg, str, REG_ICASE|REG_NOSUB))
		die("invalid function regex '%s'", re);

	free(str);

	path = tracecmd_get_tracing_file(name);
	fp = fopen(path, "r");
	if (!fp)
		die("reading %s", path);
	tracecmd_put_tracing_file(path);

	do {
		n = getline(&buf, &l, fp);
		if (n > 0 && regexec(&reg, buf, 0, NULL, 0) == 0)
			func(buf, n);
	} while (n > 0);
	free(buf);
	fclose(fp);

	regfree(&reg);
}
Example #10
0
static void reset_trace(void)
{
	char *path;
	char buf[1];
	int fd;
	int n;

	path = tracecmd_get_tracing_file("stack_max_size");
	fd = open(path, O_WRONLY);
	if (fd < 0)
		die("writing %s", path);

	buf[0] = '0';
	n = write(fd, buf, 1);
	if (n < 0)
		die("writing into %s", path);
	tracecmd_put_tracing_file(path);
	close(fd);
}
Example #11
0
static void report_events(struct buffer_instance *instance)
{
	struct event_iter *iter;
	char *str;
	char *cont;
	char *path;
	char *system;
	enum event_iter_type type;
	enum event_process processed = PROCESSED_NONE;

	str = get_instance_file_content(instance, "events/enable");
	if (!str)
		return;

	cont = strstrip(str);

	printf("\nEvents:\n");

	switch(*cont) {
	case '1':
		printf(" All enabled\n");
		free(str);
		return;
	case '0':
		printf(" All disabled\n");
		free(str);
		return;
	}

	free(str);

	path = get_instance_file(instance, "events");
	if (!path)
		die("malloc");

	iter = trace_event_iter_alloc(path);

	while (trace_event_iter_next(iter, path, NULL)) {
		process_event_enable(path, NULL, iter->system_dent->d_name, &processed);
	}

	reset_event_iter(iter);

	processed = PROCESSED_NONE;
	system = NULL;
	while ((type = trace_event_iter_next(iter, path, system))) {

		if (type == EVENT_ITER_SYSTEM) {

			/* Only process systems that are not fully enabled */
			if (!process_individual_events(path, iter))
				continue;

			system = iter->system_dent->d_name;
			if (processed)
				processed = PROCESSED_SYSTEM;
			continue;
		}

		process_event_enable(path, iter->system_dent->d_name,
				     iter->event_dent->d_name, &processed);
	}

	trace_event_iter_free(iter);

	if (!processed)
		printf("  (none enabled)\n");

	tracecmd_put_tracing_file(path);
}
Example #12
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;
}