aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_kprobe.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2009-10-07 18:27:40 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-10-12 13:21:35 -0400
commit405b2651e4bedf8d3932b64cad649b4d26b067f5 (patch)
tree2d0612b11756a450f31157693fd15858e98d66a2 /kernel/trace/trace_kprobe.c
parent88f70d7590538e427c8405a2e02ac2624847386c (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>
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r--kernel/trace/trace_kprobe.c60
1 files changed, 37 insertions, 23 deletions
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