aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2016-06-08 21:38:02 -0400
committerSteven Rostedt <rostedt@goodmis.org>2016-06-20 09:54:19 -0400
commit35abb67de744b5dbaec54381f2f9e0246089331d (patch)
treebe334f88bb9cdf78b7f2fd33529469ac352c179e /kernel/trace
parent345ddcc882d8896dcbdcb3e0ee4a415fc23ec8b0 (diff)
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.com Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace_kprobe.c1
-rw-r--r--kernel/trace/trace_probe.c33
-rw-r--r--kernel/trace/trace_probe.h10
3 files changed, 44 insertions, 0 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 5546eec0505f..9aedb0b06683 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -587,6 +587,7 @@ static int create_trace_kprobe(int argc, char **argv)
587 * $retval : fetch return value 587 * $retval : fetch return value
588 * $stack : fetch stack address 588 * $stack : fetch stack address
589 * $stackN : fetch Nth of stack (N:0-) 589 * $stackN : fetch Nth of stack (N:0-)
590 * $comm : fetch current task comm
590 * @ADDR : fetch memory at ADDR (ADDR should be in kernel) 591 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
591 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) 592 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
592 * %REG : fetch register REG 593 * %REG : fetch register REG
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 1d372fa6fefb..74e80a582c28 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -218,6 +218,28 @@ free_bitfield_fetch_param(struct bitfield_fetch_param *data)
218 kfree(data); 218 kfree(data);
219} 219}
220 220
221void FETCH_FUNC_NAME(comm, string)(struct pt_regs *regs,
222 void *data, void *dest)
223{
224 int maxlen = get_rloc_len(*(u32 *)dest);
225 u8 *dst = get_rloc_data(dest);
226 long ret;
227
228 if (!maxlen)
229 return;
230
231 ret = strlcpy(dst, current->comm, maxlen);
232 *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest));
233}
234NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string));
235
236void FETCH_FUNC_NAME(comm, string_size)(struct pt_regs *regs,
237 void *data, void *dest)
238{
239 *(u32 *)dest = strlen(current->comm) + 1;
240}
241NOKPROBE_SYMBOL(FETCH_FUNC_NAME(comm, string_size));
242
221static const struct fetch_type *find_fetch_type(const char *type, 243static const struct fetch_type *find_fetch_type(const char *type,
222 const struct fetch_type *ftbl) 244 const struct fetch_type *ftbl)
223{ 245{
@@ -348,6 +370,11 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
348 } 370 }
349 } else 371 } else
350 ret = -EINVAL; 372 ret = -EINVAL;
373 } else if (strcmp(arg, "comm") == 0) {
374 if (strcmp(t->name, "string") != 0 &&
375 strcmp(t->name, "string_size") != 0)
376 return -EINVAL;
377 f->fn = t->fetch[FETCH_MTD_comm];
351 } else 378 } else
352 ret = -EINVAL; 379 ret = -EINVAL;
353 380
@@ -522,6 +549,12 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
522 arg[t - parg->comm] = '\0'; 549 arg[t - parg->comm] = '\0';
523 t++; 550 t++;
524 } 551 }
552 /*
553 * The default type of $comm should be "string", and it can't be
554 * dereferenced.
555 */
556 if (!t && strcmp(arg, "$comm") == 0)
557 t = "string";
525 parg->type = find_fetch_type(t, ftbl); 558 parg->type = find_fetch_type(t, ftbl);
526 if (!parg->type) { 559 if (!parg->type) {
527 pr_info("Unsupported type: %s\n", t); 560 pr_info("Unsupported type: %s\n", t);
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index f6398db09114..45400ca5ded1 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -102,6 +102,7 @@ enum {
102 FETCH_MTD_reg = 0, 102 FETCH_MTD_reg = 0,
103 FETCH_MTD_stack, 103 FETCH_MTD_stack,
104 FETCH_MTD_retval, 104 FETCH_MTD_retval,
105 FETCH_MTD_comm,
105 FETCH_MTD_memory, 106 FETCH_MTD_memory,
106 FETCH_MTD_symbol, 107 FETCH_MTD_symbol,
107 FETCH_MTD_deref, 108 FETCH_MTD_deref,
@@ -183,6 +184,14 @@ DECLARE_BASIC_FETCH_FUNCS(bitfield);
183#define fetch_bitfield_string NULL 184#define fetch_bitfield_string NULL
184#define fetch_bitfield_string_size NULL 185#define fetch_bitfield_string_size NULL
185 186
187/* comm only makes sense as a string */
188#define fetch_comm_u8 NULL
189#define fetch_comm_u16 NULL
190#define fetch_comm_u32 NULL
191#define fetch_comm_u64 NULL
192DECLARE_FETCH_FUNC(comm, string);
193DECLARE_FETCH_FUNC(comm, string_size);
194
186/* 195/*
187 * Define macro for basic types - we don't need to define s* types, because 196 * Define macro for basic types - we don't need to define s* types, because
188 * we have to care only about bitwidth at recording time. 197 * we have to care only about bitwidth at recording time.
@@ -213,6 +222,7 @@ DEFINE_FETCH_##method(u64)
213ASSIGN_FETCH_FUNC(reg, ftype), \ 222ASSIGN_FETCH_FUNC(reg, ftype), \
214ASSIGN_FETCH_FUNC(stack, ftype), \ 223ASSIGN_FETCH_FUNC(stack, ftype), \
215ASSIGN_FETCH_FUNC(retval, ftype), \ 224ASSIGN_FETCH_FUNC(retval, ftype), \
225ASSIGN_FETCH_FUNC(comm, ftype), \
216ASSIGN_FETCH_FUNC(memory, ftype), \ 226ASSIGN_FETCH_FUNC(memory, ftype), \
217ASSIGN_FETCH_FUNC(symbol, ftype), \ 227ASSIGN_FETCH_FUNC(symbol, ftype), \
218ASSIGN_FETCH_FUNC(deref, ftype), \ 228ASSIGN_FETCH_FUNC(deref, ftype), \