aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/trace/kprobetrace.txt20
-rw-r--r--kernel/trace/trace_kprobe.c60
2 files changed, 47 insertions, 33 deletions
diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt
index 9b8f7c6040a7..33f531858c56 100644
--- a/Documentation/trace/kprobetrace.txt
+++ b/Documentation/trace/kprobetrace.txt
@@ -36,13 +36,13 @@ Synopsis of kprobe_events
36 36
37 FETCHARGS : Arguments. Each probe can have up to 128 args. 37 FETCHARGS : Arguments. Each probe can have up to 128 args.
38 %REG : Fetch register REG 38 %REG : Fetch register REG
39 sN : Fetch Nth entry of stack (N >= 0)
40 sa : Fetch stack address.
41 @ADDR : Fetch memory at ADDR (ADDR should be in kernel) 39 @ADDR : Fetch memory at ADDR (ADDR should be in kernel)
42 @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol) 40 @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)
43 aN : Fetch function argument. (N >= 0)(*) 41 $sN : Fetch Nth entry of stack (N >= 0)
44 rv : Fetch return value.(**) 42 $sa : Fetch stack address.
45 ra : Fetch return address.(**) 43 $aN : Fetch function argument. (N >= 0)(*)
44 $rv : Fetch return value.(**)
45 $ra : Fetch return address.(**)
46 +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***) 46 +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
47 NAME=FETCHARG: Set NAME as the argument name of FETCHARG. 47 NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
48 48
@@ -85,13 +85,13 @@ Usage examples
85To add a probe as a new event, write a new definition to kprobe_events 85To add a probe as a new event, write a new definition to kprobe_events
86as below. 86as below.
87 87
88 echo p:myprobe do_sys_open dfd=a0 filename=a1 flags=a2 mode=a3 > /sys/kernel/debug/tracing/kprobe_events 88 echo p:myprobe do_sys_open dfd=$a0 filename=$a1 flags=$a2 mode=$a3 > /sys/kernel/debug/tracing/kprobe_events
89 89
90 This sets a kprobe on the top of do_sys_open() function with recording 90 This sets a kprobe on the top of do_sys_open() function with recording
911st to 4th arguments as "myprobe" event. As this example shows, users can 911st to 4th arguments as "myprobe" event. As this example shows, users can
92choose more familiar names for each arguments. 92choose more familiar names for each arguments.
93 93
94 echo r:myretprobe do_sys_open rv ra >> /sys/kernel/debug/tracing/kprobe_events 94 echo r:myretprobe do_sys_open $rv $ra >> /sys/kernel/debug/tracing/kprobe_events
95 95
96 This sets a kretprobe on the return point of do_sys_open() function with 96 This sets a kretprobe on the return point of do_sys_open() function with
97recording return value and return address as "myretprobe" event. 97recording return value and return address as "myretprobe" event.
@@ -138,11 +138,11 @@ events, you need to enable it.
138# TASK-PID CPU# TIMESTAMP FUNCTION 138# TASK-PID CPU# TIMESTAMP FUNCTION
139# | | | | | 139# | | | | |
140 <...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0 140 <...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0
141 <...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) rv=fffffffffffffffe ra=ffffffff81367a3a 141 <...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $rv=fffffffffffffffe $ra=ffffffff81367a3a
142 <...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6 142 <...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6
143 <...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) rv=3 ra=ffffffff81367a3a 143 <...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $rv=3 $ra=ffffffff81367a3a
144 <...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10 144 <...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10
145 <...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) rv=3 ra=ffffffff81367a3a 145 <...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $rv=3 $ra=ffffffff81367a3a
146 146
147 147
148 Each line shows when the kernel hits an event, and <- SYMBOL means kernel 148 Each line shows when the kernel hits an event, and <- SYMBOL means kernel
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 97309d4714f7..f63ead0cc5cf 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -220,24 +220,24 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff)
220 int ret = -EINVAL; 220 int ret = -EINVAL;
221 221
222 if (ff->func == fetch_argument) 222 if (ff->func == fetch_argument)
223 ret = snprintf(buf, n, "a%lu", (unsigned long)ff->data); 223 ret = snprintf(buf, n, "$a%lu", (unsigned long)ff->data);
224 else if (ff->func == fetch_register) { 224 else if (ff->func == fetch_register) {
225 const char *name; 225 const char *name;
226 name = regs_query_register_name((unsigned int)((long)ff->data)); 226 name = regs_query_register_name((unsigned int)((long)ff->data));
227 ret = snprintf(buf, n, "%%%s", name); 227 ret = snprintf(buf, n, "%%%s", name);
228 } else if (ff->func == fetch_stack) 228 } else if (ff->func == fetch_stack)
229 ret = snprintf(buf, n, "s%lu", (unsigned long)ff->data); 229 ret = snprintf(buf, n, "$s%lu", (unsigned long)ff->data);
230 else if (ff->func == fetch_memory) 230 else if (ff->func == fetch_memory)
231 ret = snprintf(buf, n, "@0x%p", ff->data); 231 ret = snprintf(buf, n, "@0x%p", ff->data);
232 else if (ff->func == fetch_symbol) { 232 else if (ff->func == fetch_symbol) {
233 struct symbol_cache *sc = ff->data; 233 struct symbol_cache *sc = ff->data;
234 ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset); 234 ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset);
235 } else if (ff->func == fetch_retvalue) 235 } else if (ff->func == fetch_retvalue)
236 ret = snprintf(buf, n, "rv"); 236 ret = snprintf(buf, n, "$rv");
237 else if (ff->func == fetch_ip) 237 else if (ff->func == fetch_ip)
238 ret = snprintf(buf, n, "ra"); 238 ret = snprintf(buf, n, "$ra");
239 else if (ff->func == fetch_stack_address) 239 else if (ff->func == fetch_stack_address)
240 ret = snprintf(buf, n, "sa"); 240 ret = snprintf(buf, n, "$sa");
241 else if (ff->func == fetch_indirect) { 241 else if (ff->func == fetch_indirect) {
242 struct indirect_fetch_data *id = ff->data; 242 struct indirect_fetch_data *id = ff->data;
243 size_t l = 0; 243 size_t l = 0;
@@ -429,12 +429,10 @@ static int split_symbol_offset(char *symbol, unsigned long *offset)
429#define PARAM_MAX_ARGS 16 429#define PARAM_MAX_ARGS 16
430#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) 430#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
431 431
432static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) 432static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return)
433{ 433{
434 int ret = 0; 434 int ret = 0;
435 unsigned long param; 435 unsigned long param;
436 long offset;
437 char *tmp;
438 436
439 switch (arg[0]) { 437 switch (arg[0]) {
440 case 'a': /* argument */ 438 case 'a': /* argument */
@@ -456,14 +454,6 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
456 } else 454 } else
457 ret = -EINVAL; 455 ret = -EINVAL;
458 break; 456 break;
459 case '%': /* named register */
460 ret = regs_query_register_offset(arg + 1);
461 if (ret >= 0) {
462 ff->func = fetch_register;
463 ff->data = (void *)(unsigned long)ret;
464 ret = 0;
465 }
466 break;
467 case 's': /* stack */ 457 case 's': /* stack */
468 if (arg[1] == 'a') { 458 if (arg[1] == 'a') {
469 ff->func = fetch_stack_address; 459 ff->func = fetch_stack_address;
@@ -478,6 +468,31 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
478 } 468 }
479 } 469 }
480 break; 470 break;
471 default:
472 ret = -EINVAL;
473 }
474 return ret;
475}
476
477static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
478{
479 int ret = 0;
480 unsigned long param;
481 long offset;
482 char *tmp;
483
484 switch (arg[0]) {
485 case '$':
486 ret = parse_probe_vars(arg + 1, ff, is_return);
487 break;
488 case '%': /* named register */
489 ret = regs_query_register_offset(arg + 1);
490 if (ret >= 0) {
491 ff->func = fetch_register;
492 ff->data = (void *)(unsigned long)ret;
493 ret = 0;
494 }
495 break;
481 case '@': /* memory or symbol */ 496 case '@': /* memory or symbol */
482 if (isdigit(arg[1])) { 497 if (isdigit(arg[1])) {
483 ret = strict_strtoul(arg + 1, 0, &param); 498 ret = strict_strtoul(arg + 1, 0, &param);
@@ -489,8 +504,7 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
489 ret = split_symbol_offset(arg + 1, &offset); 504 ret = split_symbol_offset(arg + 1, &offset);
490 if (ret) 505 if (ret)
491 break; 506 break;
492 ff->data = alloc_symbol_cache(arg + 1, 507 ff->data = alloc_symbol_cache(arg + 1, offset);
493 offset);
494 if (ff->data) 508 if (ff->data)
495 ff->func = fetch_symbol; 509 ff->func = fetch_symbol;
496 else 510 else
@@ -544,11 +558,11 @@ static int create_trace_probe(int argc, char **argv)
544 * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] 558 * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS]
545 * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] 559 * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS]
546 * Fetch args: 560 * Fetch args:
547 * aN : fetch Nth of function argument. (N:0-) 561 * $aN : fetch Nth of function argument. (N:0-)
548 * rv : fetch return value 562 * $rv : fetch return value
549 * ra : fetch return address 563 * $ra : fetch return address
550 * sa : fetch stack address 564 * $sa : fetch stack address
551 * sN : fetch Nth of stack (N:0-) 565 * $sN : fetch Nth of stack (N:0-)
552 * @ADDR : fetch memory at ADDR (ADDR should be in kernel) 566 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
553 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) 567 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
554 * %REG : fetch register REG 568 * %REG : fetch register REG