diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-10-07 18:27:40 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-10-12 13:21:35 -0400 |
commit | 405b2651e4bedf8d3932b64cad649b4d26b067f5 (patch) | |
tree | 2d0612b11756a450f31157693fd15858e98d66a2 | |
parent | 88f70d7590538e427c8405a2e02ac2624847386c (diff) |
tracing/kprobes: Add $ prefix to special variables
Add $ prefix to the special variables(e.g. sa, rv) of kprobe-tracer.
This resolves consistency issues between kprobe_events and perf-kprobe.
The main goal is to avoid conflicts between local variable names of
probed functions, used by perf probe, and special variables used
in the kprobe event creation interface (stack values, etc...) and
also available from perf probe.
ie: we don't want rv (return value) to conflict with a local variable
named rv in a probed function.
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Frank Ch. Eigler <fche@redhat.com>
LKML-Reference: <20091007222740.1684.91170.stgit@dhcp-100-2-132.bos.redhat.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
-rw-r--r-- | Documentation/trace/kprobetrace.txt | 20 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 60 |
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 | |||
85 | To add a probe as a new event, write a new definition to kprobe_events | 85 | To add a probe as a new event, write a new definition to kprobe_events |
86 | as below. | 86 | as 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 |
91 | 1st to 4th arguments as "myprobe" event. As this example shows, users can | 91 | 1st to 4th arguments as "myprobe" event. As this example shows, users can |
92 | choose more familiar names for each arguments. | 92 | choose 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 |
97 | recording return value and return address as "myretprobe" event. | 97 | recording 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 | ||
432 | static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) | 432 | static 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 | |||
477 | static 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, ¶m); | 498 | ret = strict_strtoul(arg + 1, 0, ¶m); |
@@ -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 |