Skip to contentSkip to conversation

perf: parser fix for btrfs tracepoints

PATCH New Hidetoshi Seto 1 participant 4 messages Dec 7, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover perf: parser fix for btrfs tracepoints

After playing with v3.2-rc4, I found that the perf command failed to parse record contain data from (relatively new) btrfs tracepoints.

This patch set will improve parser code of perf command and allow it to handle these data from btrfs tracepoints well.

Thanks,
H.Seto

Hidetoshi Seto (3):
perf: parse greater/less than or equal
perf: allow processing single op args
perf: allow typecast for signed value

 tools/perf/util/trace-event-parse.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)
#1 lore raw

PATCH 1/3 perf: parse greater/less than or equal

Some btrfs tracepoints have complex format like following, but perf command failed to parse it:

print fmt: "%s", ((REC->id >= min) || (REC->id <= max )) ?

        __print_symbolic(REC->id, { 1ULL, "ROOT_TREE" }, ... ) : "-"
  $ perf script
  Warning: unknown op '>='
  Warning: Error: expected type 5 but read 1
  Warning: failed to read event print fmt for btrfs_transaction_commit

This patch allow perf command to parse operation tokens, '>=' and '<='.

---
 tools/perf/util/trace-event-parse.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
tools/perf/util/trace-event-parse.c +2 -0
index 0a7ed5b..c2adc76 100644
@@ -1229,6 +1229,8 @@ process_op(struct event *event, struct print_arg *arg, char **tok)
 		   strcmp(token, "/") == 0 ||
 		   strcmp(token, "<") == 0 ||
 		   strcmp(token, ">") == 0 ||
+		   strcmp(token, "<=") == 0 ||
+		   strcmp(token, ">=") == 0 ||
 		   strcmp(token, "==") == 0 ||
 		   strcmp(token, "!=") == 0) {
 
Signature · 1 line
1.7.7.3
#2 lore raw

PATCH 2/3 perf: allow processing single op args

In reply to Hidetoshi Seto

I got following error from record with btrfs tracepoints:

  $ perf script
  Fatal: unknown op '-'

It seems that perf failed to handle '-' in the following format:

print fmt: "%s", ((REC->id >= -9) || (REC->id <= 7)) ? "x" : "y"

                                ~

process_arg() have code to parse '-9' as a "single op" arg, which is PRINT_OP as type, '-' as op and have '9' as right arg but no left arg. However arg_num_eval() have no code to handle this "single op" arg even it is parsed successfully.

This patch allow perf to process such "single op" args.

---
 tools/perf/util/trace-event-parse.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
tools/perf/util/trace-event-parse.c +18 -0
index c2adc76..b709f78 100644
@@ -1355,6 +1355,24 @@ static long long arg_num_eval(struct print_arg *arg)
 		val = arg_num_eval(arg->typecast.item);
 		break;
 	case PRINT_OP:
+		if (!arg->op.left || arg->op.left->type == PRINT_NULL) {
+			/* handle single op */
+			right = arg_num_eval(arg->op.right);
+			switch (arg->op.op[0]) {
+			case '!':
+				val = !right;
+				break;
+			case '+':
+				val = right;
+				break;
+			case '-':
+				val = -right;
+				break;
+			default:
+				die("unknown single op %s", arg->op.op);
+			}
+			break;
+		}
 		switch (arg->op.op[0]) {
 		case '|':
 			left = arg_num_eval(arg->op.left);
Signature · 1 line
1.7.7.3
#3 lore raw

PATCH 3/3 perf: allow typecast for signed value

In reply to Hidetoshi Seto

Still I got following warning with btrfs tracepoints:

  $ perf script
  Warning: Error: expected type 5 but read 4
  Warning: Error: expected type 5 but read 0

I found that the complained format is:

print fmt: "%s", (REC->val >= (u64)-4) ? "-" : __print_symbolic(...)

                                     ~

In perf's parser, the typecast, which is processed in process_paren(), only expects that (unsigned) token or another parenthesis will follow to the typecast. It should expect signed tokens can be there too.

---
 tools/perf/util/trace-event-parse.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
tools/perf/util/trace-event-parse.c +3 -2
index b709f78..032f3de 100644
@@ -1645,10 +1645,11 @@ process_paren(struct event *event, struct print_arg *arg, char **tok)
 	type = read_token_item(&token);
 
 	/*
-	 * If the next token is an item or another open paren, then
-	 * this was a typecast.
+	 * If the next token is an item (might be signed, with single op "-")
+	 * or another open paren, then this was a typecast.
 	 */
 	if (event_item_type(type) ||
+	    (type == EVENT_OP && strcmp(token, "-") == 0) ||
 	    (type == EVENT_DELIM && strcmp(token, "(") == 0)) {
 
 		/* make this a typecast and contine */
Signature · 1 line
1.7.7.3