Chinaunix首页 | 论坛 | 博客
  • 博客访问: 607812
  • 博文数量: 197
  • 博客积分: 7001
  • 博客等级: 大校
  • 技术积分: 2155
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-24 00:29
文章分类

全部博文(197)

文章存档

2022年(1)

2019年(2)

2015年(1)

2012年(100)

2011年(69)

2010年(14)

2007年(3)

2005年(7)

分类: LINUX

2011-03-03 19:17:29

     Tracepoint 的实现很大一部分是依赖于宏来实现的,但是里面曾经出现不少的patch说明正确使用宏的确是不容易的事情。下面是阅读几个patch的体会。

case 1:

以include/trace/events/sched.h 为例:

#undef TRACE_SYSTEM
#define TRACE_SYSTEM sched

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

#include
#include


…....(此处为省略内容)

#endif /* _TRACE_SCHED_H */

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



而在以前,最前面三行
#undef TRACE_SYSTEM
#define TRACE_SYSTEM raw_syscalls
#define TRACE_INCLUDE_FILE syscalls

一般是放在#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)和#endif 里面,为什么移出来呢?见.

未有补丁之前,假设一个C文件先后执行下面三个#include语句:
#include
   -> TRACE_SYSTEM == sched
...
#include
   -> TRACE_SYSTEM == bar
...
#define CREATE_TRACE_POINTS
#include
 -> TRACE_SYSTEM == bar !!!

前面两个#include导致的结果容易理解,而且第一个导致了_TRACE_SCHED_H被定义,所以第三个#include直接会跳过
#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
…....(此处为省略内容)

#endif /* _TRACE_SCHED_H */
部分,也就是TRACE_SYSTEM没有改变。注意TRACE_HEADER_MULTI_READ 是在trace/define_trace.h中定义,现在还未露面,所以上面#if条件为假 。
        由此看出,移出是有必要的。

      附带说明一下,上面的说明同样适用于trace/events/sched.h的最后两行:
/* This part must be outside protection */
#include

试想一下如下的#include系列
#include
…....(此处为省略内容)
#define CREATE_TRACE_POINTS
#include

如果放入#if 保护,则第二次的#include无法激活trace/define_trace.h使得CREATE_TRACE_POINTS派上用场。

下面的patch原因也非常类似。



case 2:第二个patch简单一些,见

       tracepoint 都会用到include/linux/tracepoint.h中TRACE_EVENT宏,而该宏是位于
#ifndef _LINUX_TRACEPOINT_H. 这样的话如下的场景有问题:
#define CREATE_TRACE_POINTS
#include
#include
上述场景是连续定义两个tracepoint, 注意文件的尾部有如下两行保证了连续定义。
/* We may be processing more files */
#define CREATE_TRACE_POINTS

解决的步骤
(1) 将TRACE_EVENT宏 移出#ifndef _LINUX_TRACEPOINT_H 的保护
(2) 不让#include 中产生的TRACE_EVENT定义影响中的TRACE_EVENT定义,即避免re-defined macro 问题。为此要在文件后面加上#undef TRACE_EVENT

case 3:
这个patch更加奇怪,竟然在文件中要#include似乎不相干的文件,下面是patch的内容:
/*
* module.h includes tracepoints, and because ftrace.h
* pulls in module.h:
*  trace/ftrace.h -> linux/ftrace_event.h -> linux/perf_event.h ->
*  linux/ftrace.h -> linux/module.h
* we must include module.h here before we play with any of
* the TRACE_EVENT() macros, otherwise the tracepoints included
* by module.h may break the build.
*/
#include



文件内容如下,可以看到包含了

#ifndef _LINUX_MODULE_H
#define _LINUX_MODULE_H
#include
#include
…....(此处为省略内容)
#endif /* _LINUX_MODULE_H */

从 注释来看,#include 可能导致#include ,从而可能触发#include 中的tracepoint,导致不期望的结果。在define_trace.h首 部#include ,将#define _LINUX_MODULE_H,避免上述情况的发生。这个bug之所以以前没有被发现是因为“We have been lucky so far that this has not broke the build
since module.h is included in almost everything.”

       总体来说,围绕着tracepoint的宏的确复杂,也不容易控制,这也是patch不断出现的原因。

阅读(3404) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~