免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3197 | 回复: 2
打印 上一主题 下一主题

罪恶的宏-以tracepoint为例(2.6.38-rc5) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-03 19:22 |只看该作者 |倒序浏览
http://blog.chinaunix.net/space. ... =blog&id=152226


     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 <linux/sched.h>
#include <linux/tracepoint.h>


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

#endif /* _TRACE_SCHED_H */

/* This part must be outside protection */
#include <trace/define_trace.h>



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

一般是放在#if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)和#endif 里面,为什么移出来呢?见tracing/events: Move TRACE_SYSTEM outside of include guard.

未有补丁之前,假设一个C文件先后执行下面三个#include语句:
#include <trace/events/sched.h>
   -> TRACE_SYSTEM == sched
...
#include <trace/events/bar.h>
   -> TRACE_SYSTEM == bar
...
#define CREATE_TRACE_POINTS
#include <trace/events/sched.h>
-> 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 <trace/define_trace.h>

试想一下如下的#include系列
#include <trace/events/sched.h>
…....(此处为省略内容)
#define CREATE_TRACE_POINTS
#include <trace/events/sched.h>

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

下面的patch原因也非常类似。
tracing: Fix tracepoint.h DECLARE_TRACE() to allow more than one header


case 2:第二个patch简单一些,见tracing/events: fix the include file dependencies

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

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

case 3: tracing: Include module.h in define_trace.h
这个patch更加奇怪,竟然在<trace/define_trace.h>文件中要#include似乎不相干的文件<linux/module.h>,下面是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 <linux/module.h>



文件<linux/module.h>内容如下,可以看到包含了<trace/events/module.h>。

#ifndef _LINUX_MODULE_H
#define _LINUX_MODULE_H
#include <linux/tracepoint.h>
#include <trace/events/module.h>
…....(此处为省略内容)
#endif /* _LINUX_MODULE_H */

从注释来看,#include <trace/define_trace.h> 可能导致#include <linux/module.h>,从而可能触发#include <trace/events/module.h>中的tracepoint,导致不期望的结果。在define_trace.h首部#include <linux/module.h>,将#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不断出现的原因。

评分

参与人数 1可用积分 +18 收起 理由
Godbach + 18 感谢分享

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2011-03-08 19:07 |只看该作者
的确,内核中的宏 ,搞死人啊

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
3 [报告]
发表于 2011-03-09 08:20 |只看该作者
同感
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP