ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

stap signal && trace point

2021-08-03 20:00:36  阅读:231  来源: 互联网

标签:__ name trace -- signal && was sent uid


执行  ./install/bin/staprun ./sigkill.ko   结果发现脚本执行命令刷屏了!!

debug_bin]$ ./install/bin/staprun  ./sigkill.ko  
sig[17] SIGCHLD was sent to sh (pid:15237) by exec:ps -->:15239  uid:0
sig[17] SIGCHLD was sent to python (pid:12444) by exec:sh -->:15237  uid:0
sig[34] 0x22 was sent to wafd (pid:11041) by exec:swapper/0 -->:0  uid:0
sig[17] SIGCHLD was sent to sh (pid:15242) by exec:bp_tool -->:15243  uid:0
sig[17] SIGCHLD was sent to sh (pid:15242) by exec:awk -->:15244  uid:0
sig[17] SIGCHLD was sent to sh (pid:15240) by exec:ps -->:15241  uid:0
sig[17] SIGCHLD was sent to plat_srv (pid:3990) by exec:sh -->:15242  uid:0
sig[17] SIGCHLD was sent to python (pid:12444) by exec:sh -->:15240  uid:0
sig[17] SIGCHLD was sent to sh (pid:15245) by exec:bp_tool -->:15246  uid:0
sig[17] SIGCHLD was sent to sh (pid:15245) by exec:awk -->:15247  uid:0
sig[17] SIGCHLD was sent to plat_srv (pid:3990) by exec:sh -->:15245  uid:0
sig[17] SIGCHLD was sent to sh (pid:15248) by exec:bp_tool -->:15249  uid:0
sig[17] SIGCHLD was sent to sh (pid:15248) by exec:awk -->:15250  uid:0
sig[17] SIGCHLD was sent to plat_srv (pid:3990) by exec:sh -->:15248  uid:0
sig[17] SIGCHLD was sent to sh (pid:15251) by exec:ps -->:15252  uid:0
sig[17] SIGCHLD was sent to python (pid:12444) by exec:sh -->:15251  uid:0
sig[17] SIGCHLD was sent to sh (pid:15166) by exec:awk -->:15168  uid:0
sig[17] SIGCHLD was sent to sh (pid:15166) by exec:top -->:15167  uid:0
sig[17] SIGCHLD was sent to python (pid:7298) by exec:sh -->:15166  uid:0
sig[17] SIGCHLD was sent to sh (pid:15253) by exec:ps -->:15254  uid:0
sig[17] SIGCHLD was sent to sh (pid:15253) by exec:grep -->:15255  uid:0
sig[17] SIGCHLD was sent to sh (pid:15253) by exec:grep -->:15257  uid:0
sig[17] SIGCHLD was sent to sh (pid:15253) by exec:grep -->:15256  uid:0
sig[17] SIGCHLD was sent to python (pid:8626) by exec:sh -->:15253  uid:0
sig[17] SIGCHLD was sent to sh (pid:15258) by exec:cat -->:15264  uid:0
sig[17] SIGCHLD was sent to sh (pid:15258) by exec:head -->:15265  uid:0
sig[17] SIGCHLD was sent to sh (pid:15258) by exec:awk -->:15266  uid:0
sig[17] SIGCHLD was sent to python (pid:7298) by exec:sh -->:15258  uid:0
sig[17] SIGCHLD was sent to sh (pid:15259) by exec:ps -->:15260  uid:0
----------------------
sig[17] SIGCHLD was sent to python (pid:8626) by exec:sh -->:15278 uid:0

sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15283 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15284 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15285 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15286 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15287 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15288 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15291 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15289 uid:0
sig[17] SIGCHLD was sent to python (pid:6750) by exec:ethtool -->:15294 uid:0

 

想不通 为啥 要通过命令来获取信息, netlink 不香么!!

 

顺便看下 trace_event的实现,以kfree_skb为例

TRACE_EVENT(kfree_skb,

    TP_PROTO(struct sk_buff *skb, void *location),

    TP_ARGS(skb, location),

    TP_STRUCT__entry(
        __field(    void *,        skbaddr        )
        __field(    void *,        location    )
        __field(    unsigned short,    protocol    )
    ),

    TP_fast_assign(
        __entry->skbaddr = skb;
        __entry->location = location;
        __entry->protocol = ntohs(skb->protocol);
    ),

    TP_printk("skbaddr=%p protocol=%u location=%p",
        __entry->skbaddr, __entry->protocol, __entry->location)
);

其大概意思是 将当前地址堆栈存在location 变量中;最后输出!!

 来看下 trace_event的第一层展开:

#define TRACE_EVENT(name, proto, args, struct, assign, print)    \
    DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \
    DECLARE_EVENT_CLASS(name,                   \
                 PARAMS(proto),               \
                 PARAMS(args),               \
                 PARAMS(tstruct),               \
                 PARAMS(assign),               \
                 PARAMS(print));               \
    DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));

 

 根据tracepoint.h文件 主要函数为:DEFINE_EVENT 宏定义

#define DEFINE_EVENT(template, name, proto, args)        \
    DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))

#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 struct tracepoint __tracepoint_##name;            \// tracepoint变量“__tracepoint_##name”本身
    static inline void trace_##name(proto)                \// tracepoint桩函数“trace_##name”的定义
    {                                \
        if (static_key_false(&__tracepoint_##name.key))        \
            __DO_TRACE(&__tracepoint_##name,        \
                TP_PROTO(data_proto),            \
                TP_ARGS(data_args),            \
                TP_CONDITION(cond),,);            \
        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                        \// tracepoint的回调函数注册函数"register_trace_##name"
    register_trace_##name(void (*probe)(data_proto), void *data)    \
    {                                \
        return tracepoint_probe_register(&__tracepoint_##name,    \
                        (void *)probe, data);    \
    }                                \
    static inline int                        \
    register_trace_prio_##name(void (*probe)(data_proto), void *data,\
                   int prio)                \
    {                                \
        return tracepoint_probe_register_prio(&__tracepoint_##name, \
                          (void *)probe, data, prio); \
    }                                \
    static inline int                        \// tracepoint的回调函数反注册函数"unregister_trace_##name"
    unregister_trace_##name(void (*probe)(data_proto), void *data)    \
    {                                \
        return tracepoint_probe_unregister(&__tracepoint_##name,\
                        (void *)probe, data);    \
    }                                \
    static inline void                        \
    check_trace_callback_type_##name(void (*cb)(data_proto))    \
    {                                \
    }                                \
    static inline bool                        \
    trace_##name##_enabled(void)                    \
    {                                \
        return static_key_false(&__tracepoint_##name.key);    \
    }
//桩函数中,逐个调用回调函数进行执行
#define __DO_TRACE(tp, proto, args, cond, prercu, postrcu)        \
    do {                                \
        struct tracepoint_func *it_func_ptr;            \
        void *it_func;                        \
        void *__data;                        \
                                    \
        if (!(cond))                        \
            return;                        \
        prercu;                            \
        rcu_read_lock_sched_notrace();                \
        it_func_ptr = rcu_dereference_sched((tp)->funcs);    \
        if (it_func_ptr) {                    \
            do {                        \
                it_func = (it_func_ptr)->func;        \
                __data = (it_func_ptr)->data;        \
                ((void(*)(proto))(it_func))(args);    \
            } while ((++it_func_ptr)->func);        \
        }                            \
        rcu_read_unlock_sched_notrace();            \
        postrcu;                        \
    } whil

 

TRACE_EVENT包含5个参数:(name, proto, args, struct, assign, print)
  前面两个参数:proto, args,是给定义tracepoint使用的。在linux/tracepoint.h中构造tracepoint桩函数、callback regitser/unregister函数,在trace/define_trace.h中定义tracepoint变量。
  后面三个参数:struct, assign, print,是给trace_event使用的。在trace/trace_events.h,构造trace_event的callback函数,注册到tracepoint。

TRACE_EVENT:

  • 创建了一个tracepoint,可以放到kernel代码中;
  • 创建了一个回调函数,可以被上述tracepoint调用
  • 回调函数必须实现以最快的方式将传递给它的数据记录到trace ringbuffer中。
  • 必须创建一个函数能解析从ringbuffer读出的数据,转换成便于用户理解的形式。

在define_trace.h中,宏TRACE_EVENT()第二次的展开:

#undef TRACE_EVENT
#define TRACE_EVENT(name, proto, args, tstruct, assign, print)    \
    DEFINE_TRACE(name)

//重新宏定义展开


#define DEFINE_TRACE(name)                        \
    DEFINE_TRACE_FN(name, NULL, NULL);


/*
 * We have no guarantee that gcc and the linker won't up-align the tracepoint
 * structures, so we create an array of pointers that will be used for iteration
 * on the tracepoints.
 */
#define DEFINE_TRACE_FN(name, reg, unreg)                 \
    static const char __tpstrtab_##name[]                 \
    __attribute__((section("__tracepoints_strings"))) = #name;     \// 定义tracepoint变量“__tracepoint_##name”本身
    struct tracepoint __tracepoint_##name                 \
    __attribute__((section("__tracepoints"))) =             \
        { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\// 将tracepoint变量指针"__tracepoint_ptr_##name"存放到section("__tracepoints_ptrs")
    static struct tracepoint * const __tracepoint_ptr_##name __used     \
    __attribute__((section("__tracepoints_ptrs"))) =         \
        &__tracepoint_##name;

   在随后的trace_events.h中,宏TRACE_EVENT()又进行了多次的展开。宏定义重复多次定义多次展开

太恶心了 !! 以为很简单 结果一个宏定义都这复杂

 

tracepoint.h  trace_events.h  define_trace.h

 

这几个文件看的有点蒙蔽

下次要是需要写trace_point 在继续研究!! 继续打游戏

参考:Using the TRACE_EVENT() part1

trace point example

标签:__,name,trace,--,signal,&&,was,sent,uid
来源: https://www.cnblogs.com/codestack/p/15095828.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有