linux trace point机制2--增加trace event
创始人
2025-05-28 03:42:13
0

为fuse模块新增trace event,执行stat命令时,记录trace,输出inode的信息。

一、trace event定义

include\trace\events目录下新增fuse.h文件

/* SPDX-License-Identifier: GPL-2.0 */

#undef TRACE_SYSTEM

/* 在/d/tracing(软链接指向/sys/kernel/debug/tracing)生成fuse目录,对应fuse子系统 */

#define TRACE_SYSTEM fuse

/* _TRACE_FUSE_H尾缀与本头文件名fuse.h对应*/

#if !defined(_TRACE_FUSE_H) || defined(TRACE_HEADER_MULTI_READ)

#define _TRACE_FUSE_H

#include

#include

/* fuse_lookup_pre_inode对应trace event函数名

   即通过trace_fuse_lookup_pre_inode可以调用本trace

*/

TRACE_EVENT(fuse_lookup_pre_inode,

        

        /* TP_PROTO定义trace_fuse_lookup_pre_inode的参数类型

            TP_ARGS定义trace_fuse_lookup_pre_inode的参数名称

         */

        TP_PROTO(struct inode *inode, const unsigned char *name),

        TP_ARGS(inode, name),

        /* TP_STRUCT__entry定义待输出的信息字段 */

        TP_STRUCT__entry(

            __field(const unsigned char *, name)

            __field(ino_t,    ino)

            __field(int, count)

            __field(unsigned int, nlink)

            ),

        /* TP_fast_assign设置entry字段的值 */

        TP_fast_assign(

            __entry->name = name;

            __entry->ino = inode->i_ino;

            __entry->count = atomic_read(&inode->i_count);

            __entry->nlink = inode->i_nlink;

            ),

        /* TP_printk输出entry信息 ,即trace log*/

        TP_printk("inode info:file=%s ino=%llu count=%d nlink=%u",

              __entry->name, __entry->ino, __entry->count, __entry->nlink)

);

#endif /* _TRACE_FUSE_H */

 /* This part must be outside protection */

#include

二、c源文件调用trace函数

首先定义CREATE_TRACE_POINTS及include相关头文件。

然后再源文件中需要trace的地方,调用函数“trace_定义的event名”即可。

#define CREATE_TRACE_POINTS
#include

if (!strncmp(current->comm, "stat", strlen("stat"))) {
    trace_fuse_lookup_pre_inode(entry->d_inode, entry->d_name.name);
}

NOTE:
务必要定义#define CREATE_TRACE_POINTS,并且要在#include 前(多个c文件include该头文件,只需在一个c文件中定义CREATE_TRACE_POINTS,不需要在每个c文件中都定义),否则会出现下面的错误。

CC [M]  kernel/kheaders.o

  GEN     .version

  CHK     include/generated/compile.h

  UPD     include/generated/compile.h

  CC      init/version.o

  AR      init/built-in.o

  AR      built-in.o

  LTO     vmlinux.o

  MODPOST vmlinux.o

ld.lld: error: undefined symbol: __tracepoint_fuse_lookup_pre_inode

>>> referenced by compiler.h:183 (/work/android11/kernel-4.14/include/linux/compiler.h:183)

>>>               vmlinux.o:(fuse_lookup$2d8041ac8bc8b814b20f8728a0064873)

>>> referenced by compiler.h:183 (/work/android11/kernel-4.14/include/linux/compiler.h:183)

>>>               vmlinux.o:(fuse_lookup$2d8041ac8bc8b814b20f8728a0064873)

>>> referenced by compiler.h:183 (/work/android11/kernel-4.14/include/linux/compiler.h:183)

>>>               vmlinux.o:(fuse_lookup$2d8041ac8bc8b814b20f8728a0064873)

>>> referenced by compiler.h:183 (/work/android11/kernel-4.14/include/linux/compiler.h:183)

>>>               vmlinux.o:(fuse_lookup$2d8041ac8bc8b814b20f8728a0064873)

>>> referenced by win_minmax.c

>>>               vmlinux.o:(__ksymtab___tracepoint_fuse_lookup_pre_inode)

三、抓trace log

cp15:/ # cd /d/tracing 或者 cd /sys/kernel/debug/tracing
cp15:/d/tracing # echo fuse:* > set_event
cp15:/d/tracing # echo "" > trace
cp15:/d/tracing # echo 1 > tracing_on
然后执行stat命令查看一个文件属性。
cp15:/d/tracing # echo 0 > tracing_on

adb pull /d/tracing/trace 把trace从手机上pull出来,即可看到增加的trace log。

四、DECLARE_EVENT_CLASS增加多个同类型trace event

上面展示了用TRACE_EVENT增加一个trace event,如果需要在源文件多个地方trace相同的信息,是不是多次调用trace event定义的那个函数就可以了?

答案是不可以。注意看trace输出的log:
stat-5228  [006] ....   191.175084: fuse_lookup_pre_inode: pre inof:file=Camera ino=13666 count=1 nlink=2

log中仅有func name字段即fuse_lookup_pre_inode可以识别出该log是哪里输出的,不同的地方调用trace_fuse_lookup_pre_inode,输出的log都是上面那样的,我们没法识别出该条log对应源码的哪个位置。

内核提供了DECLARE_EVENT_CLASS可以方便地满足我们的需求。
include\trace\events\fuse.h文件改成:

/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
/* 在/d/tracing(软链接指向/sys/kernel/debug/tracing)生成fuse目录,对应fuse子系统 */
#define TRACE_SYSTEM fuse

/* _TRACE_FUSE_H尾缀与本头文件名fuse.h对应*/

#if !defined(_TRACE_FUSE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_FUSE_H

#include
#include

/* 定义了一个名为fuse_inode的模板 */

DECLARE_EVENT_CLASS(fuse_inode,

        /* 模板的参数类型、参数名称 */

        TP_PROTO(struct inode *inode, const unsigned char *name),
        TP_ARGS(inode, name),

         /* TP_STRUCT__entry定义待输出的信息字段 */

        TP_STRUCT__entry(
            __field(const unsigned char *, name)
            __field(ino_t,    ino)
            __field(int, count)
            __field(unsigned int, nlink)
            ),

         /* TP_STRUCT__entry定义待输出的信息字段 */

        TP_fast_assign(
            __entry->name = name;
            __entry->ino = inode->i_ino;
            __entry->count = atomic_read(&inode->i_count);
            __entry->nlink = inode->i_nlink;
            ),

        /* TP_printk输出entry信息,即trace log */

        TP_printk("fuse inode info:file=%s ino=%llu count=%d nlink=%u",
              __entry->name, __entry->ino, __entry->count, __entry->nlink)
);

/* 定义一个trace event,注意宏的名称跟第一节中的TRACE_EVENT名称不同 */

DEFINE_EVENT(fuse_inode, fuse_lookup_pre_inode,

    TP_PROTO(struct inode *inode, const unsigned char *name),

    TP_ARGS(inode, name)
);

/* 另一个trace event */

 DEFINE_EVENT(fuse_inode, fuse_lookup_post_inode,
 
     TP_PROTO(struct inode *inode, const unsigned char *name),
 
     TP_ARGS(inode, name)
 );


#endif /* _TRACE_FUSE_H */

 /* This part must be outside protection */
#include

c源文件示例:

#define CREATE_TRACE_POINTS

#include

if (entry->d_inode) {

        struct kstat stat

         trace_fuse_lookup_pre_inode(entry->d_inode, entry->d_name.name);

        fuse_update_get_attr(entry->d_inode, NULL, &stat, entry->d_name.name);

        trace_fuse_lookup_post_inode(entry->d_inode, entry->d_name.name);

}

相关内容

热门资讯

福建户籍制度改革最新消息 福建... 建将建立人口综合信息库,并实现跨部门、跨地区共享。  据了解,目前,福建正在优化和完善城乡统一的户口...
avue-crud组件的行内编... 前言 关于 avue 框架,其实本来不想写一篇随笔记录的,因为目前在网上...
最新或2023(历届)上海户口...  一、上海户口新政策-改革目的  对于此次改革的目的,方案明确指出“基于国家户籍制度改革的新趋势,以...
[数据分析与可视化] Pyth... 本文主要介绍GeoPandas的基本使用方法,以绘制简单的地图。GeoPandas是一...
案例16-消息队列的作用和意义 目录一:背景介绍二:消息队列概念:目的:解耦...
晋国到底起源于什么地方 不是在... 还不知道:晋国到底起源于什么地方的读者,下面趣历史小编就为大家带来详细介绍,接着往下看吧~山西的许多...
要知道晋国并没有在春秋的版图上... 还不知道:骊姬是怎么上榜四大妖姬之一的读者,下面趣历史小编就为大家带来详细介绍,接着往下看吧~古代四...
作为对手的曹操和刘备都死了 为... 还不知道:孙权为何不能统一三国的读者,下面趣历史小编就为大家带来详细介绍,接着往下看吧~在东汉末年三...
计算机科学导论笔记(十一) 目录 十三、文件结构 13.1 引言 13.1.1 顺序存取 13.1.2 随机存取 13.2 顺...
Linux小黑板(12):Li... "泥土里的蚂蚁哪儿能搞懂,天边的海鸥?"我们翻开任意一本讲操作系统的书籍,...
历史上的周瑜到底是什么样的 他... 今天趣历史小编就给大家带来历史上的周瑜的文章,希望能对大家有所帮助。从小说里了解的人物是很有偏差的,...
蔺相如反对赵括为将,为什么赵孝... 今天趣历史小编为大家带来了一篇关于蔺相如的文章,欢迎阅读哦~长平一战,白起将赵国主力坑杀殆尽,赵国再...
Vite静态资源处理——动态引... 单一资源处理 将资源引入为 URL 服务时引入一个静态资源会返回解析后的公共路径: /...
【CSS】P6 CSS样式方法... 这里写自定义目录标题三种添加样式的方法方法一:行内样式方法二:内部样式方...
宋襄公“蠢猪式&r... 宋国君主的祖先是商纣王的哥哥微子启,子姓,宋氏。周公摄政五年(公元前1039年),周武王册封微子启为...
五胡十六国到底是什么样的 为何... 还不知道:五胡十六国到底是什么样的读者,下面趣历史小编就为大家带来详细介绍,接着往下看吧~所谓“五胡...
宫里人是怎么过中秋节的?有钱任... 同样过中秋,为什么宫里人这么会玩?清朝皇帝:有钱任性,下面趣历史小编就为大家带来详细的介绍,一起来看...
万用表测量电阻时电路板为什么需... 我们在测量PCB板上电阻的阻值时,一般都会把板子断电,然后用万用表测量对...
将军分羊肉忘了车夫,留下一个成... 在日常生活中,老师和长辈经常告诫我们,一定不要小瞧任何一个人。因为人不可貌相,海水不可斗量,没有人会...
明朝为什么要实行募兵制?它有什... 趣历史小编知道读者都很感兴趣明朝中后期为何会实行“募兵制”,这个制度最大的缺点是什么,今天给大家带来...