All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] libtraceevent: Add tep_print_selected_fields()
@ 2021-08-02 11:27 Yordan Karadzhov (VMware)
  2021-08-02 11:39 ` Yordan Karadzhov
  2021-08-02 16:29 ` Steven Rostedt
  0 siblings, 2 replies; 6+ messages in thread
From: Yordan Karadzhov (VMware) @ 2021-08-02 11:27 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel, Yordan Karadzhov (VMware)

The new method can print only a subset of the unique data fields of
the trace event. The print format is derived from the parsing tokens
(tep_print_parse objects) of the event. As a byproduct of this change
the existing method tep_print_fields() gets upgraded to use the
formats provided by the tokens.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 src/event-parse.c | 87 ++++++++++++++++++++++++++++++++++++++++++-----
 src/event-parse.h |  3 ++
 2 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/src/event-parse.c b/src/event-parse.c
index f42ae38..7302f3d 100644
--- a/src/event-parse.c
+++ b/src/event-parse.c
@@ -3585,6 +3585,8 @@ tep_find_field(struct tep_event *event, const char *name)
 	return format;
 }
 
+
+
 /**
  * tep_find_any_field - find any field by name
  * @event: handle for the event
@@ -5333,6 +5335,19 @@ static int is_printable_array(char *p, unsigned int len)
 	return 1;
 }
 
+static void dynamic_offset(struct tep_handle *tep,
+			   struct tep_format_field *field,
+			   void *data,
+			   unsigned int *offset,
+			   unsigned int *len)
+{
+	unsigned long long val;
+
+	val = tep_read_number(tep, data + field->offset, field->size);
+	*offset = val & SHRT_MAX;
+	*len = val >> 16;
+}
+
 void tep_print_field(struct trace_seq *s, void *data,
 		     struct tep_format_field *field)
 {
@@ -5343,12 +5358,9 @@ void tep_print_field(struct trace_seq *s, void *data,
 	if (field->flags & TEP_FIELD_IS_ARRAY) {
 		offset = field->offset;
 		len = field->size;
-		if (field->flags & TEP_FIELD_IS_DYNAMIC) {
-			val = tep_read_number(tep, data + offset, len);
-			offset = val;
-			len = offset >> 16;
-			offset &= 0xffff;
-		}
+		if (field->flags & TEP_FIELD_IS_DYNAMIC)
+			dynamic_offset(tep, field, data, &offset, &len);
+
 		if (field->flags & TEP_FIELD_IS_STRING &&
 		    is_printable_array(data + offset, len)) {
 			trace_seq_printf(s, "%s", (char *)data + offset);
@@ -5398,19 +5410,76 @@ void tep_print_field(struct trace_seq *s, void *data,
 	}
 }
 
-void tep_print_fields(struct trace_seq *s, void *data,
-		      int size __maybe_unused, struct tep_event *event)
+static struct tep_print_parse *parse_format_next(struct tep_print_parse *parse)
+{
+	while (parse) {
+		if (strncmp(parse->format, "%", 1) == 0)
+			break;
+
+		parse = parse->next;
+	}
+
+	return parse;
+}
+
+static void tep_print_fmt_field(struct trace_seq *s, void *data,
+				const char *format,
+				struct tep_format_field *field)
+{
+	struct tep_handle *tep = field->event->tep;
+	unsigned int len, offset;
+	unsigned long long val;
+
+	if (field->flags & TEP_FIELD_IS_DYNAMIC) {
+		dynamic_offset(tep, field, data, &offset, &len);
+		if (len)
+			trace_seq_printf(s, format, (char *)data + offset);
+		else
+			trace_seq_printf(s, format, "(nil)");
+	} else {
+		val = tep_read_number(tep, data + field->offset, field->size);
+		trace_seq_printf(s, format, val);
+	}
+}
+
+void tep_print_selected_fields(struct trace_seq *s, void *data,
+			       struct tep_event *event,
+			       int ignore_mask)
 {
 	struct tep_format_field *field;
+	struct tep_print_parse *parse;
+	unsigned int len;
+	int field_mask = 1;
 
+	parse = event->print_fmt.print_cache;
 	field = event->format.fields;
 	while (field) {
+		parse = parse_format_next(parse);
+
+		if (field_mask & ignore_mask)
+			goto next;
+
 		trace_seq_printf(s, " %s=", field->name);
-		tep_print_field(s, data, field);
+
+		len = strlen(parse->format);
+		if (len > 0 && parse->format[len - 1] == 'x')
+			trace_seq_printf(s, "0x");
+
+		tep_print_fmt_field(s, data, parse->format, field);
+
+ next:
 		field = field->next;
+		parse = parse->next;
+		field_mask *= 2;
 	}
 }
 
+void tep_print_fields(struct trace_seq *s, void *data,
+		      int size __maybe_unused, struct tep_event *event)
+{
+	tep_print_selected_fields(s, data, event, 0);
+}
+
 static int print_function(struct trace_seq *s, const char *format,
 			  void *data, int size, struct tep_event *event,
 			  struct tep_print_arg *arg)
diff --git a/src/event-parse.h b/src/event-parse.h
index d4a876f..fe0fbf4 100644
--- a/src/event-parse.h
+++ b/src/event-parse.h
@@ -547,6 +547,9 @@ void tep_print_field(struct trace_seq *s, void *data,
 		     struct tep_format_field *field);
 void tep_print_fields(struct trace_seq *s, void *data,
 		      int size __maybe_unused, struct tep_event *event);
+void tep_print_selected_fields(struct trace_seq *s, void *data,
+			       struct tep_event *event,
+			       int ignore_mask);
 int tep_strerror(struct tep_handle *tep, enum tep_errno errnum,
 		 char *buf, size_t buflen);
 
-- 
2.30.2


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

end of thread, other threads:[~2021-08-03 13:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-02 11:27 [RFC PATCH] libtraceevent: Add tep_print_selected_fields() Yordan Karadzhov (VMware)
2021-08-02 11:39 ` Yordan Karadzhov
2021-08-02 16:30   ` Steven Rostedt
2021-08-02 16:29 ` Steven Rostedt
2021-08-03 12:42   ` Yordan Karadzhov
2021-08-03 13:48     ` Steven Rostedt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.