专利名称:用于分析运行时存储器访问错误的方法和系统的制作方法
技术领域:
本发明涉及软件开发,并且更具体地,涉及计算机程序的运行时存储器分析。
背景技术:
许多现代程序设计语言不支持防止运行时存储器访问错误的程序设计结构。运行时存储器访问错误可以包括、但不限于从未初始化的存储器读取或写入、超出所定义的数组的范围读取或写入、存储器泄漏、空闲存储器访问等。不支持防止这样的动作的构造的现代程序设计语言的一个例子是C或C++程序设计语言。当编译以C或C++编写的程序时,通常未检测到诸如以上所指出的运行时存储器访问错误。
举例来说,在C/C++内,开发者可能定义特定大小的数组并且然后访问超过该数组大小的元素。考虑图1中所示的代码实例。如所示出的,对a[21]的访问针对的不是由程序所分配的存储器部分,并且因此可能是堆(heap)上未分配的存储器或者是由另一段程序所分配的存储器。这样的动作是非法的,但却通常未被常规的C/C++编译器检测到。
然而,一些运行时分析工具,例如那些利用目标代码插入(OCI)技术的工具,可以检测这些类别的错误。OCI是在计算机程序的目标文件内插入校验指令的技术。具有这种插入其中的校验指令的程序被称作插装程序(instrumented program)。校验指令实现各种有关存储器使用的监控和/或跟踪功能。可以在访问(reference)存储器的程序指令之间插入校验指令,即监控读取和写入操作以及存储器分配和解除分配。
扩展与运行时存储器访问错误的检测有关的运行时分析工具的功能会是有益的。
发明内容
本文所公开的实施例提供了与计算机程序的运行时存储器分析有关的方法和制品(article of manufacture)。本发明的一个实施例可以包括分析计算机程序中运行时存储器访问错误方法。所述方法可以包括利用运行时分析代码插装(instrument)计算机程序并且检测已插装的计算机程序的运行时存储器访问错误。响应于检测运行时存储器访问错误,所述方法还可以包括动态地设置监测点。
本发明的另一实施例可以包括分析计算机程序中运行时存储器访问错误的方法,所述方法包括检测所述计算机程序中的运行时存储器访问错误、为运行时存储器访问错误确定上下文信息,并且将上下文信息与用户规定的属性进行比较。如果上下文信息与用户指定的属性匹配,则可以为所述计算机程序自动地设置监测点。
而本发明的另一实施例可以包括机器可读存储器,所述机器可读存储器上具有存储于其上的多个使得该机器执行本文所公开的各种步骤和/或功能的代码区段。
附图中示出了目前优选的实施例;然而,应当理解到本发明不限于所示出的明确的装置和手段。
图1描述了对理解本文所公开的实施例有用的示范性源代码。
图2是对理解本文所公开的实施例有用的示范性源代码。
图3是关于根据图2所描述的错误由运行时分析工具所产生的示例输出。
图4是描述依照本发明的一个实施例的运行时存储器分析方法的流程图。
具体实施例方式
尽管本说明书以规定了被认为是新颖的本发明的特征的权利要求作为结论,但是可以认为考虑根据结合附图的描述将更好地理解本发明。如所需的,本文公开了本发明的具体实施例;然而,应当认识到,所公开的实施例仅是本发明的示范,其可以以各种形式实施。因此,不认为本文所公开的特定结构的和功能的细节是限制,而仅认为是用于权利要求的基本原理以及用于教导本领域的技术人员以实际上任何适当的具体结构来多样地使用本发明装置的代表性基本原理。此外,本文所使用的术语和惯用语并不打算限制而仅是提供本发明的可理解的描述。
本文所公开的实施例提供了用于在计算机程序中动态地设置监测点的技术。依照本文所公开的发明装置,用户或开发者可以设立各种条件。如果条件满足,就可以动态地创建监测点。此外,当满足设立的条件并且创建了监测点时就可以自动地执行一个或多个程序动作。
使用软件分析工具可以实现本文所描述的各种功能。例如,在一个实施例中,可以将本文所描述的各种功能实现为Rational PurifyPlus系列软件分析工具的一个或多个成员的扩展,其中来自纽约阿蒙克(Armonk)的国际商业机器公司(IBM)的Rational PurifyPlus系列软件分析工具是商业上可用的。PurifyPlus是为软件开发者和测试者提供运行时分析功能的计算机程序系列。一般而言,运行时分析指的是使用在执行处于测试中的程序期间所收集的数据来理解应用行为的实践。使用PurifyPlus可以分析的各种开发活动可以包括、但不限于本机C/C++应用中的存储器损坏检测和存储器剖析(memory profiling)、Java和.NET管理代码应用中的存储器剖析、识别慢的或无效的代码部分的性能剖析、代码覆盖分析以及运行时跟踪。
本文所公开的产品意图提供用于教导本领域的技术人员更好地理解本文所公开的发明装置的基本原理。然而,应当认识到,本发明可以实现为独立的应用、更大的应用的一部分或者以实际上任何适当的具体结构、计算机程序和/或其部分来实现。
图2是对理解本文所公开的实施例有用的示范性源代码。使用本文所描述的运行时分析工具来执行图2中所描述的程序会导致第10行所报告的“空闲存储器读”(FMR)错误的检测。FMR类型的运行时存储器访问错误指的是数组在被访问之前已经被释放的情形。
图3是关于根据图2所描述的错误由运行时分析工具所产生的示例输出。在所提供的关于运行时存储器访问错误的上下文信息的不同项目中,该输出指出了堆栈跟踪信息。堆栈跟踪信息指出使用对源于“calloc”内的“malloc”的调用来分配存储块,其中从“main”调用“calloc”,而从“start”调用“main”。
依照本发明的一个实施例,该上下文信息可以用于动态地创建和/或设置监测点。更具体地,该上下文信息可以与用户规定的信息,即指令的一个或多个属性进行比较。用户指定的属性指出动态地创建监测点的环境。如果上下文信息与用户指定的属性匹配,那么可以自动地设置监测点。按照可能由属性所指定的,可以执行另外的一个或多个程序动作。
监测点指的是能够指出指定的数据或存储器部分何时改变的监控程序或函数。例如,Purify中的监测点是通过监控程序执行时其进行加载和存储的地址来实现的。Purify可以报告有关读取、写入、分配、释放、进入函数入口范围以及离开函数出口范围的每次存储器访问的准确原因和结果。
在本发明的一个实施例中,用户指定的属性可以包括于运行时分析工具的配置文件内。例如,关于Purify,指令可以包括于指出特定环境的配置文件内,在该特定环境下监测点被自动地创建或者视具体情况而被调用。
这样的指令的例子可以是watch on error<error type><stack trace><re-start flag>。当在Purify的情况下将该指令放入配置文件中的时候,该指令引起针对由该指令的参数所指出的环境而设置或调用监测点。<errortype>属性指定了会引起调用监测点功能的特定类型的存储器访问错误。对于该属性来说可以指定的可能的运行时存储器访问错误可以包括、但不限于空闲存储器读错误、空闲存储器写错误、存储器泄漏错误、未初始化存储器读错误、数组边界读错误、数组边界写错误等。提供不同类型的运行时存储器访问错误的清单只是为了说明。同样地,本文所公开的实施例并不打算受限于所提供的实例。应当认识到,OCI工具能够识别的任何类型的运行时存储器访问错误都可以用作error type属性的可能值。
指令中的下一属性,<stack trace>属性可以指定为了调用监测点而要从运行时存储器访问错误检测的堆栈跟踪信息。例如,指令的堆栈跟踪信息可以指出下次检测对malloc的调用,其中从calloc调用malloc,从main调用calloc,从_start调用main,假定该指令的其他条件也满足,则自动地设置监测点。<re-start flag>属性指定了当调用监测点时是否要重新启动处于测试中的程序。在另一实施例中,可以提供另外的属性,其指出当设置监测点时是否要在调试器以及要使用的特定调试器中重新启动程序。
因此,当检测到运行时存储器访问错误的时候,可以将从运行时分析工具收集的信息,即根据图3所描述的上下文信息,与配置文件中所包括的用户指定的指令进行比较。如果检测到的运行时存储器访问错误的上下文信息与指令的属性匹配,则可以自动地创建对应于匹配指令的监测点。至于Purify运行时分析工具,视具体情况而定,可以将指定了从上下文信息或指令所提取的属性的指示插入到指示文件(directive file)。如所指出的,处于测试中的程序依照指令属性所指定的可选地可以随或不随调试器重新启动。
图4是说明依照本发明的一个实施例的运行时存储器分析方法400的流程图。例如,方法400可以开始于这样的状态,即在该状态下已将本文所讨论的各种指令中的一个或多个插入到诸如Purify的运行时分析工具的配置文件。如所指出的,指令的属性可以指定将要调用或设置监测点功能的环境。
因此,方法400可从步骤402开始,在步骤402中读取来自配置文件的指令。在步骤405中,基于OCI的运行时分析工具可以利用运行时存储器分析函数插装计算机程序。例如,Purify插装程序以自动地将每个存储器访问截取为其动态错误检测的一部分。可以将对运行时例程的一个或多个调用插入到程序,所述对运行时例程的一个或多个调用是运行时分析函数库部分,而不是处于测试中的程序的原始部分。可以在程序内包括、但不限于函数入口和/或出口点的位置插入这些函数以监控本文所描述的各种类型的存储器访问。在步骤410中,运行时分析工具可以读取来自指示文件的任何指示,所述指示文件已由于处于测试中的计算机程序的一次或多次先前的运行而被启用。可以利用已标识的指示实现存储器访问监控。
在步骤415中,可以执行插装程序。在步骤420中,可以进行关于是否遇到停止条件的确定。例如,程序可以自然地终止、遇到致命的故障或断点等。如果没有遇到停止条件,则该方法可以前进到步骤425。在步骤425中,可以进行关于是否遇到运行时存储器访问错误的确定。如果没有,则该方法可以返回到步骤415继续执行。如果检测到运行时存储器访问错误,则该方法可以前进到步骤430。
在步骤430中,可以通过OCI工具来收集上下文信息。例如,可以确定诸如引起运行时存储器访问错误的功能和/或模块的信息以及被访问的特定的存储器地址。还可以识别堆栈跟踪信息以及检测的存储器访问错误的类型,所述堆栈跟踪信息指定了通向造成运行时存储器访问错误的函数的调用链。
在步骤435中,可以进行关于检测到的运行时存储器访问错误是否与配置文件中所指定的一个或多个指令的属性一致的确定。例如,可以在步骤430中所收集的上下文信息和用户指定指令的一个或多个用户指定的属性之间进行比较。可以在检测到的运行时存储器访问错误的类型和指令中所指定的类型之间、在对引起运行时存储器访问错误有责任的函数和指令中所指定的函数之间、和/或在检测到的堆栈跟踪信息或调用链和指令中所指定的堆栈跟踪信息或调用链之间进行比较。如果检测到的运行时存储器访问错误与配置文件中的指令之一所指定的属性一致或匹配,则该方法可以前进到步骤440。如果不一致或不匹配,则该方法可以返回到步骤415继续执行。
应当认识到,可以从指令中省略本文所讨论的有关指示的一个或多个属性或者将其指定为通配符。例如,开发者可以省略对引起运行时存储器访问错误有责任的函数或者将属性指定为通配符。无论哪种情况,指令都指出有责任的函数与是否触发监测点无关。如果满足其他参数,则会动态地设置监测点而不考虑引起运行时存储器访问错误的特定函数。例如,得到的监测点会监控特定类型的存储器访问错误而不考虑触发错误的函数。类似地,运行时存储器访问错误的类型可以被忽略或被指定为通配符。在这种情况下,例如,可以识别如指令所指定的特定函数和/或调用链所触发的任何类别的运行时存储器访问错误,从而实现配置的监测点监控所指出的函数的访问。
总之,在步骤440中,可以动态地设置或创建监测点。可以将指定了用户指令的参数、并且因此指定了上下文信息的指示插入到指示文件。例如,如果指令是“watch_on_error FMM foo;*1”,则该指令指定如果在名为“foo”的函数中检测出空闲存储器失配(FMM)错误,则应当动态地设置监测点。通配符“*”指出可以从任何地方调用函数“foo”。属性“1”指示将使用可以由开发者在其它地方指定的特定调试器来重新启动程序。得到的可以被插入到指示文件的监测点命令或指示可以采取purify_watch_n(<address-of-array>,<size-of-array>,“rw”)的形式,该形式告诉运行时分析工具在用于任何的读、写和/或自由访问的地址监视存储器。
因此,在步骤445中,可以自动地执行指令中指定的一个或多个程序动作。例如,如果指令中指定了的话则可以自动地重新启动程序。另外,如果指令这样指出了,则可以在用户指定的调试器内重新启动程序。也就是说,可以自动地运行调试器并且可以自动地加载和执行程序。
当程序重新启动的时候,最近创建的监测点成为有效的并且监控对目标存储器位置的和/或通过目标函数的存储器访问。可以为进一步的分析收集并且存储运行时存储器访问信息和/或以别的方式使其对于用户可用。
本文所公开的方法描述了本发明的一个实施例,并且同样地,其不打算以任何的方式来限制本发明。本发明的其它实施例,如可以由本领域的技术人员所设想的也在本发明的范围之内。作为一个例子,诸如多线程、面向对象的程序设计等程序设计习惯的应用可能导致不同的步骤以不同于所提供的次序而被并发地执行,或者以一些其它的方式而被改变。然而,这样的差异并不背离本发明的精神。
可以以硬件、软件或者硬件和软件的结合来实现本发明。可以在一个计算机系统中以集中式的方式或者在不同的元件分散于几个互连的计算机系统的情况下以分布式的方式来实现本发明。适于实现本文所描述的方法的任何类型的计算机系统或其它的装置都是适合的。硬件和软件的典型的结合可以是具有计算机程序的通用计算机系统,当加载和执行该计算机程序的时候,其控制计算机系统从而使得该计算机系统实现本文所描述的方法。还可以将本发明嵌入到计算机程序产品中,其包括能实现本文所描述的方法的全部特征,并且当加载到计算机系统的时候其能够实现这些方法。
在当前上下文中,术语“计算机程序”、“软件”、“应用”、其变型和/或组合,表示这样一组指令以任何语言、代码或符号的任何表达,即该组指令想要使得具有信息处理能力的系统直接地或者在下述其一或二者之后执行特定的功能a)转换成另一种语言、代码或符号;b)以不同材料的形式再现。例如,计算机程序可以包括、但不限于子例程、函数、过程、对象方法、对象实现、可执行应用、小应用程序、小服务程序、源代码、目标代码、共享库/动态负载库和/或设计用于在计算机系统上执行的其它指令序列。
术语“一”和“一个”,如本文所使用的,被定义为一个或多于一个。术语“多个”,如本文所使用的,被定义为两个或多于两个。术语“另一个”,如本文所使用的,被定义为至少第二个或更多。术语“包含”和/或“具有”,如本文所使用的,被定义为包括(即开放语言)。术语“连接”,如本文所使用的,尽管不一定直接连接,也不一定机械连接,但仍被定义为连接,即通过通信通道或路径或另一组件或系统进行通信链接。
可以以其它的形式实施本发明而不背离本发明的精神或实质属性。因此,当指出本发明的范围的时候,应当参考下面的权利要求,而不是前述的说明书。
权利要求
1.一种分析计算机程序中运行时存储器访问错误的方法,所述方法包括利用运行时分析代码插装所述计算机程序;检测所述已插装的计算机程序的运行时存储器访问错误;以及响应于检测所述运行时存储器访问错误,动态地设置监测点。
2.根据权利要求1的方法,所述检测步骤进一步包括为所述运行时存储器访问错误确定上下文信息;以及将所述上下文信息与用户指定的属性进行比较。
3.根据权利要求2的方法,所述动态地设置步骤进一步包括根据、至少部分地根据所述比较步骤选择性地设置所述监测点。
4.根据权利要求2的方法,其中,所述上下文信息包括一类检测到的运行时存储器访问错误并且所述属性包括用户指定类型的运行时存储器访问错误,所述比较步骤进一步包括将检测到的运行时存储器访问错误的类型与用户指定的运行时存储器访问错误的类型进行比较。
5.根据权利要求2的方法,其中,所述上下文信息包括用于检测到的运行时存储器访问错误的堆栈跟踪信息并且所述属性包括用户指定的堆栈跟踪信息,所述比较步骤进一步包括将用于检测到的运行时存储器访问错误的堆栈跟踪信息与用户指定的堆栈跟踪信息进行比较。
6.根据权利要求1的方法,其进一步包括选择性地重新启动所述具有启用的监测点的已插装的计算机程序。
7.根据权利要求1的方法,其进一步包括利用调试器来选择性地重新启动所述具有启用的监测点的已插装的计算机程序。
8.一种分析计算机程序中运行时存储器访问错误的方法,所述方法包括检测计算机程序中的运行时存储器访问错误;为所述运行时存储器访问错误确定上下文信息;将所述上下文信息与用户指定的属性进行比较;以及如果所述上下文信息与用户指定的属性匹配,则为所述计算机程序动态地设置监测点。
9.根据权利要求8的方法,其中,所述上下文信息包括一类检测到的运行时存储器访问错误并且所述属性指定了用户指定类型的运行时存储器访问错误,所述比较步骤进一步包括将检测到的运行时存储器访问错误的类型与用户指定的运行时存储器访问错误的类型进行比较。
10.根据权利要求8的方法,其中,所述上下文信息包括用于检测到的运行时存储器访问错误的堆栈跟踪信息并且所述属性指定了用户指定的堆栈跟踪信息,所述比较步骤进一步包括将用于所述检测到的运行时存储器访问错误的堆栈跟踪信息与所述用户指定的堆栈跟踪信息进行比较。
11.根据权利要求8的方法,其进一步包括选择性地重新启动具有启用的监测点的已插装的计算机程序。
12.根据权利要求8的方法,其进一步包括利用调试器来选择性地重新启动具有启用的监测点的已插装的计算机程序。
13.根据权利要求8的方法,其进一步包括利用运行时分析代码插装所述计算机程序。
14.一种包括用于实现前述方法权利要求中任何一项所述的方法的装置的系统。
全文摘要
一种分析计算机程序中运行时存储器访问错误的方法,该方法可以包括利用运行时分析代码插装所述计算机程序并且检测已插装的计算机程序的运行时存储器访问错误。响应于检测所述运行时存储器访问错误,该方法还可以包括动态地设置监测点。
文档编号G06F11/36GK1991785SQ20061014702
公开日2007年7月4日 申请日期2006年11月13日 优先权日2005年12月27日
发明者T·沃拉 申请人:国际商业机器公司