专利名称:一种基于Java并发程序错误的不变式检测系统的制作方法
技术领域:
本发明属于程序错误检测技术领域,具体涉及一种针对Java并发程序错误的检测系统。
背景技术:
随着计算机多核技术的发展,Java多线程技术的优势体现的越来越明显。多线程技术不仅能够提高程序的运行效率,还能提高程序的实时响应性,从而提升用户体验,目前推出的软件产品大多以多线程的方式实现。然而,多线程技术在为程序带来这些优势的同时,由于其编写时的复杂性和执行时的不确定性,也给程序员带来了新的挑战。在程序编写时,程序员需要额外地对各个线程中的工作进行同步管理,保持数据的一致性,否则就可能引发程序并发错误,会对软件的质量造成重大影响,并且这类错误较难被检测和修复。
为了统一地检测程序中多种类型的并发错误,一系列基于不变式的检测工具被提出。这类工具首先制定相应的不变式规则来代表可能产生并发错误的程序行为,然后通过一定数量的训练运行提取满足不变式的所有正确程序行为,最后以收集到的信息指导检测运行时的并发错误检查。不变式检测方法作为目前最为有效的并发错误检测手段,以提取正确程序行为的方式自动识别程序并发错误,较之传统的分析方法在精度和效率上都有一定的优势。但现有的不变式检测工具主要为C/C++语言设计,未考虑Java的程序特性。传统的不变式检测工具以上下文不敏感的信息来区分不同程序点,该信息一般为静态指令(例如,方法名和文件行号的组合)。但是由于Java中大量的包装函数,程序中大量的访存操作被封装在包装函数中,其中最为典型的就是程序中的getter和setter函数了。如果继续沿用静态指令来区分程序点,调用相同包装函数的不同访存操作都被认为是同一程序点,这样可能会误导检测工具最终检测结果的正确性。以一个极端的情况为例,私有字段只能通过getter来读取,通过setter来修改,那么传统的工具会认为所有调用这两个函数的程序点都是相同的,这样显然是不精确的。如图I所示,两端程序是相同含义的C++和Java的程序片段,且S2语句应该在S3语句执行完后被执行,否则会造成错误。对于C++程序,使用访存操作的静态语句能分析出S36S2是正确依赖,而S16S2则是错误依赖,这样在检测运行时就能检测出这一错误。但是Java程序中由于封装函数的存在,访存操作都被包含在封装函数中,无论是正确依赖还是错误依赖都是S46S5,由于无法区分正确和错误依赖,所以这一并发错误就无法被检测出来。简单地说,上下文不敏感的信息不足以区分Java程序中的访存程序点,使用静态语句表示程序点不能满足Java程序检测的要求,而上下文敏感的技术则为Java程序的不变式检测带来了新的机会。
发明内容
为了解决上述提到的Java程序中的封装函数导致传统工具无法有效区分程序点的问题,本发明提供一种基于Java并发程序错误的不变式检测系统。
本发明在动态运行时对程序的上下文信息进行记录,并为每个带有上下文信息的程序点收集和检测程序并发错误,以此消除因封装函数所带来的程序点无法区分的影响。本发明提供了一种基于Java并发程序错误的不变式检测系统,包括预处理模块、不变式训练模块、不变式文件分析模块,不变式检测模块,错误排序删减模块以及上下文收集传递模块六大模块;所述上下文收集传递模块与所述不变式训练模块以及所述不变式检测模块同时运行,在动态运行时所述上下文收集传递模块将当前的上下文信息进行转换,传递给所述不变式训练模块或所述不变式检测模块;所述不变式训练模块或不变式检测模块使用接收到的上下文信息连同静态语句来表示一个唯一的程序点。其中
I.预处理模块,负责检测和过滤程序中不会引起并发错误的对象。这样的对象有两类,分别是局部对象和单赋值对象。本发明通过静态分析找出这些对象,并在字节码中添加标签进行标示。在训练和检测运行阶段,本发明识别这些标签,并忽略对有标签对象的检查和记录,从而降低检测所带来的开销。
2.不变式训练模块,使用多次训练运行,基于对象粒度提取程序中的不变式信息,并将收集的不变式集合以文件形式进行保存,每次正确运行产生一个不变式记录文件。3.文件分析模块,负责把所有记录文件中的信息按照不变式规则进行归并,最终合成一个文件。4.不变式检测模块,利用合成文件指导检测运行。当检测运行中的程序行为与记录中的对象不变式信息出现矛盾时,说明可能存在并发错误,需要进一步分析。5.错误排序删减模块,负责对检测模块检测到的程序错误做可信性分析。该模块使用启发式算法,为所有检测到的错误计算相应的可信值。删除可信值较低的错误,其他筛选得到的错误经过排序后反馈给程序员。6.上下文收集传递模块,用于在动态运行时以一定的方式记录和传递当前的上下文信息。上下文收集传递模块与不变式训练模块以及不变式检测模块同时运行,在动态运行时上下文收集传递模块将当前的上下文信息进行转换,传递给不变式训练模块或不变式检测模块;
不变式训练模块或不变式检测模块使用接收到的上下文信息连同静态语句来表示一个唯一的程序点;
上下文收集传递模块与在训练和检测运行中同一程序点上的上下文信息保持一致。本发明中,上下文收集传递模块记录和传递当前的上下文信息时可采用PCC模式,即利用程序当前行号和当前调用栈的信息连续地使用哈希函数进行计算,通过计算出的值来表示当前程序点的上下文内容,用公式表达为
p = f{p, c) = (3/3 十 c) mod 264 ⑴
其中p*表示被调用函数中某个程序位置的上下文哈希值的数值,P表示调用函数的上下文哈希值,c表示在当前函数中的位置信息。PCC模式具体计算过程是通过从上至下的方式展开的,即表示上下文的哈希值P会从调用函数向被调用函数传递并进行相应的计算。PCC模式中的计算起点函数包括1)程序的main函数;2)程序中所有继承了java. lang. Thread类和java. lang. Runnable类中所声明的run函数。这些起点函数都是程序中所有线程的入口 ;具体实现中为了使不同运行中相同下上文环境具有相同的PCC值,PCC模式下把所有起点函数的PCC值初始化为O。本发明中,PCC方法能简单地通过比较PCC值,达到区分程序中的上下文环境的目的,不对程序的运行带来过大的性能影响;并且在不同的运行中,相同的上下文环境能匹配相同的PCC值。本发明中,上下文收集传递模块记录和传递当前的上下文信息时还可采用PaCC方法,其也以计算哈希值的方式来表示当前程序调用栈的信息。其记录从调用栈底向上到真正调用封装函数的位置。PaCC模式下计算的程序点哈希值依赖于当前上下文窗口中siz印个程序点的信息,包括它们的文件名字符串哈希值(C),文件行号(h)。哈希值由上下文窗口由下至上计算,计算sizep次,其计算公式为
权利要求
1.一种基于Java并发程序错误的不变式检测系统,包括预处理模块、不变式训练模块、不变式文件分析模块,不变式检测模块,错误排序删减模块,其特征在于还包括上下文收集传递模块;所述上下文收集传递模块与所述不变式训练模块以及所述不变式检测模块同时运行,在动态运行时所述上下文收集传递模块将当前的上下文信息进行转换,传递给所述不变式训练模块或所述不变式检测模块;所述不变式训练模块或不变式检测模块使用接收到的上下文信息连同静态语句来表示一个唯一的程序点。
2.根据权利要求I所述的不变式检测系统,其特征在于所述上下文收集传递模块记录和传递当前的上下文信息时采用PCC模式,即利用程序当前行号和当前调用栈的信息连续地使用哈希函数进行计算,通过计算出的值来表示当前程序点的上下文内容,用公式表达为 P = i{Pf c) = (3p + c) mod 204 ⑴ 其中P*表示被调用函数中某个程序位置的上下文哈希值的数值,P表示调用函数的上下文哈希值,c表示在当前函数中的位置信息; 所述PCC模式具体计算过程是通过从上至下的方式展开的,即表示上下文的哈希值P会从调用函数向被调用函数传递并进行相应的计算; 所述PCC模式中的计算起点函数包括1)程序的main函数,2)程序中所有继承了java. lang. Thread 类和 java. lang. Runnable 类中所声明的 run 函数; 所述PCC模式下,所有起点函数的PCC值初始化为O。
3.根据权利要求I所述的不变式检测系统,其特征在于所述上下文收集传递模块记录和传递当前的上下文信息时采用PaCC模式,其用计算哈希值的方式来表示当前程序调用栈的信息,其记录从调用栈底向上到真正调用封装函数的位置,PaCC模式下计算的程序点哈希值由上下文窗口由下至上计算,计算sizep次,其计算公式为 Pg =c, Ii) = (13ρa + Sc + h) mod 2 ^⑵ 其中Pa*表示被调用函数中某个程序位置的上下文哈希值的数值,Pa表示调用函数的上下文哈希值,c表示文件名字符串哈希值,h表示文件行号; 其中所述sizep表示上下文窗口的大小,其大于或等于当前封装方法的栈深度depthw加1,即 sizep >= depthw+I (3) 。
4.根据权利要求3所述的不变式检测系统,其特征在于所述上下文窗口的大小sizep为4。
全文摘要
本发明属于程序错误检测技术领域,具体为一种基于Java并发程序错误的不变式检测系统。其包括预处理模块、不变式训练模块、不变式文件分析模块,不变式检测模块,错误排序删减模块及上下文收集传递模块六大模块;本发明在在动态运行时以PaCC及PCC模式对程序的上下文信息进行记录,解决了Java程序中的封装函数导致传统工具无法有效区分程序点的问题。
文档编号G06F11/36GK102799527SQ201210236250
公开日2012年11月28日 申请日期2012年7月10日 优先权日2012年7月10日
发明者杨珉, 王笛 申请人:复旦大学