static int perf_session__list_build_ids(bool force, bool with_hits)
{
	struct perf_session *session;

	symbol__elf_init();
	/*
	 * See if this is an ELF file first:
	 */
	if (filename__fprintf_build_id(input_name, stdout))
		goto out;

	session = perf_session__new(input_name, O_RDONLY, force, false,
				    &build_id__mark_dso_hit_ops);
	if (session == NULL)
		return -1;
	/*
	 * in pipe-mode, the only way to get the buildids is to parse
	 * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
	 */
	if (with_hits || session->fd_pipe)
		perf_session__process_events(session, &build_id__mark_dso_hit_ops);

	perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
	perf_session__delete(session);
out:
	return 0;
}
Esempio n. 2
0
static int __cmd_diff(void)
{
	int ret, i;
	struct perf_session *session[2];

	session[0] = perf_session__new(input_old, O_RDONLY, force, false);
	session[1] = perf_session__new(input_new, O_RDONLY, force, false);
	if (session[0] == NULL || session[1] == NULL)
		return -ENOMEM;

	for (i = 0; i < 2; ++i) {
		ret = perf_session__process_events(session[i], &event_ops);
		if (ret)
			goto out_delete;
	}

	hists__output_resort(&session[1]->hists);
	if (show_displacement)
		hists__set_positions(&session[0]->hists);

	hists__match(&session[0]->hists, &session[1]->hists);
	hists__fprintf(&session[1]->hists, &session[0]->hists,
		       show_displacement, stdout);
out_delete:
	for (i = 0; i < 2; ++i)
		perf_session__delete(session[i]);
	return ret;
}
static int __cmd_annotate(void)
{
	int ret;
	struct perf_session *session;

	session = perf_session__new(input_name, O_RDONLY, force);
	if (session == NULL)
		return -ENOMEM;

	ret = perf_session__process_events(session, &event_ops);
	if (ret)
		goto out_delete;

	if (dump_trace) {
		event__print_totals();
		goto out_delete;
	}

	if (verbose > 3)
		perf_session__fprintf(session, stdout);

	if (verbose > 2)
		dsos__fprintf(stdout);

	perf_session__collapse_resort(session);
	perf_session__output_resort(session, session->event_total[0]);
	perf_session__find_annotations(session);
out_delete:
	perf_session__delete(session);

	return ret;
}
Esempio n. 4
0
static int __cmd_diff(void)
{
	int ret, i;
	struct perf_session *session[2];

	session[0] = perf_session__new(input_old, O_RDONLY, force);
	session[1] = perf_session__new(input_new, O_RDONLY, force);
	if (session[0] == NULL || session[1] == NULL)
		return -ENOMEM;

	for (i = 0; i < 2; ++i) {
		ret = perf_session__process_events(session[i], &event_ops);
		if (ret)
			goto out_delete;
		perf_session__output_resort(session[i], session[i]->events_stats.total);
	}

	perf_session__match_hists(session[0], session[1]);
	perf_session__fprintf_hists(session[1], session[0],
				    show_displacement, stdout);
out_delete:
	for (i = 0; i < 2; ++i)
		perf_session__delete(session[i]);
	return ret;
}
Esempio n. 5
0
static int __cmd_timechart(void)
{
	struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
	int ret;

	if (session == NULL)
		return -ENOMEM;

	register_perf_file_handler(&file_handler);

	ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
	if (ret)
		goto out_delete;

	process_samples();

	end_sample_processing();

	sort_pids();

	write_svg_file(output_name);

	pr_info("Written %2.1f seconds of trace to %s.\n",
		(last_time - first_time) / 1000000000.0, output_name);
out_delete:
	perf_session__delete(session);
	return ret;
}
static int perf_session__list_build_ids(void)
{
	struct perf_session *session;

	elf_version(EV_CURRENT);

	session = perf_session__new(input_name, O_RDONLY, force, false,
				    &build_id__mark_dso_hit_ops);
	if (session == NULL)
		return -1;

	/*
	 * See if this is an ELF file first:
	 */
	if (filename__fprintf_build_id(session->filename, stdout))
		goto out;

	if (with_hits)
		perf_session__process_events(session, &build_id__mark_dso_hit_ops);

	perf_session__fprintf_dsos_buildid(session, stdout, with_hits);
out:
	perf_session__delete(session);
	return 0;
}
Esempio n. 7
0
struct perf_session *perf_session__new(const char *filename, int mode,
				       bool force, bool repipe,
				       struct perf_tool *tool)
{
	struct perf_session *self;
	struct stat st;
	size_t len;

	if (!filename || !strlen(filename)) {
		if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
			filename = "-";
		else
			filename = "perf.data";
	}

	len = strlen(filename);
	self = zalloc(sizeof(*self) + len);

	if (self == NULL)
		goto out;

	memcpy(self->filename, filename, len);
	self->repipe = repipe;
	INIT_LIST_HEAD(&self->ordered_samples.samples);
	INIT_LIST_HEAD(&self->ordered_samples.sample_cache);
	INIT_LIST_HEAD(&self->ordered_samples.to_free);
	machines__init(&self->machines);

	if (mode == O_RDONLY) {
		if (perf_session__open(self, force) < 0)
			goto out_delete;
		perf_session__set_id_hdr_size(self);
	} else if (mode == O_WRONLY) {
		/*
		 * In O_RDONLY mode this will be performed when reading the
		 * kernel MMAP event, in perf_event__process_mmap().
		 */
		if (perf_session__create_kernel_maps(self) < 0)
			goto out_delete;
	}

	if (tool && tool->ordering_requires_timestamps &&
	    tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) {
		dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
		tool->ordered_samples = false;
	}

out:
	return self;
out_delete:
	perf_session__delete(self);
	return NULL;
}
Esempio n. 8
0
struct perf_session *perf_session__new(struct perf_data_file *file,
				       bool repipe, struct perf_tool *tool)
{
	struct perf_session *session = zalloc(sizeof(*session));

	if (!session)
		goto out;

	session->repipe = repipe;
	INIT_LIST_HEAD(&session->ordered_samples.samples);
	INIT_LIST_HEAD(&session->ordered_samples.sample_cache);
	INIT_LIST_HEAD(&session->ordered_samples.to_free);
	machines__init(&session->machines);

	if (file) {
		if (perf_data_file__open(file))
			goto out_delete;

		session->file = file;

		if (perf_data_file__is_read(file)) {
			if (perf_session__open(session) < 0)
				goto out_close;

			perf_session__set_id_hdr_size(session);
		}
	}

	if (!file || perf_data_file__is_write(file)) {
		/*
		 * In O_RDONLY mode this will be performed when reading the
		 * kernel MMAP event, in perf_event__process_mmap().
		 */
		if (perf_session__create_kernel_maps(session) < 0)
			goto out_delete;
	}

	if (tool && tool->ordering_requires_timestamps &&
	    tool->ordered_samples && !perf_evlist__sample_id_all(session->evlist)) {
		dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
		tool->ordered_samples = false;
	}

	return session;

 out_close:
	perf_data_file__close(file);
 out_delete:
	perf_session__delete(session);
 out:
	return NULL;
}
Esempio n. 9
0
static int __cmd_evlist(const char *file_name, struct perf_attr_details *details)
{
	struct perf_session *session;
	struct perf_evsel *pos;
	struct perf_data_file file = {
		.path = file_name,
		.mode = PERF_DATA_MODE_READ,
		.force = details->force,
	};

	session = perf_session__new(&file, 0, NULL);
	if (session == NULL)
		return -1;

	evlist__for_each(session->evlist, pos)
		perf_evsel__fprintf(pos, details, stdout);

	perf_session__delete(session);
	return 0;
}

int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused)
{
	struct perf_attr_details details = { .verbose = false, };
	const struct option options[] = {
	OPT_STRING('i', "input", &input_name, "file", "Input file name"),
	OPT_BOOLEAN('F', "freq", &details.freq, "Show the sample frequency"),
	OPT_BOOLEAN('v', "verbose", &details.verbose,
		    "Show all event attr details"),
	OPT_BOOLEAN('g', "group", &details.event_group,
		    "Show event group information"),
	OPT_BOOLEAN('f', "force", &details.force, "don't complain, do it"),
	OPT_END()
	};
	const char * const evlist_usage[] = {
		"perf evlist [<options>]",
		NULL
	};

	argc = parse_options(argc, argv, options, evlist_usage, 0);
	if (argc)
		usage_with_options(evlist_usage, options);

	if (details.event_group && (details.verbose || details.freq)) {
		usage_with_options_msg(evlist_usage, options,
			"--group option is not compatible with other options\n");
	}

	return __cmd_evlist(input_name, &details);
}
static int __cmd_evlist(void)
{
	struct perf_session *session;
	struct perf_evsel *pos;

	session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
	if (session == NULL)
		return -ENOMEM;

	list_for_each_entry(pos, &session->evlist->entries, node)
		printf("%s\n", event_name(pos));

	perf_session__delete(session);
	return 0;
}
static int build_id_cache__fprintf_missing(const char *filename, bool force, FILE *fp)
{
	struct perf_data_file file = {
		.path  = filename,
		.mode  = PERF_DATA_MODE_READ,
		.force = force,
	};
	struct perf_session *session = perf_session__new(&file, false, NULL);
	if (session == NULL)
		return -1;

	perf_session__fprintf_dsos_buildid(session, fp, dso__missing_buildid_cache, 0);
	perf_session__delete(session);

	return 0;
}
Esempio n. 12
0
static int __cmd_buildid_list(void)
{
	int err = -1;
	struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);

	if (session == NULL)
		return -1;

	err = perf_header__process_sections(&session->header, session->fd,
				         perf_file_section__process_buildids);
	if (err >= 0)
		dsos__fprintf_buildid(stdout);

	perf_session__delete(session);
	return err;
}
static int __cmd_buildid_list(void)
{
	int err = -1;
	struct perf_session *session;

	session = perf_session__new(input_name, O_RDONLY, force);
	if (session == NULL)
		return -1;

	if (with_hits)
		perf_session__process_events(session, &build_id__mark_dso_hit_ops);

	dsos__fprintf_buildid(stdout, with_hits);

	perf_session__delete(session);
	return err;
}
static int perf_session__list_build_ids(void)
{
	struct perf_session *session;

	session = perf_session__new(input_name, O_RDONLY, force, false,
				    &build_id__mark_dso_hit_ops);
	if (session == NULL)
		return -1;

	if (with_hits)
		perf_session__process_events(session, &build_id__mark_dso_hit_ops);

	perf_session__fprintf_dsos_buildid(session, stdout, with_hits);

	perf_session__delete(session);
	return 0;
}
Esempio n. 15
0
struct perf_session *perf_session__new(const char *filename, int mode, bool force)
{
	size_t len = filename ? strlen(filename) + 1 : 0;
	struct perf_session *self = zalloc(sizeof(*self) + len);

	if (self == NULL)
		goto out;

	if (perf_header__init(&self->header) < 0)
		goto out_free;

	memcpy(self->filename, filename, len);
	self->threads = RB_ROOT;
	self->last_match = NULL;
	self->mmap_window = 32;
	self->cwd = NULL;
	self->cwdlen = 0;
	self->unknown_events = 0;
	map_groups__init(&self->kmaps);

	if (mode == O_RDONLY) {
		if (perf_session__open(self, force) < 0)
			goto out_delete;
	} else if (mode == O_WRONLY) {
		/*
		 * In O_RDONLY mode this will be performed when reading the
		 * kernel MMAP event, in event__process_mmap().
		 */
		if (perf_session__create_kernel_maps(self) < 0)
			goto out_delete;
	}

	self->sample_type = perf_header__sample_type(&self->header);
out:
	return self;
out_free:
	free(self);
	return NULL;
out_delete:
	perf_session__delete(self);
	return NULL;
}
Esempio n. 16
0
static int perf_session__list_build_ids(bool force, bool with_hits)
{
	struct perf_session *session;
	struct perf_data_file file = {
		.path  = input_name,
		.mode  = PERF_DATA_MODE_READ,
		.force = force,
	};

	symbol__elf_init();
	/*
	 * See if this is an ELF file first:
	 */
	if (filename__fprintf_build_id(input_name, stdout) > 0)
		goto out;

	session = perf_session__new(&file, false, &build_id__mark_dso_hit_ops);
	if (session == NULL)
		return -1;

	/*
	 * We take all buildids when the file contains AUX area tracing data
	 * because we do not decode the trace because it would take too long.
	 */
	if (!perf_data_file__is_pipe(&file) &&
	    perf_header__has_feat(&session->header, HEADER_AUXTRACE))
		with_hits = false;

	/*
	 * in pipe-mode, the only way to get the buildids is to parse
	 * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
	 */
	if (with_hits || perf_data_file__is_pipe(&file))
		perf_session__process_events(session);

	perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
	perf_session__delete(session);
out:
	return 0;
}
Esempio n. 17
0
struct perf_session *perf_session__new(const char *filename, int mode, bool force)
{
	size_t len = strlen(filename) + 1;
	struct perf_session *self = zalloc(sizeof(*self) + len);

	if (self == NULL)
		goto out;

	if (perf_header__init(&self->header) < 0)
		goto out_delete;

	memcpy(self->filename, filename, len);

	if (mode == O_RDONLY && perf_session__open(self, force) < 0) {
		perf_session__delete(self);
		self = NULL;
	}
out:
	return self;
out_delete:
	free(self);
	return NULL;
}
int cmd_buildid_cache(int argc, const char **argv)
{
	struct strlist *list;
	struct str_node *pos;
	int ret = 0;
	int ns_id = -1;
	bool force = false;
	char const *add_name_list_str = NULL,
		   *remove_name_list_str = NULL,
		   *purge_name_list_str = NULL,
		   *missing_filename = NULL,
		   *update_name_list_str = NULL,
		   *kcore_filename = NULL;
	char sbuf[STRERR_BUFSIZE];

	struct perf_data data = {
		.mode  = PERF_DATA_MODE_READ,
	};
	struct perf_session *session = NULL;
	struct nsinfo *nsi = NULL;

	const struct option buildid_cache_options[] = {
	OPT_STRING('a', "add", &add_name_list_str,
		   "file list", "file(s) to add"),
	OPT_STRING('k', "kcore", &kcore_filename,
		   "file", "kcore file to add"),
	OPT_STRING('r', "remove", &remove_name_list_str, "file list",
		    "file(s) to remove"),
	OPT_STRING('p', "purge", &purge_name_list_str, "path list",
		    "path(s) to remove (remove old caches too)"),
	OPT_STRING('M', "missing", &missing_filename, "file",
		   "to find missing build ids in the cache"),
	OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
	OPT_STRING('u', "update", &update_name_list_str, "file list",
		    "file(s) to update"),
	OPT_INCR('v', "verbose", &verbose, "be more verbose"),
	OPT_INTEGER(0, "target-ns", &ns_id, "target pid for namespace context"),
	OPT_END()
	};
	const char * const buildid_cache_usage[] = {
		"perf buildid-cache [<options>]",
		NULL
	};

	argc = parse_options(argc, argv, buildid_cache_options,
			     buildid_cache_usage, 0);

	if (argc || (!add_name_list_str && !kcore_filename &&
		     !remove_name_list_str && !purge_name_list_str &&
		     !missing_filename && !update_name_list_str))
		usage_with_options(buildid_cache_usage, buildid_cache_options);

	if (ns_id > 0)
		nsi = nsinfo__new(ns_id);

	if (missing_filename) {
		data.file.path = missing_filename;
		data.force     = force;

		session = perf_session__new(&data, false, NULL);
		if (session == NULL)
			return -1;
	}

	if (symbol__init(session ? &session->header.env : NULL) < 0)
		goto out;

	setup_pager();

	if (add_name_list_str) {
		list = strlist__new(add_name_list_str, NULL);
		if (list) {
			strlist__for_each_entry(pos, list)
				if (build_id_cache__add_file(pos->s, nsi)) {
					if (errno == EEXIST) {
						pr_debug("%s already in the cache\n",
							 pos->s);
						continue;
					}
					pr_warning("Couldn't add %s: %s\n",
						   pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
				}

			strlist__delete(list);
		}
	}

	if (remove_name_list_str) {
		list = strlist__new(remove_name_list_str, NULL);
		if (list) {
			strlist__for_each_entry(pos, list)
				if (build_id_cache__remove_file(pos->s, nsi)) {
					if (errno == ENOENT) {
						pr_debug("%s wasn't in the cache\n",
							 pos->s);
						continue;
					}
					pr_warning("Couldn't remove %s: %s\n",
						   pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
				}

			strlist__delete(list);
		}
	}

	if (purge_name_list_str) {
		list = strlist__new(purge_name_list_str, NULL);
		if (list) {
			strlist__for_each_entry(pos, list)
				if (build_id_cache__purge_path(pos->s, nsi)) {
					if (errno == ENOENT) {
						pr_debug("%s wasn't in the cache\n",
							 pos->s);
						continue;
					}
					pr_warning("Couldn't remove %s: %s\n",
						   pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
				}

			strlist__delete(list);
		}
	}

	if (missing_filename)
		ret = build_id_cache__fprintf_missing(session, stdout);

	if (update_name_list_str) {
		list = strlist__new(update_name_list_str, NULL);
		if (list) {
			strlist__for_each_entry(pos, list)
				if (build_id_cache__update_file(pos->s, nsi)) {
					if (errno == ENOENT) {
						pr_debug("%s wasn't in the cache\n",
							 pos->s);
						continue;
					}
					pr_warning("Couldn't update %s: %s\n",
						   pos->s, str_error_r(errno, sbuf, sizeof(sbuf)));
				}

			strlist__delete(list);
		}
	}

	if (kcore_filename && build_id_cache__add_kcore(kcore_filename, force))
		pr_warning("Couldn't add %s\n", kcore_filename);

out:
	perf_session__delete(session);
	nsinfo__zput(nsi);

	return ret;
}