一 收集信息
包括:用户文档,设计文档,FAQ,SDK,测试源代码 (网站上能收集到的有用信息)这些信息可以从项目的主页、Wiki、Google、邮件列表、论坛,以及相关的论文和书籍中获得,并且将收集的相关信息统一管理起来。
二 制定分析策略
由于开源软件的代码量往往是惊人的,很多时候又缺少相关的设计文档和资料,并且对于个人来说精力也是有限的。因此,在代码分析之前制定一套分析策略是比较重要的。分析代码之前首先要明确我们分析的最终目的是什么?(主要是用途,我们用这些代码来干什么,完成什么工作,了解到什么程度就可以了)
如果我们分析代码的主要目的是研究某个模块或者功能的具体实现细节,则应当将研究目标放在下面几个方面:
实现采用了什么算法?算法的思想和原理是什么?
实现采用了什么数据结构描述
实现过程中使用了什么实现技巧
不管分析的目的是以上三个方面的哪个方面,在分析过程中都应将重点放在拟定的分析目标的基础上,不断的向自己提出新问题。不要迷失到庞大的代码中了。结果不但花费了很多时间,最终的结果也并非预期想要的。
三 源码分析
再收集和阅读相关资料,并且确定了分析策略后即可开始研读代码。代码的分析主要分成几个个部分:构建可运行环境、构建测试环境、源码的静态分析和源码的动态分析。静态分析过程重点在于把我整个代码的逻辑结构和关系,而动态代码分析主要是关注的数据流和实现方法。
阅读项目构建代码(Makefile、Scons或 者Shell),可以了了解产品的大体框架结构,并且可以了解系统目前支持那些特性、依赖那些库和文件。一般来说,开源软件都会提供README、 INSTALL文件或者在其主页上提供构建的需求文件以及构建方法。参照文档,我们可以构建出至少debug和release两个不同的版本。但是文档中 往往只会提及一些基本的构建指令、编译规则中有可能隐含了很多产品特性,这些特性可以通过阅读Makefile文件或者使用config --help来获得。通过不同的编译特性组合我们可以构建出不同特性的测试版本。
一般开源软件都会提供测试方法和代码,这些信息可以从项目主页或者代码树中获得。获得测试代码和方法后应当将这些测试代码在以构建的产品中运行一次,这样可以了解产品目前实现的状态以及发现一些缺陷,了解代码的运行环境。
代码统计:有多少代码文件采用一种语言还是多种语言?语言的分布情况代码行数有多少
四 构建代码模块
一般来说,开源软件的功能模块都是按照目录层次结构划分的,并且目录名称或者文件名称都会很明确的表示该模块或者文件的功能是什么。因此通过了解文件和目录的组织关系可以很直观的了解代码的组成结构。不过也有特列,如果文件名称或者目录名称不能很明确的标明功能,则需要通过分析代码中包和类关系来确定组成关系了。
五 了解关键的数据结构
这个活动主要是以阅读代码为主,通过阅读代码的头文件可以对关键的数据结构和涉及的算法有一个初步的认识。了解这些数据结构的大致功能,数据结构之间的关系。最后,可以通过对数据结构代码的了解绘制出数据结构的大体的关系图。
六 代码调试
这个步骤需要了解下面几个方面的问题:
运行时需要的环境变量是什么
参数是什么
运行时以来的库有那些
运行时访问的资源有那些
最终了解:
不同用列情况下的函数调用信息
数据结构关系图
数据流图
算法实现的原理文档
七 添加和修改功能
了解一个系统的最终目的还是为了使用,因此为了检验对软件的理解是正确的,我们应当在现有的基础上去修改代码以验证我们的理解是没有问题的。但是整个过程需要建立在良好的测试环境基础上。这个活动的主要步骤有:
了解现有代码的实现规则
确定修改或者添加功能的目标
实现代码
编写测试代码验证实现过程是正确的