Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aba91595 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo
Browse files

tracing/kprobes: Fix handling of argument names



Set "argN" name for each argument automatically if it has no specified name.
Since dynamic trace event(kprobe_events) accepts special characters for its
argument, its format can show those special characters (e.g. '$', '%', '+').
However, perf can't parse those format because of the character (especially
'%') mess up the format.  This sets "argX" name for those arguments if user
omitted the argument names.

E.g.
 # echo 'p do_fork %ax IP=%ip $stack' > tracing/kprobe_events
 # cat tracing/kprobe_events
 p:kprobes/p_do_fork_0 do_fork arg1=%ax IP=%ip arg3=$stack

Reported-by: default avatarSrikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
LKML-Reference: <20100827113906.22882.59312.stgit@ltc236.sdl.hitachi.co.jp>
Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 367e94c1
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -997,15 +997,18 @@ static int create_trace_probe(int argc, char **argv)

		/* Parse argument name */
		arg = strchr(argv[i], '=');
		if (arg)
		if (arg) {
			*arg++ = '\0';
		else
			tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
		} else {
			arg = argv[i];
			/* If argument name is omitted, set "argN" */
			snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
			tp->args[i].name = kstrdup(buf, GFP_KERNEL);
		}

		tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
		if (!tp->args[i].name) {
			pr_info("Failed to allocate argument%d name '%s'.\n",
				i, argv[i]);
			pr_info("Failed to allocate argument[%d] name.\n", i);
			ret = -ENOMEM;
			goto error;
		}
@@ -1014,7 +1017,7 @@ static int create_trace_probe(int argc, char **argv)
			*tmp = '_';	/* convert : to _ */

		if (conflict_field_name(tp->args[i].name, tp->args, i)) {
			pr_info("Argument%d name '%s' conflicts with "
			pr_info("Argument[%d] name '%s' conflicts with "
				"another field.\n", i, argv[i]);
			ret = -EINVAL;
			goto error;
@@ -1023,7 +1026,7 @@ static int create_trace_probe(int argc, char **argv)
		/* Parse fetch argument */
		ret = parse_probe_arg(arg, tp, &tp->args[i], is_return);
		if (ret) {
			pr_info("Parse error at argument%d. (%d)\n", i, ret);
			pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
			goto error;
		}
	}