lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon,  6 Jul 2009 09:31:34 +0100
From:	Chris Wilson <chris@...is-wilson.co.uk>
To:	Ingo Molnar <mingo@...e.hu>
Cc:	Chris Wilson <chris@...is-wilson.co.uk>,
	Ben Gamari <bgamari.foss@...il.com>,
	<linux-kernel@...r.kernel.org>
Subject: [PATCH 2/2] perf tool: Add a trace point event parser.

Accept events of the form tp=i915/i915_wait and convert those to the
ftrace event id by expanding the short name to
'/sys/kernel/debug/tracing/events/i915/i915_wait/id'. (Substituting the
real debugfs mount path as appropriate.)

Signed-off-by: Chris Wilson <chris@...is-wilson.co.uk>
---
 tools/perf/util/parse-events.c |  133 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 131 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 5184959..36078a6 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1,11 +1,12 @@
-
-#include "../perf.h"
 #include "util.h"
+#include "../perf.h"
 #include "parse-options.h"
 #include "parse-events.h"
 #include "exec_cmd.h"
 #include "string.h"
 
+#include <sys/mount.h>
+
 extern char *strcasestr(const char *haystack, const char *needle);
 
 int					nr_counters;
@@ -339,6 +340,133 @@ parse_numeric_event(const char **strp, struct perf_counter_attr *attr)
 	return 0;
 }
 
+/* mini /proc/mounts parser: searching for "^blah /mount/point debugfs" */
+static const char *
+debug_mntpt (void)
+{
+	static char mntpt[4096];
+	FILE *file;
+	size_t line_len;
+	char *line;
+
+	if (mntpt[0])
+		return mntpt;
+
+	file = fopen("/proc/mounts", "r");
+	if (file == NULL)
+		return NULL;
+
+	while (getline(&line, &line_len, file) >= 0) {
+		char *start, *end;
+
+		if (strstr(line, " debugfs ") == NULL)
+			continue;
+
+		start = strchr(line, ' ') + 1;
+		end = strchr(start + 1, ' ');
+		if(end - start > 4095)
+			goto err_file;
+		memcpy(mntpt, start, end-start);
+		break;
+	}
+	free(line);
+	fclose(file);
+
+	if (mntpt[0] == '\0') {
+		if (mount("none", "/sys/kernel/debug", "debugfs", 0, NULL))
+			return NULL;
+
+		strcpy(mntpt, "/sys/kernel/debug");
+	}
+
+	return mntpt;
+
+err_file:
+	free(line);
+	fclose(file);
+	return NULL;
+}
+
+static int
+safe_strcat(char **strp, int *rem, const char *src, int len)
+{
+	if (len < 0)
+		len = strlen(src);
+	if (len >= *rem)
+		return 0;
+
+	memcpy(*strp, src, len);
+	*strp += len;
+	*rem -= len;
+	**strp = '\0';
+
+	return 1;
+}
+
+static int
+parse_tracepoint_event(const char **strp, struct perf_counter_attr *attr)
+{
+	const char *str = *strp;
+	const char *mntpt;
+	char buf[4096], *bufp;
+	int rem;
+	int fd;
+	int ret;
+	char *comma;
+
+	if (strncmp(str, "tp=", 3))
+	    return 0;
+
+	str += 3;
+
+	/* Expand the tracepoint event to:
+	 *   /sys/kernel/debug/tracing/events/<tracepoint>/id
+	 * and then read that file to determine the ftrace event id to
+	 * pass to perf_counters. Substituting the real debugfs mount path
+	 * as appropriate.
+	 */
+
+	mntpt = debug_mntpt();
+	if (mntpt == NULL)
+		return 0;
+
+	bufp = buf, rem = sizeof(buf);
+	if (!safe_strcat(&bufp, &rem, mntpt, -1))
+		return 0;
+	if (!safe_strcat(&bufp, &rem, "/tracing/events/", -1))
+		return 0;
+
+	comma = strchr(str, ',');
+	if (comma) {
+		if (!safe_strcat(&bufp, &rem, str, comma - str))
+			return 0;
+		*strp = comma;
+	} else {
+		if (!safe_strcat(&bufp, &rem, str, -1))
+			return 0;
+		*strp = str + strlen (str);
+	}
+	if (!safe_strcat(&bufp, &rem, "/id", -1))
+		return 0;
+
+	fd = open(buf, O_RDONLY);
+	if (fd == 0)
+		return 0;
+
+	/* We expect to read a string of "integer\n". */
+	ret = read(fd, buf, sizeof(buf));
+	close(fd);
+	if (ret == -1 || ret == sizeof(buf))
+		return 0;
+
+	buf[ret] = '\0';
+
+	attr->config = strtoul(buf, &bufp, 0);
+	attr->type = PERF_TYPE_TRACEPOINT;
+
+	return bufp == buf + ret-1;
+}
+
 static int
 parse_event_modifier(const char **strp, struct perf_counter_attr *attr)
 {
@@ -377,6 +505,7 @@ static int parse_event_symbols(const char **str, struct perf_counter_attr *attr)
 	if (!(parse_raw_event(str, attr) ||
 	      parse_numeric_event(str, attr) ||
 	      parse_symbolic_event(str, attr) ||
+	      parse_tracepoint_event(str, attr) ||
 	      parse_generic_hw_event(str, attr)))
 		return 0;
 
-- 
1.6.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ