linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] libtraceevent: Copy parsing functions from trace-cmd
@ 2021-04-08 21:41 Steven Rostedt
  2021-04-08 21:41 ` [PATCH v3 1/5] libtraceevent: Update gitignore Steven Rostedt
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Steven Rostedt @ 2021-04-08 21:41 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Currently, trace-cmd does the work of parsing kallsyms, saved_cmdlines,
and printk_formats and feeding it to the libtraceevent tep handle. When
starting to write code snippets that work directly with libtracefs and
libtraceevent, I found that I need this functionality as well. But this
code doesn't need libtracecmd. As these files exist in /proc and in the
tracefs directly, just like we have events and headers that get parsed
by libtraceevent, add this functionality directly to libtraceevent, as
libtraceevent is made to parse files for processing of events, and all
of the above do exactly that.

Changes since version 2:

  Right after sending v1, I found that patch 2 had a small bug on
  install the documentation. Resending the whole series with the fix
  so that patchwork picks it up correctly.

Steven Rostedt (VMware) (5):
  libtraceevent: Update gitignore
  libtraceevent: Fix dependencies in Documentation Makefile
  libtraceevent: Add the API tep_parse_kallsyms()
  libtraceevent: Add the API tep_parse_saved_cmdlines()
  libtraceevent: Add the API tep_parse_printk_formats()

 .gitignore                                  |   5 +
 Documentation/.gitignore                    |   3 +
 Documentation/Makefile                      |  28 ++--
 Documentation/libtraceevent-parse-files.txt | 149 ++++++++++++++++++
 src/event-parse.c                           | 161 ++++++++++++++++++++
 src/event-parse.h                           |   3 +
 6 files changed, 338 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/.gitignore
 create mode 100644 Documentation/libtraceevent-parse-files.txt

-- 
2.29.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3 1/5] libtraceevent: Update gitignore
  2021-04-08 21:41 [PATCH v3 0/5] libtraceevent: Copy parsing functions from trace-cmd Steven Rostedt
@ 2021-04-08 21:41 ` Steven Rostedt
  2021-04-08 21:41 ` [PATCH v3 2/5] libtraceevent: Fix dependencies in Documentation Makefile Steven Rostedt
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2021-04-08 21:41 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Update the gitignore files to not pick up files that are created in the
build as well as those auxiliary files used for creating the man pages.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 .gitignore               | 5 +++++
 Documentation/.gitignore | 3 +++
 2 files changed, 8 insertions(+)
 create mode 100644 Documentation/.gitignore

diff --git a/.gitignore b/.gitignore
index 7123c70..fde7fe6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,8 @@
 TRACEEVENT-CFLAGS
 libtraceevent-dynamic-list
 libtraceevent.so.*
+*.o
+build_prefix
+build_uninstall
+*~
+\#*\#
diff --git a/Documentation/.gitignore b/Documentation/.gitignore
new file mode 100644
index 0000000..bdc8252
--- /dev/null
+++ b/Documentation/.gitignore
@@ -0,0 +1,3 @@
+*.m
+*.3
+*.html
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 2/5] libtraceevent: Fix dependencies in Documentation Makefile
  2021-04-08 21:41 [PATCH v3 0/5] libtraceevent: Copy parsing functions from trace-cmd Steven Rostedt
  2021-04-08 21:41 ` [PATCH v3 1/5] libtraceevent: Update gitignore Steven Rostedt
@ 2021-04-08 21:41 ` Steven Rostedt
  2021-04-08 21:41 ` [PATCH v3 3/5] libtraceevent: Add the API tep_parse_kallsyms() Steven Rostedt
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2021-04-08 21:41 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Modify the Documentation Makefile to only rebuild the man pages when their
source has been modified.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/Makefile | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/Documentation/Makefile b/Documentation/Makefile
index 21bcd5e..73dbe2a 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -11,7 +11,7 @@ MAN3_TXT= \
 MAN_TXT = $(MAN3_TXT)
 _MAN_XML=$(patsubst %.txt,%.xml,$(MAN_TXT))
 _MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT))
-_DOC_MAN3=$(patsubst %.txt,%.3,$(MAN3_TXT))
+_DOC_MAN3=$(patsubst %.txt,%.m,$(MAN3_TXT))
 
 MAN_XML=$(addprefix $(OUTPUT),$(_MAN_XML))
 MAN_HTML=$(addprefix $(OUTPUT),$(_MAN_HTML))
@@ -154,17 +154,22 @@ ifdef missing_tools
 	$(error "You need to install $(missing_tools) for man pages")
 endif
 
-do-install-man: man
-	$(call QUIET_INSTALL, Documentation-man) \
+install-%.3: $(OUTPUT)%.3
+	$(call QUIET_INSTALL, $<) \
 		$(INSTALL) -d -m 755 $(DESTDIR)$(man3dir); \
-		$(INSTALL) -m 644 $(OUTPUT)*.3 $(DESTDIR)$(man3dir);
+		$(INSTALL) -m 644 $< $(DESTDIR)$(man3dir);
 
-install-man: check-man-tools man do-install-man
+do-install-man: man $(addprefix install-,$(wildcard $(OUTPUT)*.3))
 
-do-install-html: html
-	$(call QUIET_INSTALL, Documentation-html) \
+install-man: check-man-tools man
+	$(Q)$(MAKE) -C . do-install-man
+
+install-%.txt: $(OUTPUT)%.html
+	$(call QUIET_INSTALL, $<) \
 		$(INSTALL) -d -m 755 $(DESTDIR)$(htmldir); \
-		$(INSTALL) -m 644 $(OUTPUT)*.html $(DESTDIR)$(htmldir);
+		$(INSTALL) -m 644 $< $(DESTDIR)$(htmldir);
+
+do-install-html: html $(addprefix install-,$(wildcard *.txt))
 
 install-html: check-man-tools html do-install-html
 
@@ -187,7 +192,7 @@ endif
 CLEAN_FILES =					\
 	$(MAN_XML) $(addsuffix +,$(MAN_XML))	\
 	$(MAN_HTML) $(addsuffix +,$(MAN_HTML))	\
-	$(DOC_MAN3) *.3
+	$(DOC_MAN3) *.3 *.m
 
 clean:
 	$(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES)
@@ -200,9 +205,10 @@ $(OUTPUT)%.3 : $(OUTPUT)%.txt
 	mv $@+ $@
 endif
 
-$(OUTPUT)%.3 : $(OUTPUT)%.xml
+$(OUTPUT)%.m : $(OUTPUT)%.xml
 	$(QUIET_XMLTO)$(RM) $@ && \
-	$(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
+	$(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<; \
+	touch $@
 
 $(OUTPUT)%.xml : %.txt
 	$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 3/5] libtraceevent: Add the API tep_parse_kallsyms()
  2021-04-08 21:41 [PATCH v3 0/5] libtraceevent: Copy parsing functions from trace-cmd Steven Rostedt
  2021-04-08 21:41 ` [PATCH v3 1/5] libtraceevent: Update gitignore Steven Rostedt
  2021-04-08 21:41 ` [PATCH v3 2/5] libtraceevent: Fix dependencies in Documentation Makefile Steven Rostedt
@ 2021-04-08 21:41 ` Steven Rostedt
  2021-04-08 21:41 ` [PATCH v3 4/5] libtraceevent: Add the API tep_parse_saved_cmdlines() Steven Rostedt
  2021-04-08 21:42 ` [PATCH v3 5/5] libtraceevent: Add the API tep_parse_printk_formats() Steven Rostedt
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2021-04-08 21:41 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Currently, trace-cmd has a tracecmd_parse_proc_kallsyms() function that
reads a string that holds the content of /proc/kallsyms and then passes
the function mapping it reads into the tep handler.

There's no reason for this to be specific to trace-cmd as other
applications can easily save /proc/kallsyms, or just read it directly and
then pass it to the tep handler.

Add the same functionality to libtraceevent as tep_parse_kallsyms().

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtraceevent-parse-files.txt | 97 +++++++++++++++++++++
 src/event-parse.c                           | 68 +++++++++++++++
 src/event-parse.h                           |  1 +
 3 files changed, 166 insertions(+)
 create mode 100644 Documentation/libtraceevent-parse-files.txt

diff --git a/Documentation/libtraceevent-parse-files.txt b/Documentation/libtraceevent-parse-files.txt
new file mode 100644
index 0000000..10144d1
--- /dev/null
+++ b/Documentation/libtraceevent-parse-files.txt
@@ -0,0 +1,97 @@
+libtraceevent(3)
+================
+
+NAME
+----
+tep_parse_kallsyms - Parses mappings of address to function names from kallsyms format file
+
+SYNOPSIS
+--------
+[verse]
+--
+*#include <event-parse.h>*
+
+int *tep_parse_kallsyms*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_);
+--
+
+DESCRIPTION
+-----------
+*tep_parse_kallsyms* is a helper function to parse the Linux kernel /proc/kallsyms format
+(stored in a string buffer passed in by _buf_) and load the functions into the
+_tep_ handler such that function IP addresses can be mapped to their name when
+parsing events with %pS in the print format field. It parses the string _buf_ that
+holds the content of /proc/kallsyms and ends with a nul character ('\0').
+
+RETURN VALUE
+------------
+The *tep_parse_kallsyms*() function returns 0 in case of success, or -1
+in case of an error.
+
+EXAMPLE
+-------
+[source,c]
+--
+...
+#include <event-parse.h>
+#include <stdlib.h>
+
+int load_kallsyms(struct tep_handle *tep)
+{
+        char *line = NULL;
+        char *buf = NULL;
+        size_t sz = 0;
+        FILE *fp;
+        int len = 0;
+        int r;
+
+        fp = fopen("/proc/kallsyms", "r");
+        while ((r = getline(&line, &sz, fp)) >= 0) {
+                buf = realloc(buf, len + r + 1);
+                memcpy(buf + len, line, r);
+                len += r;
+        }
+        free(line);
+        fclose(fp);
+        if (!buf)
+                return -1;
+        buf[len] = 0;
+
+        r = tep_parse_kallsyms(tep, buf);
+        free(buf);
+        return r;
+}
+...
+--
+
+FILES
+-----
+[verse]
+--
+*event-parse.h*
+	Header file to include in order to have access to the library APIs.
+*-ltraceevent*
+	Linker switch to add when building a program that uses the library.
+--
+
+SEE ALSO
+--------
+_libtraceevent(3)_, _trace-cmd(1)_, _tep_register_function(3)_
+
+AUTHOR
+------
+[verse]
+--
+*Steven Rostedt* <rostedt@goodmis.org>, author of *libtraceevent*.
+*Tzvetomir Stoyanov* <tz.stoyanov@gmail.com>, coauthor of *libtraceevent*.
+--
+REPORTING BUGS
+--------------
+Report bugs to  <linux-trace-devel@vger.kernel.org>
+
+LICENSE
+-------
+libtraceevent is Free Software licensed under the GNU LGPL 2.1
+
+RESOURCES
+---------
+https://git.kernel.org/pub/scm/libs/libtrace/libtraceevent.git/
diff --git a/src/event-parse.c b/src/event-parse.c
index 7c1f4cb..6bf293d 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -640,6 +640,74 @@ out_free:
 	return -1;
 }
 
+/**
+ * tep_parse_kallsyms - load functions from a read of /proc/kallsyms
+ * @tep: a handle to the trace event parser
+ * @kallsyms: A string buffer that holds the content of /proc/kallsyms and ends with '\0'
+ *
+ * This is a helper function to parse the Linux kernel /proc/kallsyms
+ * format (stored in a string buffer) and load the functions into
+ * the @tep handler such that function IP addresses can be mapped to
+ * their name when parsing events with %pS in the print format field.
+ *
+ * Returns 0 on success, and -1 on error.
+ */
+int tep_parse_kallsyms(struct tep_handle *tep, const char *kallsyms)
+{
+	unsigned long long addr;
+	char *copy;
+	char *func;
+	char *line;
+	char *next = NULL;
+	char *mod;
+	char ch;
+	int ret = -1;
+
+	copy = strdup(kallsyms);
+	if (!copy)
+		return -1;
+
+	line = strtok_r(copy, "\n", &next);
+	while (line) {
+		int func_start, func_end = 0;
+		int mod_start, mod_end = 0;
+		int n;
+
+		mod = NULL;
+		errno = 0;
+		n = sscanf(line, "%16llx %c %n%*s%n%*1[\t][%n%*s%n",
+			   &addr, &ch, &func_start, &func_end, &mod_start, &mod_end);
+		if (errno)
+			goto out;
+
+		if (n != 2 || !func_end)
+			goto out;
+
+		func = line + func_start;
+		/*
+		 * Hacks for
+		 *  - arm arch that adds a lot of bogus '$a' functions
+		 *  - x86-64 that reports per-cpu variable offsets as absolute
+		 */
+		if (func[0] != '$' && ch != 'A' && ch != 'a') {
+			line[func_end] = 0;
+			if (mod_end) {
+				mod = line + mod_start;
+				/* truncate the extra ']' */
+				line[mod_end - 1] = 0;
+			}
+			tep_register_function(tep, func, addr, mod);
+		}
+
+		line = strtok_r(NULL, "\n", &next);
+	}
+	ret = 0;
+ out:
+	free(copy);
+
+	return ret;
+}
+
 /**
  * tep_print_funcs - print out the stored functions
  * @tep: a handle to the trace event parser context
diff --git a/src/event-parse.h b/src/event-parse.h
index a67ad9a..3fbd3c4 100644
--- a/src/event-parse.h
+++ b/src/event-parse.h
@@ -439,6 +439,7 @@ int tep_set_function_resolver(struct tep_handle *tep,
 void tep_reset_function_resolver(struct tep_handle *tep);
 int tep_register_comm(struct tep_handle *tep, const char *comm, int pid);
 int tep_override_comm(struct tep_handle *tep, const char *comm, int pid);
+int tep_parse_kallsyms(struct tep_handle *tep, const char *kallsyms);
 int tep_register_function(struct tep_handle *tep, char *name,
 			  unsigned long long addr, char *mod);
 int tep_register_print_string(struct tep_handle *tep, const char *fmt,
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 4/5] libtraceevent: Add the API tep_parse_saved_cmdlines()
  2021-04-08 21:41 [PATCH v3 0/5] libtraceevent: Copy parsing functions from trace-cmd Steven Rostedt
                   ` (2 preceding siblings ...)
  2021-04-08 21:41 ` [PATCH v3 3/5] libtraceevent: Add the API tep_parse_kallsyms() Steven Rostedt
@ 2021-04-08 21:41 ` Steven Rostedt
  2021-04-08 21:42 ` [PATCH v3 5/5] libtraceevent: Add the API tep_parse_printk_formats() Steven Rostedt
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2021-04-08 21:41 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Currently, trace-cmd has a tracecmd_parse_cmdlines() function that
reads a string that holds the content of saved_cmdlines from the tracefs
file system, and then passes the pid to comm mapping to the tep handler.

There's no reason for this to be specific to trace-cmd as other
applications can easily read the saved_cmdlines with the tracefs API and
then pass it to the tep handler.

Add the same functionality to libtraceevent as tep_parse_saved_cmdlines().

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtraceevent-parse-files.txt | 30 ++++++++++++++-
 src/event-parse.c                           | 42 +++++++++++++++++++++
 src/event-parse.h                           |  1 +
 3 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/Documentation/libtraceevent-parse-files.txt b/Documentation/libtraceevent-parse-files.txt
index 10144d1..594cef2 100644
--- a/Documentation/libtraceevent-parse-files.txt
+++ b/Documentation/libtraceevent-parse-files.txt
@@ -3,7 +3,8 @@ libtraceevent(3)
 
 NAME
 ----
-tep_parse_kallsyms - Parses mappings of address to function names from kallsyms format file
+tep_parse_saved_cmdlines, tep_parse_kallsyms
+- Parsing functions to load mappings
 
 SYNOPSIS
 --------
@@ -11,11 +12,19 @@ SYNOPSIS
 --
 *#include <event-parse.h>*
 
+int *tep_parse_saved_cmdlines*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_);
 int *tep_parse_kallsyms*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_);
 --
 
 DESCRIPTION
 -----------
+*tep_parse_saved_cmdlines* is a helper function to parse content in the tracefs
+file system of the "saved_cmdlines" file (stored in a string buffer passed in by _buf_)
+and loads the mapping of the process IDs (pid) to the comm names in the
+_tep_ handler. The events store the pid and this is used to be able to show the
+process names associated to those process ids. It parses the string _buf_ that
+holds the content of saved_cmdlines and ends with a nul character ('\0').
+
 *tep_parse_kallsyms* is a helper function to parse the Linux kernel /proc/kallsyms format
 (stored in a string buffer passed in by _buf_) and load the functions into the
 _tep_ handler such that function IP addresses can be mapped to their name when
@@ -24,6 +33,9 @@ holds the content of /proc/kallsyms and ends with a nul character ('\0').
 
 RETURN VALUE
 ------------
+The *tep_parse_saved_cmdlines*() function returns 0 in case of success, or -1
+in case of an error.
+
 The *tep_parse_kallsyms*() function returns 0 in case of success, or -1
 in case of an error.
 
@@ -33,8 +45,22 @@ EXAMPLE
 --
 ...
 #include <event-parse.h>
+#include <tracefs.h>
 #include <stdlib.h>
 
+int load_cmdlines(struct tep_handle *tep)
+{
+        char *buf = NULL;
+        int r;
+
+        buf = tracefs_instance_file_read(NULL, "saved_cmdlines", NULL);
+        if (!buf)
+                return -1;
+        r = tep_parse_saved_cmdlines(tep, buf);
+        free(buf);
+        return r;
+}
+
 int load_kallsyms(struct tep_handle *tep)
 {
         char *line = NULL;
@@ -75,7 +101,7 @@ FILES
 
 SEE ALSO
 --------
-_libtraceevent(3)_, _trace-cmd(1)_, _tep_register_function(3)_
+_libtraceevent(3)_, _trace-cmd(1)_, _tep_register_comm(3)_, _tep_register_function(3)_
 
 AUTHOR
 ------
diff --git a/src/event-parse.c b/src/event-parse.c
index 6bf293d..0d12ec4 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -387,6 +387,48 @@ int tep_override_comm(struct tep_handle *tep, const char *comm, int pid)
 	return _tep_register_comm(tep, comm, pid, true);
 }
 
+/**
+ * tep_parse_saved_cmdlines - parse the comms from the saved_cmdlines file
+ * @tep: a handle to the trace event parser
+ * @buf: A string buffer that holds the content of saved_cmdlines and ends with '\0'
+ *
+ * This is a helper function to parse the comms in the tracefs saved_cmdlines
+ * file (stored in a string buffer) and load the comms into the @tep handler
+ * such that comm name matches an process ID (pid). This is used to show
+ * the names of the processes as the events only hold the pid.
+ *
+ * Returns 0 on success, and -1 on error.
+ */
+int tep_parse_saved_cmdlines(struct tep_handle *tep, const char *buf)
+{
+	char *copy;
+	char *comm;
+	char *line;
+	char *next = NULL;
+	int pid;
+	int ret = -1;
+	int n;
+
+	copy = strdup(buf);
+	if (!copy)
+		return -1;
+
+	line = strtok_r(copy, "\n", &next);
+	while (line) {
+		errno = 0;
+		n = sscanf(line, "%d %m[^\n]s", &pid, &comm);
+		if (errno || n != 2 || !comm)
+			goto out;
+		tep_register_comm(tep, comm, pid);
+		free(comm);
+		line = strtok_r(NULL, "\n", &next);
+	}
+	ret = 0;
+ out:
+	free(copy);
+	return ret;
+}
+
 struct func_map {
 	unsigned long long		addr;
 	char				*func;
diff --git a/src/event-parse.h b/src/event-parse.h
index 3fbd3c4..078b202 100644
--- a/src/event-parse.h
+++ b/src/event-parse.h
@@ -439,6 +439,7 @@ int tep_set_function_resolver(struct tep_handle *tep,
 void tep_reset_function_resolver(struct tep_handle *tep);
 int tep_register_comm(struct tep_handle *tep, const char *comm, int pid);
 int tep_override_comm(struct tep_handle *tep, const char *comm, int pid);
+int tep_parse_saved_cmdlines(struct tep_handle *tep, const char *buf);
 int tep_parse_kallsyms(struct tep_handle *tep, const char *kallsyms);
 int tep_register_function(struct tep_handle *tep, char *name,
 			  unsigned long long addr, char *mod);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v3 5/5] libtraceevent: Add the API tep_parse_printk_formats()
  2021-04-08 21:41 [PATCH v3 0/5] libtraceevent: Copy parsing functions from trace-cmd Steven Rostedt
                   ` (3 preceding siblings ...)
  2021-04-08 21:41 ` [PATCH v3 4/5] libtraceevent: Add the API tep_parse_saved_cmdlines() Steven Rostedt
@ 2021-04-08 21:42 ` Steven Rostedt
  4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2021-04-08 21:42 UTC (permalink / raw)
  To: linux-trace-devel; +Cc: Steven Rostedt (VMware)

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

Currently, trace-cmd has a tracecmd_parse_ftrace_printk() function that
reads a string that holds the content of printk_formats from the tracefs
file system, and then passes the address of the printk strings mappings
to the tep handler.

There's no reason for this to be specific to trace-cmd as other
applications can easily read the printk_formats with the tracefs API and
then pass it to the tep handler.

Add the same functionality to libtraceevent as tep_parse_printk_formats().

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/libtraceevent-parse-files.txt | 30 +++++++++++-
 src/event-parse.c                           | 51 +++++++++++++++++++++
 src/event-parse.h                           |  1 +
 3 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/Documentation/libtraceevent-parse-files.txt b/Documentation/libtraceevent-parse-files.txt
index 594cef2..211f4f4 100644
--- a/Documentation/libtraceevent-parse-files.txt
+++ b/Documentation/libtraceevent-parse-files.txt
@@ -3,7 +3,7 @@ libtraceevent(3)
 
 NAME
 ----
-tep_parse_saved_cmdlines, tep_parse_kallsyms
+tep_parse_saved_cmdlines, tep_parse_printk_formats, tep_parse_kallsyms
 - Parsing functions to load mappings
 
 SYNOPSIS
@@ -13,6 +13,7 @@ SYNOPSIS
 *#include <event-parse.h>*
 
 int *tep_parse_saved_cmdlines*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_);
+int *tep_parse_printk_formats*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_);
 int *tep_parse_kallsyms*(struct tep_handle pass:[*]_tep_, const char pass:[*]_buf_);
 --
 
@@ -25,6 +26,14 @@ _tep_ handler. The events store the pid and this is used to be able to show the
 process names associated to those process ids. It parses the string _buf_ that
 holds the content of saved_cmdlines and ends with a nul character ('\0').
 
+*tep_parse_printk_formats* is a helper function to parse content in the tracefs
+file system of the "printk_formats" file (stored in a string buffer passed in by _buf_)
+and loads the mapping of addresses of strings that may be referenced by events.
+Events only store the address of constant strings in the kernel, and the mapping
+of their address to the string is exported to user space in the printk_formats
+file. It parses the string _buf_ that holds the content of printk_formats and
+ends with a nul character ('\0').
+
 *tep_parse_kallsyms* is a helper function to parse the Linux kernel /proc/kallsyms format
 (stored in a string buffer passed in by _buf_) and load the functions into the
 _tep_ handler such that function IP addresses can be mapped to their name when
@@ -36,6 +45,9 @@ RETURN VALUE
 The *tep_parse_saved_cmdlines*() function returns 0 in case of success, or -1
 in case of an error.
 
+The *tep_parse_printk_formats*() function returns 0 in case of success, or -1
+in case of an error.
+
 The *tep_parse_kallsyms*() function returns 0 in case of success, or -1
 in case of an error.
 
@@ -61,6 +73,19 @@ int load_cmdlines(struct tep_handle *tep)
         return r;
 }
 
+int load_print_strings(struct tep_handle *tep)
+{
+        char *buf = NULL;
+        int r;
+
+        buf = tracefs_instance_file_read(NULL, "printk_formats", NULL);
+        if (!buf)
+                return -1;
+        r = tep_parse_printk_formats(tep, buf);
+        free(buf);
+        return r;
+}
+
 int load_kallsyms(struct tep_handle *tep)
 {
         char *line = NULL;
@@ -101,7 +126,8 @@ FILES
 
 SEE ALSO
 --------
-_libtraceevent(3)_, _trace-cmd(1)_, _tep_register_comm(3)_, _tep_register_function(3)_
+_libtraceevent(3)_, _trace-cmd(1)_, _tep_register_comm(3)_, _tep_register_function(3)_,
+_tep_register_print_string_(3)
 
 AUTHOR
 ------
diff --git a/src/event-parse.c b/src/event-parse.c
index 0d12ec4..cec4ad1 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -913,6 +913,57 @@ void tep_print_printk(struct tep_handle *tep)
 	}
 }
 
+/**
+ * tep_parse_printk_formats - Parse the address to strings
+ * @tep: a handle to the trace event parser
+ * @buf: A string buffer that holds the content of printk_formats and ends with '\0'
+ *
+ * This is a helper function to parse the address to printk formats in
+ * the kernel. Some events use %s to a kernel address that holds a constant
+ * string. The printk_formats file has a mapping of these addresses to the
+ * strings that are in the kernel. This parses the content of that file
+ * and registers those strings and their addresses so that the parsing of
+ * events can display the string as the event only has the address of the string.
+ *
+ * Returns 0 on success, and -1 on error.
+ */
+int tep_parse_printk_formats(struct tep_handle *tep, const char *buf)
+{
+	unsigned long long addr;
+	char *copy;
+	char *printk;
+	char *line;
+	char *next = NULL;
+	char *addr_str;
+	char *fmt;
+	int ret = -1;
+
+	copy = strdup(buf);
+	if (!copy)
+		return -1;
+
+	line = strtok_r(copy, "\n", &next);
+	while (line) {
+		addr_str = strtok_r(line, ":", &fmt);
+		if (!addr_str) {
+			tep_warning("printk format with empty entry");
+			break;
+		}
+		addr = strtoull(addr_str, NULL, 16);
+		/* fmt still has a space, skip it */
+		printk = strdup(fmt+1);
+		if (!printk)
+			goto out;
+		line = strtok_r(NULL, "\n", &next);
+		tep_register_print_string(tep, printk, addr);
+		free(printk);
+	}
+	ret = 0;
+ out:
+	free(copy);
+	return ret;
+}
+
 static struct tep_event *alloc_event(void)
 {
 	return calloc(1, sizeof(struct tep_event));
diff --git a/src/event-parse.h b/src/event-parse.h
index 078b202..05b156b 100644
--- a/src/event-parse.h
+++ b/src/event-parse.h
@@ -443,6 +443,7 @@ int tep_parse_saved_cmdlines(struct tep_handle *tep, const char *buf);
 int tep_parse_kallsyms(struct tep_handle *tep, const char *kallsyms);
 int tep_register_function(struct tep_handle *tep, char *name,
 			  unsigned long long addr, char *mod);
+int tep_parse_printk_formats(struct tep_handle *tep, const char *buf);
 int tep_register_print_string(struct tep_handle *tep, const char *fmt,
 			      unsigned long long addr);
 bool tep_is_pid_registered(struct tep_handle *tep, int pid);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-04-08 21:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-08 21:41 [PATCH v3 0/5] libtraceevent: Copy parsing functions from trace-cmd Steven Rostedt
2021-04-08 21:41 ` [PATCH v3 1/5] libtraceevent: Update gitignore Steven Rostedt
2021-04-08 21:41 ` [PATCH v3 2/5] libtraceevent: Fix dependencies in Documentation Makefile Steven Rostedt
2021-04-08 21:41 ` [PATCH v3 3/5] libtraceevent: Add the API tep_parse_kallsyms() Steven Rostedt
2021-04-08 21:41 ` [PATCH v3 4/5] libtraceevent: Add the API tep_parse_saved_cmdlines() Steven Rostedt
2021-04-08 21:42 ` [PATCH v3 5/5] libtraceevent: Add the API tep_parse_printk_formats() Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).