tools lib traceevent: Handle __attribute__((user)) in field names
authorSteven Rostedt (VMware) <rostedt@goodmis.org>
Tue, 24 Mar 2020 20:08:47 +0000 (16:08 -0400)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 18 Jun 2020 13:22:27 +0000 (10:22 -0300)
Commit c61f13eaa1ee1 ("gcc-plugins: Add structleak for more stack
initialization") added "__attribute__((user))" to the user when
stackleak detector is enabled. This now appears in the field format of
system call trace events for system calls that have user buffers. The
"__attribute__((user))" breaks the parsing in libtraceevent. That needs
to be handled.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jaewon Kim <jaewon31.kim@samsung.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kees Kook <keescook@chromium.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: linux-mm@kvack.org
Cc: linux-trace-devel@vger.kernel.org
Link: http://lore.kernel.org/lkml/20200324200956.663647256@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/lib/traceevent/event-parse.c

index eec96c31ea9e520275ed67a662e64ab4e9d3b8f8..010e60d5a0817c19f93c099c34c082c7c65b3ce5 100644 (file)
@@ -1444,6 +1444,7 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
        enum tep_event_type type;
        char *token;
        char *last_token;
+       char *delim = " ";
        int count = 0;
        int ret;
 
@@ -1504,13 +1505,49 @@ static int event_read_fields(struct tep_event *event, struct tep_format_field **
                                        field->flags |= TEP_FIELD_IS_POINTER;
 
                                if (field->type) {
-                                       ret = append(&field->type, " ", last_token);
+                                       ret = append(&field->type, delim, last_token);
                                        free(last_token);
                                        if (ret < 0)
                                                goto fail;
                                } else
                                        field->type = last_token;
                                last_token = token;
+                               delim = " ";
+                               continue;
+                       }
+
+                       /* Handle __attribute__((user)) */
+                       if ((type == TEP_EVENT_DELIM) &&
+                           strcmp("__attribute__", last_token) == 0 &&
+                           token[0] == '(') {
+                               int depth = 1;
+                               int ret;
+
+                               ret = append(&field->type, " ", last_token);
+                               ret |= append(&field->type, "", "(");
+                               if (ret < 0)
+                                       goto fail;
+
+                               delim = " ";
+                               while ((type = read_token(&token)) != TEP_EVENT_NONE) {
+                                       if (type == TEP_EVENT_DELIM) {
+                                               if (token[0] == '(')
+                                                       depth++;
+                                               else if (token[0] == ')')
+                                                       depth--;
+                                               if (!depth)
+                                                       break;
+                                               ret = append(&field->type, "", token);
+                                               delim = "";
+                                       } else {
+                                               ret = append(&field->type, delim, token);
+                                               delim = " ";
+                                       }
+                                       if (ret < 0)
+                                               goto fail;
+                                       free(last_token);
+                                       last_token = token;
+                               }
                                continue;
                        }
                        break;