mj-trace 代码分析

mj-trace 代码分析-(1)


编写的 trace模块 mj请参考文档《Linux内核增加一个trace.md》,接下来开始分析一下代码。

内核有自带的sample,在路径samples/trace_events/下,代码相对来说比较长,可以使用下面命令进行编译以及生成预处理文件:

make ARCH=arm64 CROSS_COMPILE=aarch64-himix100-linux- M=samples/trace_events/  CONFIG_SAMPLES=m CONFIG_SAMPLE_TRACE_EVENTS=m
make ARCH=arm64 CROSS_COMPILE=aarch64-himix100-linux- CONFIG_SAMPLES=m CONFIG_SAMPLE_TRACE_EVENTS=m samples/trace_events/trace-events-sample.i   

中间产物分析

首先看一下编译的中间产物,开启FTRACE相关选项后,内核根据Makefiiledebug.ctrace.c编译进去,所以编译产物多了debug.otrace.o以及相关的.o.cmd文件。

在这里插入图片描述

共同的产物中,.mj.o.cmd文件的差异在于增加的编译选项-pg,内核Documentation/trace/ftrace.txt中有关于这个培训选项的描述:

在这里插入图片描述

查看一下gcc手册关于这个选项的描述:

生成额外的代码来编写适合分析程序prof(用于-p)或gprof(用于-pg)的配置文件信息。在编译需要数据的源文件时必须使用此选项,在链接时也必须使用此选项。

在使用这些选项进行编译时,可以使用函数属性no_instrument_function来禁止对单个函数进行分析。

在这里插入图片描述

trace.[c/h/i]分析

trace.c里面是关于事件类和事件的定义,内容也比较简单,就是定义CREATE_TRACE_POINTS宏并包含trace.h

在这里插入图片描述

看一下trace.h的内容:

在这里插入图片描述

看一下DECLARE_EVENT_CLASS宏,这个宏共有9处地方进行了定义,一开始的时候我在想到底是在用哪一处地方的定义,但是看了好几遍这几处的定义,发现并没有宏来决定使用哪一个。

在这里插入图片描述

后来我灵机一动,反汇编之后,搜索mj_log_msg变量,再根据代码,可以得到下面的图:

在这里插入图片描述

可以看到起始是所有的宏都用到了,有一些宏内联了导致汇编之后找不到。

trace.i 分析

在网上找到一条预编译处理命令:

make ARCH=arm64 CROSS_COMPILE=aarch64-himix100-linux- drivers/mj/trace.i

预编译之后查看trace.i的内容,里面内容实在是太长了,提取相关信息。(相信我,你不会想看里面的内容的,按照上面的代码,原始的trace.i一共三万多行,删除空行以及包含头文件的语句之后,还有两万多行)

结构体:

  • struct trace_event_raw_mj_log_msg
  • struct trace_event_data_offsets_mj_log_msg

变量:

  • __tpstrtab_mj_core : static const char [] __attribute__((section("__tracepoints_strings")))
  • __tracepoint_mj_core : struct tracepoint __attribute__((section("__tracepoints")))
  • __tracepoint_ptr_mj_core : static struct tracepoint * const __attribute__((used)) __attribute__((section("__tracepoints_ptrs")))
  • str__mj__trace_system_name : static const char []
  • event_mj_core : static struct trace_event_call __attribute__((used)) __attribute__((aligned(4)))
  • trace_event_type_funcs_mj_log_msg : static struct trace_event_functions
  • print_fmt_mj_log_msg : static char []
  • event_class_mj_log_msg : static struct trace_event_class __attribute__((used)) __attribute__ ((section(".ref.data")))
  • __event_mj_core : static struct trace_event_call __attribute__((used)) __attribute__((section("_ftrace_events"))) *

函数:

  • trace_raw_output_mj_log_msg()
  • trace_event_define_fields_mj_log_msg()
  • trace_event_get_offsets_mj_log_msg()
  • trace_event_raw_event_mj_log_msg()
  • ftrace_test_probe_mj_core()
  • perf_trace_mj_log_msg()
  • perf_trace_mj_log_msg()
  • perf_test_probe_mj_core()

大概内容图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zpfj9nDq-1615003699527)(pics/mj/trace-macro.png)]

定义的结构体

structtrace_event_raw_mj_log_msg如下图所示:

在这里插入图片描述

struct trace_event_data_offsets_mj_log_msg如下图所示:

在这里插入图片描述

这两个结构体都是函数内部使用的,暂时就不管了。

定义的变量

__tpstrtab_mj_core如下图所示:

在这里插入图片描述

__tracepoint_mj_core如下图所示:定义一个追踪点。

在这里插入图片描述

__tracepoint_ptr_mj_core如下图所示:追踪点的常量指针。

在这里插入图片描述

str__mj__trace_system_name如下图所示:

在这里插入图片描述

trace_event_type_funcs_mj_log_msg如下图所示:定义追踪事件函数。

在这里插入图片描述

print_fmt_mj_log_msg如下图所示:

在这里插入图片描述

event_class_mj_log_msg如下图所示:定义事件追踪类。

在这里插入图片描述

event_mj_core如下图所示:定义一个追踪事件。

在这里插入图片描述

__event_mj_core如下图所示:追踪事件的指针。

在这里插入图片描述

定义的函数

trace_raw_output_mj_log_msg()如下图所示:

在这里插入图片描述

trace_event_define_fields_mj_log_msg()如下图所示:

在这里插入图片描述

trace_event_get_offsets_mj_log_msg()如下图所示:

在这里插入图片描述

trace_event_raw_event_mj_log_msg()如下图所示:

在这里插入图片描述

ftrace_test_probe_mj_core()如下图所示:

在这里插入图片描述

perf_trace_mj_log_msg()如下图所示:

在这里插入图片描述

在这里插入图片描述

perf_test_probe_mj_core()如下图所示:

在这里插入图片描述

注意到上面的函数,都有__attribute__((no_instrument_funcion))这个属性,查看gcc手册关于这个属性的描述:

在这里插入图片描述

如果给出了finstrument-functions-p-pg中的任何一个,则在大多数用户编译函数的入口和出口处都会生成概要分析函数调用。 具有此属性的功能不会生成相应的分析函数调用。

因为编译时已经带了-pg选项,如果这些函数再生成分析调用函数,是会造成死循环?

变量与函数之间的关联

回头查看trace.h的定义,会发现是以event_class_mj_log_msg变量为中心,然后将结构体变量的成员初始化为某些函数指针:
在这里插入图片描述

再看event_mj_core与其他函数或结构体的联系:

在这里插入图片描述

啊,这有空再分析吧,头秃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值