Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 169435
b: refs/heads/master
c: 405b265
h: refs/heads/master
i:
  169433: f55e692
  169431: a6e3f32
v: v3
  • Loading branch information
Masami Hiramatsu authored and Frederic Weisbecker committed Oct 12, 2009
1 parent 73dd459 commit fcb172e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 34 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 88f70d7590538e427c8405a2e02ac2624847386c
refs/heads/master: 405b2651e4bedf8d3932b64cad649b4d26b067f5
20 changes: 10 additions & 10 deletions trunk/Documentation/trace/kprobetrace.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ Synopsis of kprobe_events

FETCHARGS : Arguments. Each probe can have up to 128 args.
%REG : Fetch register REG
sN : Fetch Nth entry of stack (N >= 0)
sa : Fetch stack address.
@ADDR : Fetch memory at ADDR (ADDR should be in kernel)
@SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)
aN : Fetch function argument. (N >= 0)(*)
rv : Fetch return value.(**)
ra : Fetch return address.(**)
$sN : Fetch Nth entry of stack (N >= 0)
$sa : Fetch stack address.
$aN : Fetch function argument. (N >= 0)(*)
$rv : Fetch return value.(**)
$ra : Fetch return address.(**)
+|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
NAME=FETCHARG: Set NAME as the argument name of FETCHARG.

Expand Down Expand Up @@ -85,13 +85,13 @@ Usage examples
To add a probe as a new event, write a new definition to kprobe_events
as below.

echo p:myprobe do_sys_open dfd=a0 filename=a1 flags=a2 mode=a3 > /sys/kernel/debug/tracing/kprobe_events
echo p:myprobe do_sys_open dfd=$a0 filename=$a1 flags=$a2 mode=$a3 > /sys/kernel/debug/tracing/kprobe_events

This sets a kprobe on the top of do_sys_open() function with recording
1st to 4th arguments as "myprobe" event. As this example shows, users can
choose more familiar names for each arguments.

echo r:myretprobe do_sys_open rv ra >> /sys/kernel/debug/tracing/kprobe_events
echo r:myretprobe do_sys_open $rv $ra >> /sys/kernel/debug/tracing/kprobe_events

This sets a kretprobe on the return point of do_sys_open() function with
recording return value and return address as "myretprobe" event.
Expand Down Expand Up @@ -138,11 +138,11 @@ events, you need to enable it.
# TASK-PID CPU# TIMESTAMP FUNCTION
# | | | | |
<...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0
<...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) rv=fffffffffffffffe ra=ffffffff81367a3a
<...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $rv=fffffffffffffffe $ra=ffffffff81367a3a
<...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6
<...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) rv=3 ra=ffffffff81367a3a
<...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $rv=3 $ra=ffffffff81367a3a
<...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10
<...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) rv=3 ra=ffffffff81367a3a
<...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $rv=3 $ra=ffffffff81367a3a


Each line shows when the kernel hits an event, and <- SYMBOL means kernel
Expand Down
60 changes: 37 additions & 23 deletions trunk/kernel/trace/trace_kprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,24 +220,24 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff)
int ret = -EINVAL;

if (ff->func == fetch_argument)
ret = snprintf(buf, n, "a%lu", (unsigned long)ff->data);
ret = snprintf(buf, n, "$a%lu", (unsigned long)ff->data);
else if (ff->func == fetch_register) {
const char *name;
name = regs_query_register_name((unsigned int)((long)ff->data));
ret = snprintf(buf, n, "%%%s", name);
} else if (ff->func == fetch_stack)
ret = snprintf(buf, n, "s%lu", (unsigned long)ff->data);
ret = snprintf(buf, n, "$s%lu", (unsigned long)ff->data);
else if (ff->func == fetch_memory)
ret = snprintf(buf, n, "@0x%p", ff->data);
else if (ff->func == fetch_symbol) {
struct symbol_cache *sc = ff->data;
ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset);
} else if (ff->func == fetch_retvalue)
ret = snprintf(buf, n, "rv");
ret = snprintf(buf, n, "$rv");
else if (ff->func == fetch_ip)
ret = snprintf(buf, n, "ra");
ret = snprintf(buf, n, "$ra");
else if (ff->func == fetch_stack_address)
ret = snprintf(buf, n, "sa");
ret = snprintf(buf, n, "$sa");
else if (ff->func == fetch_indirect) {
struct indirect_fetch_data *id = ff->data;
size_t l = 0;
Expand Down Expand Up @@ -429,12 +429,10 @@ static int split_symbol_offset(char *symbol, unsigned long *offset)
#define PARAM_MAX_ARGS 16
#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))

static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return)
{
int ret = 0;
unsigned long param;
long offset;
char *tmp;

switch (arg[0]) {
case 'a': /* argument */
Expand All @@ -456,14 +454,6 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
} else
ret = -EINVAL;
break;
case '%': /* named register */
ret = regs_query_register_offset(arg + 1);
if (ret >= 0) {
ff->func = fetch_register;
ff->data = (void *)(unsigned long)ret;
ret = 0;
}
break;
case 's': /* stack */
if (arg[1] == 'a') {
ff->func = fetch_stack_address;
Expand All @@ -478,6 +468,31 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
}
}
break;
default:
ret = -EINVAL;
}
return ret;
}

static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
{
int ret = 0;
unsigned long param;
long offset;
char *tmp;

switch (arg[0]) {
case '$':
ret = parse_probe_vars(arg + 1, ff, is_return);
break;
case '%': /* named register */
ret = regs_query_register_offset(arg + 1);
if (ret >= 0) {
ff->func = fetch_register;
ff->data = (void *)(unsigned long)ret;
ret = 0;
}
break;
case '@': /* memory or symbol */
if (isdigit(arg[1])) {
ret = strict_strtoul(arg + 1, 0, &param);
Expand All @@ -489,8 +504,7 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return)
ret = split_symbol_offset(arg + 1, &offset);
if (ret)
break;
ff->data = alloc_symbol_cache(arg + 1,
offset);
ff->data = alloc_symbol_cache(arg + 1, offset);
if (ff->data)
ff->func = fetch_symbol;
else
Expand Down Expand Up @@ -544,11 +558,11 @@ static int create_trace_probe(int argc, char **argv)
* - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS]
* - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS]
* Fetch args:
* aN : fetch Nth of function argument. (N:0-)
* rv : fetch return value
* ra : fetch return address
* sa : fetch stack address
* sN : fetch Nth of stack (N:0-)
* $aN : fetch Nth of function argument. (N:0-)
* $rv : fetch return value
* $ra : fetch return address
* $sa : fetch stack address
* $sN : fetch Nth of stack (N:0-)
* @ADDR : fetch memory at ADDR (ADDR should be in kernel)
* @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
* %REG : fetch register REG
Expand Down

0 comments on commit fcb172e

Please sign in to comment.