Page 311 - 《软件学报》2021年第7期
P. 311

张献  等:基于代码自然性的切片粒度缺陷预测方法                                                        2229


                 征的重要性.
                    以上是对本文方法核心构成的可解释性的简要分析.至今,关于机器学习可解释性的研究依旧是一个难题.
                 我们也将在后续工作中继续加以探索.
                    (2)  代码自然性的讨论
                    本文将在切片级模块粒度上应用 CNDePor 方法并验证方法的有效性.由于涉及依赖性强的程序切片技术,
                 因而易使读者产生如下疑问:由于程序切片有别于自然语言特性,那么再提“代码自然性”是否合适?我们保持该
                 提法的思考是:① 对原始“代码自然性”思想的一种延续.本质上代码是一种人工制品.Hindle 等人最早提出的
                 软件代码的“自然性假设”受自然语言特点启发,因此所谓的“代码自然性”原本就是一种借鉴性说法.为延续这
                 种思想,本文保持了“代码自然性”这一提法.② 已有不少工作利用 NLP 方法来处理代码分析任务                              [12,50] .虽然软
                 件代码有别于自然语言文本,但是它们有着诸多相似之处,例如都有语法规则约束、都由语法单元构成、都能
                 表示成序列/树/图等形式.文中作为重要基准的 VulDeePecker 方法,即是利用 NLP 领域中经典的双向 LSTM 模
                 型来学习切片代码段的语义特征,进而利用分类器进行缺陷识别.③ 语言序列的自然性是相对于语料库而言
                 的.语言模型可以视作是一个语言学习者,其在挖掘语料库的过程中会对常见的序列赋予更高的自然性,而罕见
                 的序列则反之.也就是说,语料库对语言模型起到决定性作用.一旦语料库构造完成后(如本文的切片粒度模块
                 数据集),便可以利用语言模型进行训练,进而判断给定序列(在该语料库上)的自然性.④ 语言模型可以捕获语
                 言间的依赖等规律与模式.通过挖掘语料库,语言模型(特别是神经语言模型)善于学习语言间的依赖规律和使
                 用模式,进而建模出语言序列的联合概率分布.对此说法的一个有力证据是语言模型在代码提示与补全                                    [54] 等任
                 务上取得的成功.

                 3    切片粒度模块生成方法及度量元设计

                    事实上,本文提出的 CNDePor 方法适用于不同粒度缺陷预测问题.然而经典的粗粒度方法难以精确地预测
                 缺陷区域,例如文件级、类级,使得实际应用中软件开发人员需要付出高昂的代码审查/测试成本.为此,我们将利
                 用 CNDePor 方法在面向语句的切片级粒度上进行细粒度缺陷预测应用.下面主要介绍切片粒度模块的生成方
                 法和面向此类模块的度量元设计.
                 3.1   模块生成方法
                    切片粒度软件模块的生成过程如图 4 所示.这一粒度分析的软件模块实质上是由一个或多个面向语句的
                 切片构成的代码序列.针对特定缺陷类型设计相关的切片准则,再通过软件历史信息标注生成的切片模块,便可
                 以构建出缺陷数据集.具体步骤如下            [30] .
                    步骤 1.  抽取库/API 函数调用.将库/API 函数调用分为两类:前向型和后向型.如果库/API 函数调用直接从
                 外部接收一个或多个输入,例如命令行、外部程序等,则它属于前向型.如果库/API 函数调用不从程序运行环境
                 中接收任何外部输入,则它属于后向型.
                    步骤 2.  生成关于库/API 函数调用中参数的切片.针对前向库/API 函数调用中的每个参数,生成一个或多个
                 前向切片;针对后向库/API 函数调用中的每个参数,生成一个或多个后向切片.需要注意的是,程序切片中的语
                 句可以从属多个函数,即切片范围可以逾越切片准则所在的函数.
                    步骤 3.  融合程序切片构成软件模块.针对已生成的切片集合,将从属于相同自定义函数的语句融合为一个
                 代码段,次序按语句在自定义函数中的原有出现顺序来设置.如果切片间存在重复语句,则删除.然后,将从属于
                 不同自定义函数的代码段融合为一个整体,构成一个软件模块.如果两个代码段对应的函数在某个切片中已有
                 明确顺序,则顺序保留;否则,代码段的顺序随机设置.
                    步骤 4.  标注软件模块的质量类型.依据缺陷数据库信息及人工审核方法,为每个软件模块分配一个质量标
                 签:“1”代表有缺陷;“0”代表无缺陷.需要注意的是,根据贡献者论文的叙述,实验数据集存在标签噪声,即相同的
                 软件模块可能拥有不同的质量标签.对于这种冲突情况,本文将其列为未知类型.
   306   307   308   309   310   311   312   313   314   315   316