Commit 35abb67d authored by Omar Sandoval's avatar Omar Sandoval Committed by Steven Rostedt

tracing: expose current->comm to [ku]probe events

ftrace is very quick to give up on saving the task command line (see
`trace_save_cmdline()`). The workaround for events which really care
about the command line is to explicitly assign it as part of the entry.
However, this doesn't work for kprobe events, as there's no
straightforward way to get access to current->comm. Add a kprobe/uprobe
event variable $comm which provides exactly that.

Link: http://lkml.kernel.org/r/f59b472033b943a370f5f48d0af37698f409108f.1465435894.git.osandov@fb.comAcked-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 345ddcc8
...@@ -40,6 +40,7 @@ Synopsis of kprobe_events ...@@ -40,6 +40,7 @@ Synopsis of kprobe_events
$stackN : Fetch Nth entry of stack (N >= 0) $stackN : Fetch Nth entry of stack (N >= 0)
$stack : Fetch stack address. $stack : Fetch stack address.
$retval : Fetch return value.(*) $retval : Fetch return value.(*)
$comm : Fetch current task comm.
+|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
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
...@@ -62,6 +63,8 @@ offset, and container-size (usually 32). The syntax is; ...@@ -62,6 +63,8 @@ offset, and container-size (usually 32). The syntax is;
b<bit-width>@<bit-offset>/<container-size> b<bit-width>@<bit-offset>/<container-size>
For $comm, the default type is "string"; any other type is invalid.
Per-Probe Event Filtering Per-Probe Event Filtering
------------------------- -------------------------
......
...@@ -36,6 +36,7 @@ Synopsis of uprobe_tracer ...@@ -36,6 +36,7 @@ Synopsis of uprobe_tracer
$stackN : Fetch Nth entry of stack (N >= 0) $stackN : Fetch Nth entry of stack (N >= 0)
$stack : Fetch stack address. $stack : Fetch stack address.
$retval : Fetch return value.(*) $retval : Fetch return value.(*)
$comm : Fetch current task comm.
+|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**) +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
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
...@@ -57,6 +58,8 @@ offset, and container-size (usually 32). The syntax is; ...@@ -57,6 +58,8 @@ offset, and container-size (usually 32). The syntax is;
b<bit-width>@<bit-offset>/<container-size> b<bit-width>@<bit-offset>/<container-size>
For $comm, the default type is "string"; any other type is invalid.
Event Profiling Event Profiling
--------------- ---------------
......
...@@ -587,6 +587,7 @@ static int create_trace_kprobe(int argc, char **argv) ...@@ -587,6 +587,7 @@ static int create_trace_kprobe(int argc, char **argv)
* $retval : fetch return value * $retval : fetch return value
* $stack : fetch stack address * $stack : fetch stack address
* $stackN : fetch Nth of stack (N:0-) * $stackN : fetch Nth of stack (N:0-)
* $comm : fetch current task comm
* @ADDR : fetch memory at ADDR (ADDR should be in kernel) * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
* @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
* %REG : fetch register REG * %REG : fetch register REG
......
...@@ -218,6 +218,28 @@ free_bitfield_fetch_param(struct bitfield_fetch_param *data) ...@@ -218,6 +218,28 @@ free_bitfield_fetch_param(struct bitfield_fetch_param *data)
kfree(data); kfree(data);
} }
void FETCH_FUNC_NAME(comm, string)(struct pt_regs *regs,
void *data, void *dest)
{
int maxlen = get_rloc_len(*(u32 *)dest);
u8 *dst = get_rloc_data(dest);
long ret;
if (!maxlen)
return;
ret = strlcpy(dst, current->comm, maxlen);
*(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest));
}
NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string));
void FETCH_FUNC_NAME(comm, string_size)(struct pt_regs *regs,
void *data, void *dest)
{
*(u32 *)dest = strlen(current->comm) + 1;
}
NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string_size));
static const struct fetch_type *find_fetch_type(const char *type, static const struct fetch_type *find_fetch_type(const char *type,
const struct fetch_type *ftbl) const struct fetch_type *ftbl)
{ {
...@@ -348,6 +370,11 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, ...@@ -348,6 +370,11 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
} }
} else } else
ret = -EINVAL; ret = -EINVAL;
} else if (strcmp(arg, "comm") == 0) {
if (strcmp(t->name, "string") != 0 &&
strcmp(t->name, "string_size") != 0)
return -EINVAL;
f->fn = t->fetch[FETCH_MTD_comm];
} else } else
ret = -EINVAL; ret = -EINVAL;
...@@ -522,6 +549,12 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size, ...@@ -522,6 +549,12 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
arg[t - parg->comm] = '\0'; arg[t - parg->comm] = '\0';
t++; t++;
} }
/*
* The default type of $comm should be "string", and it can't be
* dereferenced.
*/
if (!t && strcmp(arg, "$comm") == 0)
t = "string";
parg->type = find_fetch_type(t, ftbl); parg->type = find_fetch_type(t, ftbl);
if (!parg->type) { if (!parg->type) {
pr_info("Unsupported type: %s\n", t); pr_info("Unsupported type: %s\n", t);
......
...@@ -102,6 +102,7 @@ enum { ...@@ -102,6 +102,7 @@ enum {
FETCH_MTD_reg = 0, FETCH_MTD_reg = 0,
FETCH_MTD_stack, FETCH_MTD_stack,
FETCH_MTD_retval, FETCH_MTD_retval,
FETCH_MTD_comm,
FETCH_MTD_memory, FETCH_MTD_memory,
FETCH_MTD_symbol, FETCH_MTD_symbol,
FETCH_MTD_deref, FETCH_MTD_deref,
...@@ -183,6 +184,14 @@ DECLARE_BASIC_FETCH_FUNCS(bitfield); ...@@ -183,6 +184,14 @@ DECLARE_BASIC_FETCH_FUNCS(bitfield);
#define fetch_bitfield_string NULL #define fetch_bitfield_string NULL
#define fetch_bitfield_string_size NULL #define fetch_bitfield_string_size NULL
/* comm only makes sense as a string */
#define fetch_comm_u8 NULL
#define fetch_comm_u16 NULL
#define fetch_comm_u32 NULL
#define fetch_comm_u64 NULL
DECLARE_FETCH_FUNC(comm, string);
DECLARE_FETCH_FUNC(comm, string_size);
/* /*
* Define macro for basic types - we don't need to define s* types, because * Define macro for basic types - we don't need to define s* types, because
* we have to care only about bitwidth at recording time. * we have to care only about bitwidth at recording time.
...@@ -213,6 +222,7 @@ DEFINE_FETCH_##method(u64) ...@@ -213,6 +222,7 @@ DEFINE_FETCH_##method(u64)
ASSIGN_FETCH_FUNC(reg, ftype), \ ASSIGN_FETCH_FUNC(reg, ftype), \
ASSIGN_FETCH_FUNC(stack, ftype), \ ASSIGN_FETCH_FUNC(stack, ftype), \
ASSIGN_FETCH_FUNC(retval, ftype), \ ASSIGN_FETCH_FUNC(retval, ftype), \
ASSIGN_FETCH_FUNC(comm, ftype), \
ASSIGN_FETCH_FUNC(memory, ftype), \ ASSIGN_FETCH_FUNC(memory, ftype), \
ASSIGN_FETCH_FUNC(symbol, ftype), \ ASSIGN_FETCH_FUNC(symbol, ftype), \
ASSIGN_FETCH_FUNC(deref, ftype), \ ASSIGN_FETCH_FUNC(deref, ftype), \
......
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