掌桥专利:专业的专利平台
掌桥专利
首页

一种软件不可重复编译故障定位及补丁自动生成方法

文献发布时间:2023-06-19 12:16:29


一种软件不可重复编译故障定位及补丁自动生成方法

技术领域

本发明属于软件编译领域,涉及一种用于定位软件不可重复编译故障和自动生成故障修复补丁的技术,具体为一种软件不可重复编译故障定位及补丁自动生成方法。

背景技术

随着网络技术和计算机技术的快速发展,人们获取开源软件的途径逐渐增多,如各式的应用商店、资源网站等。保证获取的软件的安全性和可信性已经成为了一个日益严重的问题。因此,以Debian为首的开源社区通过确保分发软件包可重复编译,来验证软件包的可信性。可重复编译是指任何一方在相同的编译环境下,使用相同的编译指令,对相同的源代码进行编译,都可以生成特定工件逐位相同的副本。

虽然现有的一些论文和发明专利可被用于软件故障的修复,但其故障定位精度及修复方法在软件不可重复编译故障上仍存在许多不足。例如,基于代码变更历史的软件代码质量问题自动修复方法、系统及介质(专利申请号:CN201911338355.0),此专利首先获取待修复目标的代码;然后从基于代码变更历史变更的修复模式库中找出匹配的修复方式;最后生成目标代码的修复补丁。但是此方法并未针对软件不可重复编译故障的修复。2018任等人在论文不可重复编译定位中提出的RepLoc框架,此框架从构建日志中提取信息,通过启发式组件过滤缩小信息搜索范围,提供可能的文件列表。但是此框架高度依赖构建日志,因此只能分析高级构建命令,同时构建日志中信息的完整性对框架的效率也会产生影响。2019任等人进一步提出一种基于系统调用日志的不可重复编译定位方法RrpTrace并申请相关专利(专利申请号:CN201910549431.6),此专利首先通过对系统调用日志信息进行差异分析编译依赖图;再通过分析编译过程中父子进程关系对依赖图进行增强;最终通过遍历依赖图并排序,得到最终的问题编译命令,以便进行后续修复工作。该专利能够有效验证软件源代码与二进制包之间的对应关系,一旦发生不一致,能够定位到可能导致软件不可重复编译的编译命令。但是该方法在追踪过程中对于存储的空间要求较高,而且只能到达文件级别,定位粒度有待提高。

综上所述,目前的软件可重复编译故障定位与修复方法存在以下两方面问题:一是定位粒度不够精细,现有方法均只能实现文件级定位,且所需存储空间较大;二是目前软件包可重复编译故障修复方式主要是修改执行过程中的系统调用或者命令行参数,并且目前积累的修复经验没有得到利用,缺乏源码包修复补丁的自动生成。

发明内容

本发明的目的在于提供一种软件不可重复编译故障定位及补丁自动生成方法。本发明有利于提高软件不可重复编译故障的定位粒度,降低存储空间,并自动生成故障修复补丁。

本发明的技术方案:

一种软件不可重复编译故障定位及补丁自动生成方法,具体步骤如下:

步骤1:构建两个具有差异化的编译环境1号和2号。

具体为:编译环境由固定部分和扰动部分组成。其中固定部分在两个编译环境中保持不变,包括编译器种类、编译需要的相关依赖等。扰动部分是指两个编译环境差异化的部分,包含语言环境、时间、编译目录等。

步骤2:在1号和2号编译环境下分别编译源码包,得到1号生成工件和2号生成工件。

具体为:在1号编译环境和2号编译环境下,根据编译规则,对源码包进行编译。在1号编译环境下编译生成的工件为1号生成工件,在2号编译环境下编译生成的工件为2号生成工件。

步骤3:判断1号生成工件和2号生成工件是否一致。

具体为:利用工具diffoscope对1号生成工件和2号生成工件进行比特级递归对比,判断两者是否完全一致。如果两者比较结果完全一致,则软件可重复编译,报告一致性结果,流程终止。如果两者比较结果不一致,将比对工具输出文件作为差异日志,并从差异日志中提取作为故障定位基础的文件名;根据提取的文件名列表生成差异文件列表文件,并将该文件作为步骤6的输入。

diffoscope工具由不可重复编译社区Reproducible builds开发,拥有GNU通用公共许可版本3许可的免费软件,可在多个平台获取。该工具能够将二进制文件以更利于理解的形式进行对比,并可以生成多种格式的对比文件。

步骤4:调用疑似系统调用进程传播图生成程序,生成疑似系统调用进程传播图。

具体为:系统调用能够产生导致软件包不可重复编译的内容,则称该系统调用为疑似系统调用,产生导致软件包不可重复编译的内容为疑似内容。在源码包编译过程中,调用疑似系统调用进程传播图生成程序,以ptrace(process trace)系统调用为核心的监控源码包编译过程中所有的系统调用,生成疑似系统调用进程传播图,并将该图作为步骤6的输入。

整体过程如下:记录所有疑似系统调用和发出该疑似系统调用的进程信息;跟踪读写操作,记录疑似内容在进程间的传播路径;生成疑似系统调用进程传播图。图中节点为自定义的进程信息类,包含发出疑似系统调用的进程号、发出的疑似系统调用、疑似内容、包含疑似内容的写出文件、包含疑似内容的读取文件,图中边为疑似内容在进程间的传播方向。

ptrace是在Unix和一些类似Unix的操作系统中对进程追踪的系统调用。它提供了父进程观察和控制其子进程执行的能力,并允许父进程检查和替换子进程内核镜像(包括寄存器)的值。在Windows平台,可使用Debuging API实现系统调用监控。

步骤5:调用编译工具信息提取程序,生成进程和文件行号之间的对应关系日志文件。

具体为:在源码包进行编译时,根据使用的编译工具的调试符号表,通过断点得到特定函数运行时的参数值,获取编译过程中正在运行的进程信息和该进程执行的编译命令信息。根据获取的进程信息和编译命令信息,即可生成进程和文件行号之间的对应关系日志文件,并将该图作为步骤6的输入。

步骤6:不可重复编译故障定位,得到导致软件不可重复编译故障的编译命令。

具体为:获取步骤3生成的差异文件列表文件,步骤4生成的疑似系统调用进程传播图,步骤5生成的进程和编译脚本文件行号对应关系日志文件。在疑似系统调用进程传播图中进行搜索,匹配图中节点包含疑似内容的写出文件名,得到写出差异文件的进程p1。根据系统调用进程传播图搜索路径找到发出疑似系统调用的进程p2;在进程和编译脚本文件行号对应关系日志中搜索,定位编译脚本中执行进程p2的代码行和编译命令。

步骤7:获取历史修复补丁,获取源命令和目标命令。

具体为:根据步骤6中定位的编译命令,获取和该软件不可重复编译故障有着相似故障,且已经发行的历史修复补丁。使用脚本,从补丁中提取出修复的内容,即修复前的编译命令和修复后的编译命令。其中修复前的编译命令称为源命令,修复后的编译命令称为目标命令。

步骤8:将源命令和目标命令转化为AST,获取修复节点。

根据编译原理语法分析将源命令和目标命令都转化为AST(Abstract SyntaxTree),AST中CommandNode为根节点,WordNode和RedirectNode为中间节点,解析后的命令内容为叶子节点。对比源命令转化的ASTT1和目标命令转化的ASTT2,其中存在改动的ASTT2叶子节点即为修复的节点,叶子节点的内容即修复的命令内容。

AST(Abstract Syntax Tree)是指抽象语法树,是源代码语法结构的一种抽象表示。

步骤9:修复定位获取的命令对应的AST,得到修复之后编译命令。

具体为:根据编译原理语法分析将步骤6中在编译脚本中定位获取的命令转化为对应的ASTT3。将步骤8中获取的AST T2的修复节点变换施加在AST T3上,得到定位获取的命令修复之后的ASTT4,将定位获取的命令修复之后的ASTT4重新转化为编译命令,该命令即为修复之后编译命令。

步骤10:生成修复补丁,修复软件源码包。

具体为:根据编译原理将步骤8中修复之后的编译命令,生成软件不可重复编译故障的修复补丁。根据生成的修复补丁,对编译脚本进行修复。

步骤11:修复软件包健全性检测。

具体为:对修复之后的源码包进行编译,如果该源码包能够正常编译,并且生成的工件和修复其之前的源码包所编译生成的工件相比没有缺失;同时生成的工件能够正常发挥功效,则说明软件包是健全性的,则可以对软件包进行步骤1中的可重复编译检测。如果通过检测则返回自动生成的修复补丁。如果修复的软件包未能通过健全性测试,则返回步骤7重新生成补丁。

本发明的有益效果:本发明方法可对软件不可重复编译故障进行定位并自动生成修复补丁,避免了以前修复工作中需要开发人员手动定位和修复的繁琐工作,大大的节省了时间。

附图说明

图1是本发明的一种软件不可重复编译故障定位及补丁自动生成方法的工作流程示意图。

具体实施方式

以下结合附图、技术方案以及实例对本发明方法进行详细说明。

本实施例中,本发明的方法部署在一台Linux服务器上,服务器具体配置如表1所示。本实施例以软件包when为例进行阐述,需要when的源码包以及dpkg包管理器等相关依赖,make编译工具,diffoscope对比工具,reprotest编译工具。本发明方法由源码包两次编译对比程序、编译追踪程序、修复补丁生成程序等程序构成。

表1:Linux服务器配置信息表

如图1所示,本发明的一种软件不可重复编译故障定位及补丁自动生成方法按如下流程进行。构建编译环境,得到源码包生成工件;判断两次生成工件是否一致;调用编译追踪程序,对源码包的编译过程追踪;不可重复编译故障定位;获取历史修复补丁并自动生成软件源码包的修复补丁;修复软件源码包;修复软件健全性检测。

本实施例步骤描述时以Linux平台下ptrace为例,具体步骤可以根据平台进行调整。具体步骤如下:

步骤1:构建两个具有差异化的编译环境1号和2号。

具体为:构建两个具有差异化的编译环境1号和2号。

本实施例中1号编译环境中的编译目录为b1,时区为UTC-8(PST—太平洋标准时间),时间从零点开始。2号编译环境中的编译目录为b2,UTC+8(CT—中国标准时间),时间从12点开始。

步骤2:在1号和2号编译环境下分别编译源码包,得到1号生成工件和2号生成工件。

具体为:在1号编译环境和2号编译环境下,根据编译规则,对源码包进行编译,得到1号生成工件和2号生成工件。

本实施例中使用构建命令如下:‘dpkg-buildpackage-us-uc’,完成了对when软件包的两次编译。1号生成工件保存在目录b1下,2号生成工件保存在目录b2下。

dpkg(Debian Packager)为“Debian”的套件管理系统,方便软件的安装、更新及移除。所有源自“Debian”的“Linux”发行版都使用“dpkg”,例如“Ubuntu”、“Knoppix”等。

步骤3:判断1号生成工件和2号生成工件是否一致。

具体为:利用工具diffoscope对1号生成工件和2号生成工件进行比特级递归对比,判断两者是否完全一致。本实施例中使用命令diffoscope–jsondiff.json b1 b2,完成b1和b2中所有生成的工件比特级递归对比。如果b1和b2比较结果不一致,比对工具输出文件为diff.json。使用脚本从diff.json文件中提取作为故障定位基础的文件名为/usr/share/man/man1/when.1.gz,并生成差异文件列表文件difffiles.json。

步骤4:调用疑似系统调用进程传播图生成程序,生成疑似系统调用进程传播图。

具体为:在源码包编译过程中,调用疑似系统调用进程传播图生成程序,以ptrace(process trace)系统调用为核心的监控源码包编译过程中所有的系统调用,生成疑似系统调用进程传播图。本实施例中调用疑似系统调用进程传播图生成程序追踪‘dpkg-buildpackage-us-uc’命令执行,完成when软件包的编译过程追踪。生成疑似系统调用进程传播图G1。

步骤5:调用编译工具信息提取程序,生成进程和文件行号之间的对应关系日志文件。

具体为:在源码包进行编译时,通过断点得到特定函数运行时的参数值,获取编译过程中正在运行的进程信息和该进程执行的编译命令信息,生成进程和文件行号之间的对应关系日志文件。

本实施例中,使用的是make编译工具,安装带有调试信息的make-dbgsym,通过中断make的start_waiting_job和job_next_command函数执行,获取函数的参数,生成进程和文件行号之间的对应关系日志文件correspond.json。

make编译工具是负责从项目的源代码中生成最终可执行文件和其他非源代码文件的工具。

步骤6:不可重复编译故障定位,得到导致软件不可重复编译故障的编译命令。

具体为:本实施例中获取步骤3生成的差异文件列表文件difffiles.json,步骤5生成疑似系统调用进程传播图G1,步骤5生成的进程和编译脚本文件行号对应关系日志文件correspond.json。将差异文件列表文件difffiles.json作为输入,在疑似系统调用进程传播图G1中进行搜索,利用正则匹配的方式匹配图中节点包含疑似内容的写出文件,从而得到写出差异文件的进程84。根据系统调用进程传播图搜索路径找到发出疑似系统调用的进程63。进程号63作为输入,在进程和编译脚本文件行号对应关系日志correspond.json搜索,定位到when源码包makefile文件中的第49行,构建命令为gzip-9when.1.gz。

步骤7:获取历史修复补丁,获取源命令和目标命令。

具体为:本实施例中定位的命令为gzip-9when.1.gz。通过脚本在目前debain已经发布的修复补丁中搜索,发现rockdodger软件的修复补丁为可利用补丁,下载rockdodger的修复补丁。提取补丁的修复内容,rockdodger修复补丁中修复内容如下:

-gzip-9debian/tmp/usr/share/doc/rockdodger/changelog.Debian

+gzip-9n debian/tmp/usr/share/doc/rockdodger/changelog.Debian

其中前者为源命令,后者为目标命令。

步骤8:将源命令和目标命令转化为AST,获取修复节点。

本实施例中:将源命令和目标命令转化为ASTT1和T2,T1、T2都对应三个WordeNode节点,T1为gzip,-9,debian/tmp/usr/share/doc/rockdodger/changelog.Debian,T2为gzip,-9n,debian/tmp/usr/share/doc/rockdodger/changelog.Debian。对比两棵AST树,可知T2的第二个WorldNode节点为修复节点。

步骤9:修复定位获取的命令对应的AST,得到修复之后编译命令。

具体为:对when包不可重复编译故障定位得到的编译命令为gzip-9when.1.gz,将该命令转化为ASTT3,T3包含两个WordNode节点和两个RedirectNode节点,分别为gzip,-9,when.1.gz.。将rockdodger修复补丁中的修复内容变换施加在when包不可重复编译故障定位得到的命令转化的ASTT4上,T4的节点为两个WordNode节点和两个RedirectNode节点,分别为gzip,-9n,when.1.gz。将定位获取的命令修复之后的ASTT4转化为编译命令可得gzip-9nwhen.1.gz。

步骤10:生成修复补丁,修复软件源码包。

本实施例中生成修复补丁when.sh将when软件包中makefile文件的第49行命令修改为gzip-9nwhen.1.gz。

步骤11:修复软件包健全性检测。

具体为:本实施例中,对修复的when源码包进行编译,源码包成功编译,编译工件保存在文件目录b3下,其中包含的文件/usr/share/man/man1/when.1.gz、/usr/bin/when、/usr/share/doc/when/NEWS.Debian.gz、/usr/share/doc/when/copyright、/usr/share/doc/when/changelog.Debian.gz和未修复的when源码包编译生成的工件相同。编译生成的工件功能上无差异,进入步骤1对修复之后的源码进行可重复性编译检测。

修复的when软件包进行可重复编译检测,两次编译生成的工件一致,说明修复补丁有效,when软件包的修复工作完成。

本发明方法有效减少追踪过程中对存储空间的消耗;故障定位颗粒程度提升,实现了文件行级定位;根据历史修复信息自动生成修复脚本,完成源码包修复。大大减少了时间和人力的投入,有效节约成本。

相关技术
  • 一种软件不可重复编译故障定位及补丁自动生成方法
  • 一种补丁编译平台及补丁编译方法
技术分类

06120113229058