aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrikar Dronamraju <srikar@linux.vnet.ibm.com>2012-04-11 06:30:43 -0400
committerIngo Molnar <mingo@kernel.org>2012-05-07 08:30:17 -0400
commitf3f096cfedf8113380c56fc855275cc75cd8cf55 (patch)
treeb8d0553afc8cebf6dd320d094206e93df5d95794
parent8ab83f56475ec9151645a888dfe1941f4a92091d (diff)
tracing: Provide trace events interface for uprobes
Implements trace_event support for uprobes. In its current form it can be used to put probes at a specified offset in a file and dump the required registers when the code flow reaches the probed address. The following example shows how to dump the instruction pointer and %ax a register at the probed text address. Here we are trying to probe zfree in /bin/zsh: # cd /sys/kernel/debug/tracing/ # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp 00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh # objdump -T /bin/zsh | grep -w zfree 0000000000446420 g DF .text 0000000000000012 Base zfree # echo 'p /bin/zsh:0x46420 %ip %ax' > uprobe_events # cat uprobe_events p:uprobes/p_zsh_0x46420 /bin/zsh:0x0000000000046420 # echo 1 > events/uprobes/enable # sleep 20 # echo 0 > events/uprobes/enable # cat trace # tracer: nop # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | zsh-24842 [006] 258544.995456: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79 zsh-24842 [007] 258545.000270: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79 zsh-24842 [002] 258545.043929: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79 zsh-24842 [004] 258547.046129: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79 Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com> Cc: Linux-mm <linux-mm@kvack.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Christoph Hellwig <hch@infradead.org> Cc: Arnaldo Carvalho de Melo <acme@infradead.org> Cc: Anton Arapov <anton@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20120411103043.GB29437@linux.vnet.ibm.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--Documentation/trace/uprobetracer.txt95
-rw-r--r--arch/Kconfig2
-rw-r--r--kernel/trace/Kconfig16
-rw-r--r--kernel/trace/Makefile1
-rw-r--r--kernel/trace/trace.h5
-rw-r--r--kernel/trace/trace_kprobe.c2
-rw-r--r--kernel/trace/trace_probe.c14
-rw-r--r--kernel/trace/trace_probe.h3
-rw-r--r--kernel/trace/trace_uprobe.c788
9 files changed, 919 insertions, 7 deletions
diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt
new file mode 100644
index 000000000000..eae40a003eec
--- /dev/null
+++ b/Documentation/trace/uprobetracer.txt
@@ -0,0 +1,95 @@
1 Uprobe-tracer: Uprobe-based Event Tracing
2 =========================================
3 Documentation written by Srikar Dronamraju
4
5Overview
6--------
7Uprobe based trace events are similar to kprobe based trace events.
8To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.
9
10Similar to the kprobe-event tracer, this doesn't need to be activated via
11current_tracer. Instead of that, add probe points via
12/sys/kernel/debug/tracing/uprobe_events, and enable it via
13/sys/kernel/debug/tracing/events/uprobes/<EVENT>/enabled.
14
15However unlike kprobe-event tracer, the uprobe event interface expects the
16user to calculate the offset of the probepoint in the object
17
18Synopsis of uprobe_tracer
19-------------------------
20 p[:[GRP/]EVENT] PATH:SYMBOL[+offs] [FETCHARGS] : Set a probe
21
22 GRP : Group name. If omitted, use "uprobes" for it.
23 EVENT : Event name. If omitted, the event name is generated
24 based on SYMBOL+offs.
25 PATH : path to an executable or a library.
26 SYMBOL[+offs] : Symbol+offset where the probe is inserted.
27
28 FETCHARGS : Arguments. Each probe can have up to 128 args.
29 %REG : Fetch register REG
30
31Event Profiling
32---------------
33 You can check the total number of probe hits and probe miss-hits via
34/sys/kernel/debug/tracing/uprobe_profile.
35 The first column is event name, the second is the number of probe hits,
36the third is the number of probe miss-hits.
37
38Usage examples
39--------------
40To add a probe as a new event, write a new definition to uprobe_events
41as below.
42
43 echo 'p: /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events
44
45 This sets a uprobe at an offset of 0x4245c0 in the executable /bin/bash
46
47 echo > /sys/kernel/debug/tracing/uprobe_events
48
49 This clears all probe points.
50
51The following example shows how to dump the instruction pointer and %ax
52a register at the probed text address. Here we are trying to probe
53function zfree in /bin/zsh
54
55 # cd /sys/kernel/debug/tracing/
56 # cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
57 00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
58 # objdump -T /bin/zsh | grep -w zfree
59 0000000000446420 g DF .text 0000000000000012 Base zfree
60
610x46420 is the offset of zfree in object /bin/zsh that is loaded at
620x00400000. Hence the command to probe would be :
63
64 # echo 'p /bin/zsh:0x46420 %ip %ax' > uprobe_events
65
66Please note: User has to explicitly calculate the offset of the probepoint
67in the object. We can see the events that are registered by looking at the
68uprobe_events file.
69
70 # cat uprobe_events
71 p:uprobes/p_zsh_0x46420 /bin/zsh:0x0000000000046420
72
73Right after definition, each event is disabled by default. For tracing these
74events, you need to enable it by:
75
76 # echo 1 > events/uprobes/enable
77
78Lets disable the event after sleeping for some time.
79 # sleep 20
80 # echo 0 > events/uprobes/enable
81
82And you can see the traced information via /sys/kernel/debug/tracing/trace.
83
84 # cat trace
85 # tracer: nop
86 #
87 # TASK-PID CPU# TIMESTAMP FUNCTION
88 # | | | | |
89 zsh-24842 [006] 258544.995456: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
90 zsh-24842 [007] 258545.000270: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
91 zsh-24842 [002] 258545.043929: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
92 zsh-24842 [004] 258547.046129: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
93
94Each line shows us probes were triggered for a pid 24842 with ip being
950x446421 and contents of ax register being 79.
diff --git a/arch/Kconfig b/arch/Kconfig
index e5d3778d5554..0f8f968015e2 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -78,7 +78,7 @@ config OPTPROBES
78 78
79config UPROBES 79config UPROBES
80 bool "Transparent user-space probes (EXPERIMENTAL)" 80 bool "Transparent user-space probes (EXPERIMENTAL)"
81 depends on ARCH_SUPPORTS_UPROBES && PERF_EVENTS 81 depends on UPROBE_EVENTS && PERF_EVENTS
82 default n 82 default n
83 help 83 help
84 Uprobes is the user-space counterpart to kprobes: they 84 Uprobes is the user-space counterpart to kprobes: they
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index ce5a5c54ac8f..ea4bff6295fc 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -386,6 +386,22 @@ config KPROBE_EVENT
386 This option is also required by perf-probe subcommand of perf tools. 386 This option is also required by perf-probe subcommand of perf tools.
387 If you want to use perf tools, this option is strongly recommended. 387 If you want to use perf tools, this option is strongly recommended.
388 388
389config UPROBE_EVENT
390 bool "Enable uprobes-based dynamic events"
391 depends on ARCH_SUPPORTS_UPROBES
392 depends on MMU
393 select UPROBES
394 select PROBE_EVENTS
395 select TRACING
396 default n
397 help
398 This allows the user to add tracing events on top of userspace
399 dynamic events (similar to tracepoints) on the fly via the trace
400 events interface. Those events can be inserted wherever uprobes
401 can probe, and record various registers.
402 This option is required if you plan to use perf-probe subcommand
403 of perf tools on user space applications.
404
389config PROBE_EVENTS 405config PROBE_EVENTS
390 def_bool n 406 def_bool n
391 407
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index fa10d5ca5ab1..1734c03e048b 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -62,5 +62,6 @@ ifeq ($(CONFIG_TRACING),y)
62obj-$(CONFIG_KGDB_KDB) += trace_kdb.o 62obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
63endif 63endif
64obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o 64obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
65obj-$(CONFIG_UPROBE_EVENT) += trace_uprobe.o
65 66
66libftrace-y := ftrace.o 67libftrace-y := ftrace.o
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 95059f091a24..1bcdbec95a11 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -103,6 +103,11 @@ struct kretprobe_trace_entry_head {
103 unsigned long ret_ip; 103 unsigned long ret_ip;
104}; 104};
105 105
106struct uprobe_trace_entry_head {
107 struct trace_entry ent;
108 unsigned long ip;
109};
110
106/* 111/*
107 * trace_flag_type is an enumeration that holds different 112 * trace_flag_type is an enumeration that holds different
108 * states when a trace occurs. These are: 113 * states when a trace occurs. These are:
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index f8b777367d8e..b31d3d5699fe 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -525,7 +525,7 @@ static int create_trace_probe(int argc, char **argv)
525 525
526 /* Parse fetch argument */ 526 /* Parse fetch argument */
527 ret = traceprobe_parse_probe_arg(arg, &tp->size, &tp->args[i], 527 ret = traceprobe_parse_probe_arg(arg, &tp->size, &tp->args[i],
528 is_return); 528 is_return, true);
529 if (ret) { 529