源码分析的目的
分析源码从来不是孤立的,不是为了源码而分析源码,而是为了更好的理解某一模块。这里所说的模块,指的是一个独立的功能单元,是硬件设备、设计与源码的集合。以网卡驱动为例,包括物理的MAC与PHY芯片、总线协议、驱动源码三部分。
前期准备
要理解这一模块的工作原理与实现方式,需要从上面三方面着手,而且是要同时进行。在开始前,需要搜集相关资料。如硬件手册、协议规范、源码。相关资料了解的越多,越有助于源码的阅读分析。
还有一个是合适的工具,我见过的最好工具是source insight,交叉索引能力非常强大,分析源码的必备利器。
分析方法
1)简化
源码中总是有很多没有必要关注的代码。如为了兼容不同型号硬件而做的宏区分,历史遗留的费代码,如参校验等提高安全性的代码。实际上都是在源码分析时没必要看的。它们经常比有用代码还多。删除这些代码,可以极大降低阅读难度。
2)三副图:函数调用图、数据流图、配置图
源码的细节很复杂,但没有必要全记住。分析过程可能很复杂,需要用几周时间,但最终的结果可能用几幅图就完全概括了。这些图就像是一张张地图,自从有了它,我们不再迷路。不管是重构还是添加新功能,都有了依据。
主线是函数调用图,因为我们按着模块的入口函数一层成分析函数调用图。副线是数据流图,目的是为了搞明白各个函数的入参是从哪里来的。作为对函理解数功能的辅助。
配置图指的是模块的配置信息,主要是一些全局结构体变量,这个也是使用该模块时唯一需要修改的东西。如果说前两幅图是城市交通的话,配置图就是导航仪上的行车路线图。
3)抽象
上面已经得到了地图,我们还需要什么呢?对于小模块来说,不需要了。比如我画了张我们村的地图,总共就一条街,一眼就能看清楚,就不需要其他的了。但是如果是张北京市地图,不在划分一下还真不行。总要分个朝阳、通州吧。大的模块也是这样,需要把函数组合成一个个模块,最好的结构就是一眼就能看明白其中关系。
出了帮助从宏观上把握模块外,抽象还有更重要的一层意思:搞清楚模块的设计思路。任何模块的都是基于一定的设计思路的,搞清楚其他人的设计思路可能比搞清楚代码调用过程对自己帮助更大。
成果输出
三幅图与抽象的结果。
本文乃fireaxe原创,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,并注明原作者及原链接。内容可任意使用,但对因使用该内容引起的后果不做任何保证。
作者:fireaxe_hq@hotmail.com
博客:fireaxe.blog.chinaunix.net
阅读(543) | 评论(0) | 转发(0) |