Commit 6218bf9f authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Steven Rostedt (VMware)

tracing/probe: Add immediate parameter support

Add immediate value parameter (\1234) support to
probe events. This allows you to specify an immediate
(or dummy) parameter instead of fetching from memory
or register.

This feature looks odd, but imagine when you put a probe
on a code to trace some data. If the code is compiled into
2 instructions and 1 instruction has a value but other has
nothing since it is optimized out.
In that case, you can not fold those into one event, even
if ftrace supported multiple probes on one event.
With this feature, you can set a dummy value like
foo=\deadbeef instead of something like foo=%di.

Link: http://lkml.kernel.org/r/156095690733.28024.13258186548822649469.stgit@devnote2Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent ab10d69e
...@@ -52,6 +52,7 @@ Synopsis of kprobe_events ...@@ -52,6 +52,7 @@ Synopsis of kprobe_events
$retval : Fetch return value.(\*2) $retval : Fetch return value.(\*2)
$comm : Fetch current task comm. $comm : Fetch current task comm.
+|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*3)(\*4) +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*3)(\*4)
\IMM : Store an immediate value to the argument.
NAME=FETCHARG : Set NAME as the argument name of FETCHARG. NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
(u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
......
...@@ -45,6 +45,7 @@ Synopsis of uprobe_tracer ...@@ -45,6 +45,7 @@ Synopsis of uprobe_tracer
$retval : Fetch return value.(\*1) $retval : Fetch return value.(\*1)
$comm : Fetch current task comm. $comm : Fetch current task comm.
+|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*2)(\*3) +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*2)(\*3)
\IMM : Store an immediate value to the argument.
NAME=FETCHARG : Set NAME as the argument name of FETCHARG. NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
(u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
......
...@@ -4848,7 +4848,7 @@ static const char readme_msg[] = ...@@ -4848,7 +4848,7 @@ static const char readme_msg[] =
#else #else
"\t $stack<index>, $stack, $retval, $comm,\n" "\t $stack<index>, $stack, $retval, $comm,\n"
#endif #endif
"\t +|-[u]<offset>(<fetcharg>)\n" "\t +|-[u]<offset>(<fetcharg>), \\imm-value\n"
"\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n" "\t type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n"
"\t b<bit-width>@<bit-offset>/<container-size>, ustring,\n" "\t b<bit-width>@<bit-offset>/<container-size>, ustring,\n"
"\t <type>\\[<array-size>\\]\n" "\t <type>\\[<array-size>\\]\n"
......
...@@ -316,6 +316,17 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, ...@@ -316,6 +316,17 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
return -EINVAL; return -EINVAL;
} }
static int str_to_immediate(char *str, unsigned long *imm)
{
if (isdigit(str[0]))
return kstrtoul(str, 0, imm);
else if (str[0] == '-')
return kstrtol(str, 0, (long *)imm);
else if (str[0] == '+')
return kstrtol(str + 1, 0, (long *)imm);
return -EINVAL;
}
/* Recursive argument parser */ /* Recursive argument parser */
static int static int
parse_probe_arg(char *arg, const struct fetch_type *type, parse_probe_arg(char *arg, const struct fetch_type *type,
...@@ -444,6 +455,13 @@ parse_probe_arg(char *arg, const struct fetch_type *type, ...@@ -444,6 +455,13 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
code->offset = offset; code->offset = offset;
} }
break; break;
case '\\': /* Immediate value */
ret = str_to_immediate(arg + 1, &code->immediate);
if (ret)
trace_probe_log_err(offs + 1, BAD_IMM);
else
code->op = FETCH_OP_IMM;
break;
} }
if (!ret && code->op == FETCH_OP_NOP) { if (!ret && code->op == FETCH_OP_NOP) {
/* Parsed, but do not find fetch method */ /* Parsed, but do not find fetch method */
......
...@@ -408,6 +408,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, ...@@ -408,6 +408,7 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
C(BAD_VAR, "Invalid $-valiable specified"), \ C(BAD_VAR, "Invalid $-valiable specified"), \
C(BAD_REG_NAME, "Invalid register name"), \ C(BAD_REG_NAME, "Invalid register name"), \
C(BAD_MEM_ADDR, "Invalid memory address"), \ C(BAD_MEM_ADDR, "Invalid memory address"), \
C(BAD_IMM, "Invalid immediate value"), \
C(FILE_ON_KPROBE, "File offset is not available with kprobe"), \ C(FILE_ON_KPROBE, "File offset is not available with kprobe"), \
C(BAD_FILE_OFFS, "Invalid file offset value"), \ C(BAD_FILE_OFFS, "Invalid file offset value"), \
C(SYM_ON_UPROBE, "Symbol is not available with uprobe"), \ C(SYM_ON_UPROBE, "Symbol is not available with uprobe"), \
......
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