1. tracepoint原理
tracepoint是预先在函数的插入点中插桩,当执行到函数的插入点,则执行插桩函数,进而触发与插入点预先绑定的probe函数,probe函数可以是一个或者多个,probe函数可以定义为任意的行为,从而可以起到对函数内部观测的作用。目前内核已经不提倡手动创建tracepoint,因此将tracpoint-sample从内核sample代码中删除,取而代之的是trac event,大大简化了tracepoint的使用,但是如果要更好的理解trace event,则也要对tracepoint做一个了解比较好。后面介绍trace event时我们可以在回过头进行比较。
2. 使用tracepoint的步骤
2.1 DECLARE_TRACE
需要在头文件中通过DECLARE_TRACE宏声明,DECLARE_TRACE的关键是定义了register_trace_xxx函数来完成tracepoint与probe的绑定,同时还定义了trace_xxx函数来触发probe的执行,DECLARE_TRACE定义如下:
#define DECLARE_TRACE(name, proto, args) \
__DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \
cpu_online(raw_smp_processor_id()), \
PARAMS(void *__data, proto), \
PARAMS(__data, args))
#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \
extern int __traceiter_##name(data_proto); \
DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
extern struct tracepoint __tracepoint_##name; \
static inline void trace_##name(proto) \
{
\
if (static_key_false(&__tracepoint_##name.key)) \
__DO_TRACE(name, \
TP_PROTO(data_proto), \
TP_ARGS(data_args), \
TP_CONDITION(cond), 0); \
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) {
\
rcu_read_lock_sched_notrace(); \
rcu_dereference_sched(__tracepoint_##name.funcs);\
rcu_read_unlock_sched_notrace(); \
} \
} \
__DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
PARAMS(cond), PARAMS(data_proto), PARAMS(data_args)) \
static inline int \
register_trace_##name(void (*probe)(data_proto), void *data) \
{
\
return tracepoint_probe_register(&__tracepoint_##name, \
(void *)probe, data); \
} \
static inline int

最低0.47元/天 解锁文章
1738





