diff options
-rw-r--r-- | Documentation/trace/kprobetrace.txt | 22 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 52 |
2 files changed, 35 insertions, 39 deletions
diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt index 4208253b5a53..15415243a9a3 100644 --- a/Documentation/trace/kprobetrace.txt +++ b/Documentation/trace/kprobetrace.txt | |||
@@ -35,13 +35,13 @@ Synopsis of kprobe_events | |||
35 | MEMADDR : Address where the probe is inserted. | 35 | MEMADDR : Address where the probe is inserted. |
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 | @ADDR : Fetch memory at ADDR (ADDR should be in kernel) | 39 | @ADDR : Fetch memory at ADDR (ADDR should be in kernel) |
40 | @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) |
41 | $sN : Fetch Nth entry of stack (N >= 0) | 41 | $stackN : Fetch Nth entry of stack (N >= 0) |
42 | $sa : Fetch stack address. | 42 | $stack : Fetch stack address. |
43 | $aN : Fetch function argument. (N >= 0)(*) | 43 | $argN : Fetch function argument. (N >= 0)(*) |
44 | $rv : Fetch return value.(**) | 44 | $retval : Fetch return value.(**) |
45 | +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***) | 45 | +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***) |
46 | NAME=FETCHARG: Set NAME as the argument name of FETCHARG. | 46 | NAME=FETCHARG: Set NAME as the argument name of FETCHARG. |
47 | 47 | ||
@@ -84,13 +84,13 @@ Usage examples | |||
84 | To add a probe as a new event, write a new definition to kprobe_events | 84 | To add a probe as a new event, write a new definition to kprobe_events |
85 | as below. | 85 | as below. |
86 | 86 | ||
87 | echo p:myprobe do_sys_open dfd=$a0 filename=$a1 flags=$a2 mode=$a3 > /sys/kernel/debug/tracing/kprobe_events | 87 | echo p:myprobe do_sys_open dfd=$arg0 filename=$arg1 flags=$arg2 mode=$arg3 > /sys/kernel/debug/tracing/kprobe_events |
88 | 88 | ||
89 | This sets a kprobe on the top of do_sys_open() function with recording | 89 | This sets a kprobe on the top of do_sys_open() function with recording |
90 | 1st to 4th arguments as "myprobe" event. As this example shows, users can | 90 | 1st to 4th arguments as "myprobe" event. As this example shows, users can |
91 | choose more familiar names for each arguments. | 91 | choose more familiar names for each arguments. |
92 | 92 | ||
93 | echo r:myretprobe do_sys_open $rv >> /sys/kernel/debug/tracing/kprobe_events | 93 | echo r:myretprobe do_sys_open $retval >> /sys/kernel/debug/tracing/kprobe_events |
94 | 94 | ||
95 | This sets a kretprobe on the return point of do_sys_open() function with | 95 | This sets a kretprobe on the return point of do_sys_open() function with |
96 | recording return value as "myretprobe" event. | 96 | recording return value as "myretprobe" event. |
@@ -137,11 +137,11 @@ events, you need to enable it. | |||
137 | # TASK-PID CPU# TIMESTAMP FUNCTION | 137 | # TASK-PID CPU# TIMESTAMP FUNCTION |
138 | # | | | | | | 138 | # | | | | | |
139 | <...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0 | 139 | <...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0 |
140 | <...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $rv=fffffffffffffffe | 140 | <...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $retval=fffffffffffffffe |
141 | <...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6 | 141 | <...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6 |
142 | <...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $rv=3 | 142 | <...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3 |
143 | <...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10 | 143 | <...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10 |
144 | <...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $rv=3 | 144 | <...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3 |
145 | 145 | ||
146 | 146 | ||
147 | Each line shows when the kernel hits an event, and <- SYMBOL means kernel | 147 | 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 ba6d3bd48889..3313fa74ce5f 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -215,22 +215,22 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff) | |||
215 | int ret = -EINVAL; | 215 | int ret = -EINVAL; |
216 | 216 | ||
217 | if (ff->func == fetch_argument) | 217 | if (ff->func == fetch_argument) |
218 | ret = snprintf(buf, n, "$a%lu", (unsigned long)ff->data); | 218 | ret = snprintf(buf, n, "$arg%lu", (unsigned long)ff->data); |
219 | else if (ff->func == fetch_register) { | 219 | else if (ff->func == fetch_register) { |
220 | const char *name; | 220 | const char *name; |
221 | name = regs_query_register_name((unsigned int)((long)ff->data)); | 221 | name = regs_query_register_name((unsigned int)((long)ff->data)); |
222 | ret = snprintf(buf, n, "%%%s", name); | 222 | ret = snprintf(buf, n, "%%%s", name); |
223 | } else if (ff->func == fetch_stack) | 223 | } else if (ff->func == fetch_stack) |
224 | ret = snprintf(buf, n, "$s%lu", (unsigned long)ff->data); | 224 | ret = snprintf(buf, n, "$stack%lu", (unsigned long)ff->data); |
225 | else if (ff->func == fetch_memory) | 225 | else if (ff->func == fetch_memory) |
226 | ret = snprintf(buf, n, "@0x%p", ff->data); | 226 | ret = snprintf(buf, n, "@0x%p", ff->data); |
227 | else if (ff->func == fetch_symbol) { | 227 | else if (ff->func == fetch_symbol) { |
228 | struct symbol_cache *sc = ff->data; | 228 | struct symbol_cache *sc = ff->data; |
229 | ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset); | 229 | ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset); |
230 | } else if (ff->func == fetch_retvalue) | 230 | } else if (ff->func == fetch_retvalue) |
231 | ret = snprintf(buf, n, "$rv"); | 231 | ret = snprintf(buf, n, "$retval"); |
232 | else if (ff->func == fetch_stack_address) | 232 | else if (ff->func == fetch_stack_address) |
233 | ret = snprintf(buf, n, "$sa"); | 233 | ret = snprintf(buf, n, "$stack"); |
234 | else if (ff->func == fetch_indirect) { | 234 | else if (ff->func == fetch_indirect) { |
235 | struct indirect_fetch_data *id = ff->data; | 235 | struct indirect_fetch_data *id = ff->data; |
236 | size_t l = 0; | 236 | size_t l = 0; |
@@ -427,40 +427,36 @@ static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return) | |||
427 | int ret = 0; | 427 | int ret = 0; |
428 | unsigned long param; | 428 | unsigned long param; |
429 | 429 | ||
430 | switch (arg[0]) { | 430 | if (strcmp(arg, "retval") == 0) { |
431 | case 'a': /* argument */ | 431 | if (is_return) { |
432 | ret = strict_strtoul(arg + 1, 10, ¶m); | ||
433 | if (ret || param > PARAM_MAX_ARGS) | ||
434 | ret = -EINVAL; | ||
435 | else { | ||
436 | ff->func = fetch_argument; | ||
437 | ff->data = (void *)param; | ||
438 | } | ||
439 | break; | ||
440 | case 'r': /* retval or retaddr */ | ||
441 | if (is_return && arg[1] == 'v') { | ||
442 | ff->func = fetch_retvalue; | 432 | ff->func = fetch_retvalue; |
443 | ff->data = NULL; | 433 | ff->data = NULL; |
444 | } else | 434 | } else |
445 | ret = -EINVAL; | 435 | ret = -EINVAL; |
446 | break; | 436 | } else if (strncmp(arg, "stack", 5) == 0) { |
447 | case 's': /* stack */ | 437 | if (arg[5] == '\0') { |
448 | if (arg[1] == 'a') { | ||
449 | ff->func = fetch_stack_address; | 438 | ff->func = fetch_stack_address; |
450 | ff->data = NULL; | 439 | ff->data = NULL; |
451 | } else { | 440 | } else if (isdigit(arg[5])) { |
452 | ret = strict_strtoul(arg + 1, 10, ¶m); | 441 | ret = strict_strtoul(arg + 5, 10, ¶m); |
453 | if (ret || param > PARAM_MAX_STACK) | 442 | if (ret || param > PARAM_MAX_STACK) |
454 | ret = -EINVAL; | 443 | ret = -EINVAL; |
455 | else { | 444 | else { |
456 | ff->func = fetch_stack; | 445 | ff->func = fetch_stack; |
457 | ff->data = (void *)param; | 446 | ff->data = (void *)param; |
458 | } | 447 | } |
448 | } else | ||
449 | ret = -EINVAL; | ||
450 | } else if (strncmp(arg, "arg", 3) == 0 && isdigit(arg[3])) { | ||
451 | ret = strict_strtoul(arg + 3, 10, ¶m); | ||
452 | if (ret || param > PARAM_MAX_ARGS) | ||
453 | ret = -EINVAL; | ||
454 | else { | ||
455 | ff->func = fetch_argument; | ||
456 | ff->data = (void *)param; | ||
459 | } | 457 | } |
460 | break; | 458 | } else |
461 | default: | ||
462 | ret = -EINVAL; | 459 | ret = -EINVAL; |
463 | } | ||
464 | return ret; | 460 | return ret; |
465 | } | 461 | } |
466 | 462 | ||
@@ -548,10 +544,10 @@ static int create_trace_probe(int argc, char **argv) | |||
548 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] | 544 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] |
549 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] | 545 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] |
550 | * Fetch args: | 546 | * Fetch args: |
551 | * $aN : fetch Nth of function argument. (N:0-) | 547 | * $argN : fetch Nth of function argument. (N:0-) |
552 | * $rv : fetch return value | 548 | * $retval : fetch return value |
553 | * $sa : fetch stack address | 549 | * $stack : fetch stack address |
554 | * $sN : fetch Nth of stack (N:0-) | 550 | * $stackN : fetch Nth of stack (N:0-) |
555 | * @ADDR : fetch memory at ADDR (ADDR should be in kernel) | 551 | * @ADDR : fetch memory at ADDR (ADDR should be in kernel) |
556 | * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) | 552 | * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) |
557 | * %REG : fetch register REG | 553 | * %REG : fetch register REG |