Commit 0959b8d6 authored by Steven Rostedt's avatar Steven Rostedt Committed by Ingo Molnar

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: default avatarSteven 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: default avatarIngo Molnar <mingo@elte.hu>
parent 298ebc3e
...@@ -1046,6 +1046,35 @@ out_free: ...@@ -1046,6 +1046,35 @@ out_free:
return EVENT_ERROR; return EVENT_ERROR;
} }
static enum event_type
process_array(struct event *event, struct print_arg *top, char **tok)
{
struct print_arg *arg;
enum event_type type;
char *token = NULL;
arg = malloc_or_die(sizeof(*arg));
memset(arg, 0, sizeof(*arg));
*tok = NULL;
type = process_arg(event, arg, &token);
if (test_type_token(type, token, EVENT_OP, (char *)"]"))
goto out_free;
top->op.right = arg;
free_token(token);
type = read_token_item(&token);
*tok = token;
return type;
out_free:
free_token(*tok);
free_arg(arg);
return EVENT_ERROR;
}
static int get_op_prio(char *op) static int get_op_prio(char *op)
{ {
if (!op[1]) { if (!op[1]) {
...@@ -1192,6 +1221,18 @@ process_op(struct event *event, struct print_arg *arg, char **tok) ...@@ -1192,6 +1221,18 @@ process_op(struct event *event, struct print_arg *arg, char **tok)
arg->op.right = right; arg->op.right = right;
} else if (strcmp(token, "[") == 0) {
left = malloc_or_die(sizeof(*left));
*left = *arg;
arg->type = PRINT_OP;
arg->op.op = token;
arg->op.left = left;
arg->op.prio = 0;
type = process_array(event, arg, tok);
} else { } else {
die("unknown op '%s'", token); die("unknown op '%s'", token);
/* the arg is now the left side */ /* the arg is now the left side */
...@@ -1931,6 +1972,7 @@ static unsigned long long eval_num_arg(void *data, int size, ...@@ -1931,6 +1972,7 @@ static unsigned long long eval_num_arg(void *data, int size,
{ {
unsigned long long val = 0; unsigned long long val = 0;
unsigned long long left, right; unsigned long long left, right;
struct print_arg *larg;
switch (arg->type) { switch (arg->type) {
case PRINT_NULL: case PRINT_NULL:
...@@ -1957,6 +1999,26 @@ static unsigned long long eval_num_arg(void *data, int size, ...@@ -1957,6 +1999,26 @@ static unsigned long long eval_num_arg(void *data, int size,
return 0; return 0;
break; break;
case PRINT_OP: case PRINT_OP:
if (strcmp(arg->op.op, "[") == 0) {
/*
* Arrays are special, since we don't want
* to read the arg as is.
*/
if (arg->op.left->type != PRINT_FIELD)
goto default_op; /* oops, all bets off */
larg = arg->op.left;
if (!larg->field.field) {
larg->field.field =
find_any_field(event, larg->field.name);
if (!larg->field.field)
die("field %s not found", larg->field.name);
}
right = eval_num_arg(data, size, event, arg->op.right);
val = read_size(data + larg->field.field->offset +
right * long_size, long_size);
break;
}
default_op:
left = eval_num_arg(data, size, event, arg->op.left); left = eval_num_arg(data, size, event, arg->op.left);
right = eval_num_arg(data, size, event, arg->op.right); right = eval_num_arg(data, size, event, arg->op.right);
switch (arg->op.op[0]) { switch (arg->op.op[0]) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment