Skip to content

Commit 413d37d

Browse files
Masami Hiramatsufweisbec
authored andcommitted
tracing: Add kprobe-based event tracer
Add kprobes-based event tracer on ftrace. This tracer is similar to the events tracer which is based on Tracepoint infrastructure. Instead of Tracepoint, this tracer is based on kprobes (kprobe and kretprobe). It probes anywhere where kprobes can probe(this means, all functions body except for __kprobes functions). Similar to the events tracer, this tracer doesn't need to be activated via current_tracer, instead of that, just set probe points via /sys/kernel/debug/tracing/kprobe_events. And you can set filters on each probe events via /sys/kernel/debug/tracing/events/kprobes/<EVENT>/filter. This tracer supports following probe arguments for each probe. %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. +|-offs(FETCHARG) : fetch memory at FETCHARG +|- offs address. See Documentation/trace/kprobetrace.txt in the next patch for details. Changes from v13: - Support 'sa' for stack address. - Use call->data instead of container_of() macro. [[email protected]: Fixed conflict against latest tracing/core] Signed-off-by: Masami Hiramatsu <[email protected]> Acked-by: Ananth N Mavinakayanahalli <[email protected]> Cc: Avi Kivity <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Frank Ch. Eigler <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jason Baron <[email protected]> Cc: Jim Keniston <[email protected]> Cc: K.Prasad <[email protected]> Cc: Lai Jiangshan <[email protected]> Cc: Li Zefan <[email protected]> Cc: Przemysław Pawełczyk <[email protected]> Cc: Roland McGrath <[email protected]> Cc: Sam Ravnborg <[email protected]> Cc: Srikar Dronamraju <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Tom Zanussi <[email protected]> Cc: Vegard Nossum <[email protected]> LKML-Reference: <[email protected]> Signed-off-by: Frederic Weisbecker <[email protected]>
1 parent d93f12f commit 413d37d

File tree

5 files changed

+1263
-0
lines changed

5 files changed

+1263
-0
lines changed

kernel/trace/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,18 @@ config BLK_DEV_IO_TRACE
411411

412412
If unsure, say N.
413413

414+
config KPROBE_TRACER
415+
depends on KPROBES
416+
depends on X86
417+
bool "Trace kprobes"
418+
select TRACING
419+
select GENERIC_TRACER
420+
help
421+
This tracer probes everywhere where kprobes can probe it, and
422+
records various registers and memories specified by user.
423+
This also allows you to trace kprobe probe points as a dynamic
424+
defined events. It provides per-probe event filtering interface.
425+
414426
config DYNAMIC_FTRACE
415427
bool "enable/disable ftrace tracepoints dynamically"
416428
depends on FUNCTION_TRACER

kernel/trace/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,6 @@ obj-$(CONFIG_EVENT_TRACING) += trace_export.o
5454
obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
5555
obj-$(CONFIG_EVENT_PROFILE) += trace_event_profile.o
5656
obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
57+
obj-$(CONFIG_KPROBE_TRACER) += trace_kprobe.o
5758

5859
libftrace-y := ftrace.o

kernel/trace/trace.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ enum trace_type {
3838
TRACE_KMEM_FREE,
3939
TRACE_POWER,
4040
TRACE_BLK,
41+
TRACE_KPROBE,
42+
TRACE_KRETPROBE,
4143

4244
__TRACE_LAST_TYPE,
4345
};
@@ -205,6 +207,30 @@ struct syscall_trace_exit {
205207
unsigned long ret;
206208
};
207209

210+
struct kprobe_trace_entry {
211+
struct trace_entry ent;
212+
unsigned long ip;
213+
int nargs;
214+
unsigned long args[];
215+
};
216+
217+
#define SIZEOF_KPROBE_TRACE_ENTRY(n) \
218+
(offsetof(struct kprobe_trace_entry, args) + \
219+
(sizeof(unsigned long) * (n)))
220+
221+
struct kretprobe_trace_entry {
222+
struct trace_entry ent;
223+
unsigned long func;
224+
unsigned long ret_ip;
225+
int nargs;
226+
unsigned long args[];
227+
};
228+
229+
#define SIZEOF_KRETPROBE_TRACE_ENTRY(n) \
230+
(offsetof(struct kretprobe_trace_entry, args) + \
231+
(sizeof(unsigned long) * (n)))
232+
233+
208234

209235
/*
210236
* trace_flag_type is an enumeration that holds different
@@ -317,6 +343,10 @@ extern void __ftrace_bad_type(void);
317343
TRACE_KMEM_ALLOC); \
318344
IF_ASSIGN(var, ent, struct kmemtrace_free_entry, \
319345
TRACE_KMEM_FREE); \
346+
IF_ASSIGN(var, ent, struct kprobe_trace_entry, \
347+
TRACE_KPROBE); \
348+
IF_ASSIGN(var, ent, struct kretprobe_trace_entry, \
349+
TRACE_KRETPROBE); \
320350
__ftrace_bad_type(); \
321351
} while (0)
322352

kernel/trace/trace_event_types.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,22 @@ TRACE_EVENT_FORMAT(kmem_free, TRACE_KMEM_FREE, kmemtrace_free_entry, ignore,
175175
TP_RAW_FMT("type:%u call_site:%lx ptr:%p")
176176
);
177177

178+
TRACE_EVENT_FORMAT(kprobe, TRACE_KPROBE, kprobe_trace_entry, ignore,
179+
TRACE_STRUCT(
180+
TRACE_FIELD(unsigned long, ip, ip)
181+
TRACE_FIELD(int, nargs, nargs)
182+
TRACE_FIELD_ZERO(unsigned long, args)
183+
),
184+
TP_RAW_FMT("%08lx: args:0x%lx ...")
185+
);
186+
187+
TRACE_EVENT_FORMAT(kretprobe, TRACE_KRETPROBE, kretprobe_trace_entry, ignore,
188+
TRACE_STRUCT(
189+
TRACE_FIELD(unsigned long, func, func)
190+
TRACE_FIELD(unsigned long, ret_ip, ret_ip)
191+
TRACE_FIELD(int, nargs, nargs)
192+
TRACE_FIELD_ZERO(unsigned long, args)
193+
),
194+
TP_RAW_FMT("%08lx <- %08lx: args:0x%lx ...")
195+
);
178196
#undef TRACE_SYSTEM

0 commit comments

Comments
 (0)