aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-10-14 15:43:35 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-15 04:42:36 -0400
commit0959b8d65ce26131c2d5ccfa518a7b76529280fa (patch)
treeeae5c5c426623156142dc406f92b42d358dd53c2
parent298ebc3ef2a6c569b3eb51651f04e26aecbf8a1d (diff)
perf tools: Handle arrays in print fields for trace parsing
The array used by the ftrace stack events (caller[x]) causes issues with the parser. This adds code to handle the case, but it also assumes that the array is of type long. Note, this is a special case used (currently) only by the ftrace user and kernel stack records. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> LKML-Reference: <20091014194358.124833639@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/util/trace-event-parse.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index 3e643f5da202..7aeedb09ea7d 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -1046,6 +1046,35 @@ out_free:
1046 return EVENT_ERROR; 1046 return EVENT_ERROR;
1047} 1047}
1048 1048
1049static enum event_type
1050process_array(struct event *event, struct print_arg *top, char **tok)
1051{
1052 struct print_arg *arg;
1053 enum event_type type;
1054 char *token = NULL;
1055
1056 arg = malloc_or_die(sizeof(*arg));
1057 memset(arg, 0, sizeof(*arg));
1058
1059 *tok = NULL;
1060 type = process_arg(event, arg, &token);
1061 if (test_type_token(type, token, EVENT_OP, (char *)"]"))
1062 goto out_free;
1063
1064 top->op.right = arg;
1065
1066 free_token(token);
1067 type = read_token_item(&token);
1068 *tok = token;
1069
1070 return type;
1071
1072out_free:
1073 free_token(*tok);
1074 free_arg(arg);
1075 return EVENT_ERROR;
1076}
1077
1049static int get_op_prio(char *op) 1078static int get_op_prio(char *op)
1050{ 1079{
1051 if (!op[1]) { 1080 if (!op[1]) {
@@ -1192,6 +1221,18 @@ process_op(struct event *event, struct print_arg *arg, char **tok)
1192 1221
1193 arg->op.right = right; 1222 arg->op.right = right;
1194 1223
1224 } else if (strcmp(token, "[") == 0) {
1225
1226 left = malloc_or_die(sizeof(*left));
1227 *left = *arg;
1228
1229 arg->type = PRINT_OP;
1230 arg->op.op = token;
1231 arg->op.left = left;
1232
1233 arg->op.prio = 0;
1234 type = process_array(event, arg, tok);
1235
1195 } else { 1236 } else {
1196 die("unknown op '%s'", token); 1237 die("unknown op '%s'", token);
1197 /* the arg is now the left side */ 1238 /* the arg is now the left side */
@@ -1931,6 +1972,7 @@ static unsigned long long eval_num_arg(void *data, int size,
1931{ 1972{
1932 unsigned long long val = 0; 1973 unsigned long long val = 0;
1933 unsigned long long left, right; 1974 unsigned long long left, right;
1975 struct print_arg *larg;
1934 1976
1935 switch (arg->type) { 1977 switch (arg->type) {
1936 case PRINT_NULL: 1978 case PRINT_NULL:
@@ -1957,6 +1999,26 @@ static unsigned long long eval_num_arg(void *data, int size,
1957 return 0; 1999 return 0;
1958 break; 2000 break;
1959 case PRINT_OP: 2001 case PRINT_OP:
2002 if (strcmp(arg->op.op, "[") == 0) {
2003 /*
2004 * Arrays are special, since we don't want
2005 * to read the arg as is.
2006 */
2007 if (arg->op.left->type != PRINT_FIELD)
2008 goto default_op; /* oops, all bets off */
2009 larg = arg->op.left;
2010 if (!larg->field.field) {
2011 larg->field.field =
2012 find_any_field(event, larg->field.name);
2013 if (!larg->field.field)
2014 die("field %s not found", larg->field.name);
2015 }
2016 right = eval_num_arg(data, size, event, arg->op.right);
2017 val = read_size(data + larg->field.field->offset +
2018 right * long_size, long_size);
2019 break;
2020 }
2021 default_op:
1960 left = eval_num_arg(data, size, event, arg->op.left); 2022 left = eval_num_arg(data, size, event, arg->op.left);
1961 right = eval_num_arg(data, size, event, arg->op.right); 2023 right = eval_num_arg(data, size, event, arg->op.right);
1962 switch (arg->op.op[0]) { 2024 switch (arg->op.op[0]) {