CN111602121A - 利用所应用的存储器区域生命期的比特精确跟踪分析 - Google Patents

利用所应用的存储器区域生命期的比特精确跟踪分析 Download PDF

Info

Publication number
CN111602121A
CN111602121A CN201880085906.4A CN201880085906A CN111602121A CN 111602121 A CN111602121 A CN 111602121A CN 201880085906 A CN201880085906 A CN 201880085906A CN 111602121 A CN111602121 A CN 111602121A
Authority
CN
China
Prior art keywords
memory
application
stack
stack location
location
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
CN201880085906.4A
Other languages
English (en)
Other versions
CN111602121B (zh
Inventor
H·加布里杰尔斯基
J·莫拉
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Microsoft Technology Licensing LLC
Original Assignee
Microsoft Technology Licensing LLC
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Microsoft Technology Licensing LLC filed Critical Microsoft Technology Licensing LLC
Publication of CN111602121A publication Critical patent/CN111602121A/zh
Application granted granted Critical
Publication of CN111602121B publication Critical patent/CN111602121B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/008Reliability or availability analysis
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/07Responding to the occurrence of a fault, e.g. fault tolerance
    • G06F11/0703Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation
    • G06F11/0706Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation the processing taking place on a specific hardware platform or in a specific software environment
    • G06F11/073Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation the processing taking place on a specific hardware platform or in a specific software environment in a memory management context, e.g. virtual memory or cache management
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F3/00Input arrangements for transferring data to be processed into a form capable of being handled by the computer; Output arrangements for transferring data from processing unit to output unit, e.g. interface arrangements
    • G06F3/06Digital input from, or digital output to, record carriers, e.g. RAID, emulated record carriers or networked record carriers
    • G06F3/0601Interfaces specially adapted for storage systems
    • G06F3/0628Interfaces specially adapted for storage systems making use of a particular technique
    • G06F3/0653Monitoring storage devices or systems
    • GPHYSICS
    • G11INFORMATION STORAGE
    • G11CSTATIC STORES
    • G11C16/00Erasable programmable read-only memories
    • G11C16/02Erasable programmable read-only memories electrically programmable
    • G11C16/06Auxiliary circuits, e.g. for writing into memory
    • G11C16/34Determination of programming status, e.g. threshold voltage, overprogramming or underprogramming, retention
    • G11C16/349Arrangements for evaluating degradation, retention or wearout, e.g. by counting erase cycles

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Quality & Reliability (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Computer Hardware Design (AREA)
  • Human Computer Interaction (AREA)
  • Debugging And Monitoring (AREA)

Abstract

基于应用的执行的可重放跟踪来检测和提供在应用的先前执行期间的非故障存储器访问的通知。实施例包括从应用的先前执行的可重放跟踪重放应用的先前执行的(多个)部分,同时跟踪由应用使用的(多个)存储器区域的生命期。基于跟踪存储器区域的生命期,检测在应用的先前执行期间由应用进行的非故障但不适当的(多个)存储器访问。在用户界面处和/或向软件组件提供关于这些非故障但不适当的(多个)存储器访问的通知。

Description

利用所应用的存储器区域生命期的比特精确跟踪分析
背景技术
常见的编程错误类别包括导致线程执行超出所分配存储器的存储器读取和/或写入操作(即,越界存储器访问)的错误。例如,一类编程错误是由存储器分配函数保留的存储器使用不当引起的。很多编程语言和/或库提供使得进程能够请求指定大小的存储器块的分配(例如,从可用存储器池,诸如堆)的一个或多个存储器分配函数调用(例如,C标准库中的malloc())、以及用于稍后重新分配该存储器的一个或多个存储器重新分配函数调用(例如,C标准库中的free())。通常,存储器分配函数从存储器池中定位和保留指定大小的连续的可用存储器块,并且在该块的开始返回指向存储器地址的指针。然后,线程可以基于距该指针的整数偏移来访问该保留的存储器块中的存储器位置。但是,很多编程语言可能很少或根本没有提供保护以防止线程实际访问保留块之外的存储器地址。如果线程向其保留块之外的存储器写入,则存在可能会不适当地覆盖有效的存储器值(例如,作为不同数据结构的部分和/或由另一线程使用的值)的风险。如果线程从其保留块之外的存储器中读取数据,则存在以下风险:可能读取意外数据(例如,来自不同数据结构和/或由另一线程写入的数据),读取未定义数据(例如,尚未被写入的存储器位置),或通过尝试访问不可访问存储器而导致访问冲突。
另一类常见的编程错误涉及导致线程在其有效性状态已经转变之后从存储器位置不适当地访问存储器的错误。例如,在很多计算机架构中,每个执行线程与称为“堆栈”的存储器区域相关联,该存储器区域在线程执行时存储临时本地信息。通常,每次函数被调用时,新的“堆栈框架”被添加到堆栈,并且在该函数终止时,该函数的堆栈框架从堆栈中移除。因此,堆栈在线程的执行期间动态地增长和收缩。每个堆栈框架会为函数的任何局部变量分配一个或多个存储器位置。这些存储器位置在函数执行时对于要使用的函数是“有效”的,但是在从堆栈中移除堆栈框架时对于要使用的任何函数是“无效”的。但是,即使堆栈框架已经从堆栈中移除(并且存储器位置已经变为无效),编码错误也可能导致对这些存储器位置的访问(读取和/或写入)。编程语言可能很少或根本没有提供保护以防止线程执行这些类型的基于堆栈的不适当的存储器访问。
这些类型的不适当的存储器访问可能特别难以定位和调试,因为它们实际上并不会在所有情况下都导致线程执行失败(故障)。如本文中使用的,引起故障的不适当的存储器访问是导致错误(例如,分段故障、访问冲突、未处理异常等)的访问,该错误导致线程的执行终止。这与适当的存储器访问相反,适当的存储器访问可能会导致通常称为“故障”(例如,页面故障)的事件,但是该事件实际上并不会错误地导致线程的执行终止。导致执行失败的错误可能在读取和依赖无效数据并且无效数据以某种方式导致执行“失败”时发生,或者在线程访问不允许访问或实际上不对应于合法存储器地址的存储器位置时发生。但是,超出所分配存储器的每次访问或对不再有效的存储器的每次访问都不一定会导致发生这些故障之一。例如,即使存储器访问可能不适当,它也可能读取有效数据(例如,线程先前写入的并且随后未被覆盖的数据),它可能是对线程被允许访问的存储器位置的访问,等等。
因此,出于本说明书的目的,术语“非故障”包括非错误的页面故障(诸如在大多数虚拟存储系统中用于允许临时“调出”存储器的页面故障)。类似地,术语“执行故障”(或其变体)通过排除非错误页面故障而更具限制性,并且旨在涵盖影响继续执行能力的故障(例如,访问冲突、分段故障、未处理异常等)。当然,术语“非执行故障”(或其变体)因此表示“执行故障”的反义词。
已经进行了先前的尝试来定位不适当的非故障存储器访问,但是它们不能检测所有实例,并且可能不利地改变程序执行状态。例如,一种尝试是使用调试程序来设置写断点以观察每个存储器写入,并且手动确定它是否在范围之内。但是,这很繁琐,并且在生产软件上也不可行。另一尝试是在程序出现故障之后解析存储器转储,以便尝试确定其原因。然而,这也很繁琐并且丢失状态。
其他先前尝试试图鼓励这些不适当的存储器访问中的一些出错。例如,一些工具在邻近所分配缓冲区的线程的地址空间内(例如,在堆内和/或在线程的堆栈空间之后)插入(多个)存储器页面,其中这些页面包含作为非法地址或该线程不允许访问的存储器地址。如果线程试图读取的内容超出所分配缓冲区并且进入这些“保护页面”之一,则会发生故障(例如,分段故障、访问冲突等)。然而,保护页面将仅能够检测第一类编程错误(即,读取超出所分配缓冲区),并且即使那样,保护页面也不能用于检测超出所分配缓冲区的所有访问。例如,在所分配缓冲区与保护页面之间可能仍然存在允许线程访问的存储器位置。这些存储器位置可能包括用于存储器对准的填充、其他所分配缓冲区等。尝试鼓励不适当的存储器访问错误的另一种先前尝试涉及使用预定义的任意值来预填充堆栈位置,以增加在读取未初始化的值的情况下导致错误的可能性。但是,预填充堆栈位置会带来附加的执行开销,并且无法捕获所有未初始化的值的使用。
此外,调试技术的最新发展已经包围了通常被称为“时间旅行”跟踪(TTT)的内容。通常,TTT涉及记录应用程序的一个或多个线程的实时执行的比特精确跟踪,从而使得能够在稍后的时间完整且精确地重放这些线程的先前执行。因此,TTT能够创建“时间旅行”调试程序,该调试程序能够在正反两个方向上忠实地重放一个或多个线程的执行并且执行其他类型的丰富分析。
发明内容
本文中描述的至少一些实施例应用时间行进跟踪的比特精确跟踪分析以跟踪线程在其先前执行期间实际使用的存储器区域的生命期。特别地,实施例使用所跟踪的存储器区域的生命期来标识线程何时对所分配存储器之外的(多个)存储器位置进行了非故障但不适当的(多个)访问和/或当存储器位置在有效与无效之间转变时线程何时对(多个)存储器位置进行了非故障但不适当的(多个)访问。这样,实施例可以标识否则难以发现的编程错误,这些错误导致这些非故障存储器访问在线程的先前执行期间发生。
一些实施例基于应用的执行的可重放跟踪来检测在应用的先前执行期间的非故障存储器访问。这些实施例包括方法、系统和计算机程序产品,该方法、系统和计算机程序产品从应用的执行的可重放跟踪重放应用的先前执行的一个或多个部分,同时跟踪由应用使用的存储器区域的生命期。基于跟踪存储器区域的生命期来检测在应用的先前执行期间由应用进行的一个或多个非故障存储器访问,并且向用户界面或其他组件提供关于一个或多个非故障存储器访问的通知。
可以检测的非故障存储器访问的一个示例包括:由应用进行的超出请求大小的存储器(例如,超出所分配缓冲区)的存储器访问。另一示例包括在至少以下各项的有序序列之后,由应用进行的从堆栈位置的读取:(i)在堆栈位置有效的同时对堆栈位置的写入;(ii)使堆栈位置无效;以及(iii)使堆栈位置有效,并且其中在使堆栈位置有效与读取之间,堆栈位置未被写入。又一示例包括在至少以下各项的有序序列之后,由应用进行的从堆栈位置的读取:(i)使堆栈位置有效,(ii)使堆栈位置无效,以及(iii)在堆栈位置无效的同时对堆栈位置写入,并且其中在在堆栈位置无效的同时对堆栈位置写入与读取之间,在堆栈位置为有效堆栈位置的同时堆栈位置未被写入。又一示例包括在至少以下各项的有序序列之后,由应用对堆栈位置的写入:(i)使堆栈位置有效,以及(ii)使堆栈位置无效,并且其中堆栈位置在写入时无效。
提供本“发明内容”以便以简化的形式介绍一些概念,这些概念将在下面的“具体实施方式”中进一步描述。本“发明内容”既不旨在标识所要求保护的主题的关键特征或必要特征,也不旨在用于帮助确定所要求保护的主题的范围。
附图说明
为了描述获取可以本发明的上述及其他优点和特征的方式,将通过参考在附图中示出的本发明的具体实施例来对以上简要描述的本发明进行更具体的描述。应当理解,这些附图仅描绘了本发明的典型实施例,因此不应当被认为是对本发明的范围的限制,将通过使用附图以附加的特征和细节来描述和解释本发明,在附图中:
图1示出了促进应用时间行进跟踪的比特精确跟踪分析以便跟踪线程在其先前执行期间实际使用的存储器区域的生命期的示例计算机系统;
图2示出了示例存储器生命期组件;
图3A示出了可能由线程对分配函数的调用导致的示例存储器分配;
图3B示出了可能由线程对分配函数(包括保护页面)的调用导致的示例存储器分配;
图4示出了可能由线程对重新分配函数的调用导致的示例存储器分配;
图5A示出了在线程的执行期间可能发生的第一组堆栈状态的示例;
图5B示出了在线程的执行期间可能发生的第二组堆栈状态的示例;
图6A示出了示例“struct”原语定义;
图6B示出了可以基于图6A的“struct”原语定义而保留的示例存储器分配;以及
图7示出了用于基于应用的执行的可重放跟踪来检测在应用的先前执行期间的非故障存储器访问的示例方法的流程图。
具体实施方式
本文中描述的至少一些实施例应用时间行进跟踪的比特精确跟踪分析以跟踪线程在其先前执行期间实际使用的存储器区域的生命期。特别地,实施例使用所跟踪的存储器区域的生命期来标识线程何时对所分配存储器之外的(多个)存储器位置进行了非故障但不适当的(多个)访问和/或当存储器位置在有效与无效之间转变时线程何时对(多个)存储器位置进行了非故障但不适当的(多个)访问。这样,实施例可以标识否则难以发现的编程错误,这些错误导致这些非故障存储器访问在线程的先前执行期间发生。
图1示出了促进应用时间行进跟踪的比特精确跟踪分析以便跟踪线程在其先前执行期间实际使用的存储器区域的生命期的示例计算机系统100。这使得计算机系统100能够在线程的该先前执行期间定位非故障但不适当的存储器访问的发生,包括标识引起不适当的存储器访问的程序代码。如图所示,实施例可以包括或利用包括计算机硬件的专用或通用计算机系统100,诸如例如通过一个或多个总线105通信互连的一个或多个处理器101、系统存储器102、输入/输出硬件103(例如,用户输入硬件,诸如键盘、鼠标、触摸屏、触控板等;网络硬件;显示硬件;等)、一个或多个存储设备104等。
在本发明的范围内的实施例包括用于承载或存储计算机可执行指令和/或数据结构的物理和其他计算机可读介质。这样的计算机可读介质可以是计算机系统100可以访问的任何可用介质。存储计算机可执行指令和/或数据结构的计算机可读介质是计算机存储设备。携带计算机可执行指令和/或数据结构的计算机可读介质是传输介质。因此,作为示例而非限制,本发明的实施例可以包括至少两种明显不同种类的计算机可读介质:计算机存储设备和传输介质。
计算机存储设备是存储计算机可执行指令和/或数据结构的物理硬件设备。计算机存储设备包括各种计算机硬件,诸如RAM、ROM、EEPROM、固态驱动器(“SSD”)、闪存、相变存储器(“PCM”)、光盘存储、磁盘存储或其他磁性存储设备、或者可以用于以计算机可执行指令或数据结构的形式存储程序代码并且可以由计算机系统100访问和执行并且由一个或多个处理器101执行以实现本发明的公开功能的任何其他(多个)硬件设备。因此,例如,计算机存储设备可以包括所示出的系统存储器102、可以存储计算机可执行指令和/或数据结构的所示出的(多个)存储设备104、或者一个或多个处理器上101的诸如高速缓存等其他存储装置。
传输介质可以包括可以用于以计算机可执行指令或数据结构的形式携带程序代码并且可以由计算机系统100访问的网络和/或数据链路。“网络”被定义为使得能够在计算机系统和/或模块和/或其他电子设备之间传输电子数据的一个或多个数据链路。当信息通过网络或另一通信连接(硬连线、无线、或硬连线或无线的组合)传输或提供给计算机系统时,计算机系统可以将连接视为传输介质。上述的组合也应当被包括在计算机可读介质的范围内。例如,输入/输出硬件103可以包括连接可以用于以计算机可执行指令或数据结构的形式携带程序代码的网络和/或数据链路的硬件(例如,网络接口模块(例如,“NIC”))。
此外,在到达各种计算机系统组件时,计算机可执行指令或数据结构形式的程序代码可以从传输介质自动传输到计算机存储设备(反之亦然)。例如,通过网络或数据链路接收的计算机可执行指令或数据结构可以缓冲在NIC(例如,输入/输出硬件103)内的RAM中,并且然后最终传输到系统存储器102和/或计算机系统100处的易失性较小的计算机存储设备(例如,(多个)存储设备104)。因此,应当理解,计算机存储设备可以被包括在也(或甚至主要)利用传输介质的计算机系统组件中。
例如,计算机可执行指令包括当在(多个)处理器101处执行时引起计算机系统100执行特定功能或功能组的指令和数据。计算机可执行指令可以是例如二进制、中间格式指令(诸如汇编语言)、或甚至源代码。
本领域技术人员将理解,本发明可以在具有很多类型的计算机系统配置的网络计算环境中实践,包括个人计算机、台式计算机、膝上型计算机、消息处理器、手持式设备、多处理器系统、基于微处理器或可编程的消费电子产品、网络PC、小型计算机、大型计算机、移动电话、PDA、平板电脑、寻呼机、路由器、交换机等。本发明也可以在分布式系统环境中实践,在分布式系统环境中,通过网络链接(通过硬连线数据链路、无线数据链路、或通过硬连线和无线数据链路的组合)的本地和远程计算机系统均执行任务。这样,在分布式系统环境中,计算机系统可以包括多个组成计算机系统。在分布式系统环境中,程序模块可以位于本地和远程存储设备两者中。
本领域技术人员还将意识到,本发明可以在云计算环境中实践。云计算环境可以是分布式的,尽管这不是必需的。当是分布式时,云计算环境可以在组织内在国际上分布和/或具有跨多个组织而拥有的组件。在本说明书和所附权利要求中,“云计算”被定义为用于使得能够对可配置计算资源(例如,网络、服务器、存储、应用和服务)的共享池进行按需网络访问的模型。“云计算”的定义不限于在适当部署时可以从这样的模型中获取的其他众多优势中的任何一种。
云计算模型可以由各种特征组成,诸如按需自助服务、广泛的网络访问、资源池、快速弹性、测量的服务等。云计算模型也可以采用各种服务模型的形式,诸如例如软件即服务(“SaaS”)、平台即服务(“PaaS”)和基础设施即服务(“IaaS”)。云计算模型也可以使用诸如私有云、社区云、公共云、混合云等不同部署模型来部署。
诸如云计算环境等一些实施例可以包括一种系统,该系统包括一个或多个主机,每个主机能够运行一个或多个虚拟机。在操作期间,虚拟机模拟操作计算系统,从而支持操作系统,也许还支持一个或多个其他应用。在一些实施例中,每个主机包括管理程序,该管理程序使用从虚拟机的角度抽象的物理资源来模拟虚拟机的虚拟资源。管理程序还可以在虚拟机之间提供适当的隔离。因此,从任何给定虚拟机的角度来看,管理程序提供虚拟机正在与物理资源接口的错觉,即使该虚拟机仅与物理资源的外观(例如,虚拟资源)交互。物理资源的示例包括处理能力、存储器、磁盘空间、网络带宽、媒体驱动器等。
如图所示,(多个)存储设备104可以存储表示可执行代码的计算机可执行指令和/或数据结构,诸如例如一个或多个应用程序106(例如,用户空间应用、操作系统内核、管理程序等)、和调试程序107。通常,一个或多个应用106可能会受到调试程序107的调试。当可执行代码在(多个)处理器101处被执行时,系统存储器102可以存储对应的运行时数据,诸如运行时数据结构、计算机可执行指令等。(多个)存储设备104还可以存储可以由(多个)应用106和/或调试程序107创建和/或使用的任何类型的数据,诸如由调试程序107创建和/或使用的一个或多个跟踪文件108。
调试程序107可以包括用于结合(多个)应用106的执行来生成、重放和/或分析(多个)跟踪文件108的各种组件(例如,107a-107f)中的一个或多个。组件107a-107f的特定标识和布置可以根据调试程序107的特定配置/部署而变化。例如,如果调试程序107包括记录组件107a,则其包括用于记录应用106的执行的比特精确跟踪并且将跟踪数据存储在(多个)跟踪文件108中的功能。如果调试程序107包括重放组件107b,则其包括用于基于存储在(多个)跟踪文件108中的跟踪数据来重放应用106的比特精确跟踪的功能,从而精确地再现该应用的先前执行。
值得注意的是,跟踪记录和跟踪回复不必在同一计算机系统上发生。因此,例如,调试程序107的有限实现(例如,包括组件107a-107f的子集,诸如仅记录组件107a)可以部署在生产计算机系统处以将生产应用的执行的跟踪记录到(多个)跟踪文件中108中,并且调试程序107的更广泛的实现(例如,包括所有组件107a-107f)可以部署在开发计算机系统100处以用于基于所记录的(多个)跟踪文件108来执行生产应用的执行的重放/调试。
如所提及的,记录组件107a可用于将应用106的执行的比特精确跟踪记录到跟踪文件108中。存在比特精确跟踪记录的不同实现,并且本文中的用于应用时间行进跟踪的比特精确跟踪分析以便跟踪在线程的先前执行期间由线程实际使用的存储器区域的生命期的实施例并不限于特定的比特精确跟踪记录机制。
作为示例,记录组件107a的实现可以记录足够的数据以能够在应用的(多个)线程的执行期间将信息的涌入再现到(多个)处理器101的高速缓存中。执行该操作的第一种方法是通过记录由线程引起的所有高速缓存未命中和未高速缓存读取(即,从硬件组件和不可高速缓存的存储器中的读取)、以及在执行期间每个数据被引入高速缓存的时间(例如,使用所执行的指令数或某个其他计数器)来记录引入高速缓存中用于线程的执行的所有数据。第二种方法可以仅跟踪和记录(多个)处理器101中的每个处理单元“消耗”的高速缓存行(例如,当处理单元知道其当前值时,可以认为该处理单元“消耗”了高速缓存行)。处理单元可能已经“消耗”了高速缓存行,因为它是写入高速缓存行的当前值的高速缓存行,或者因为处理单元已经对高速缓存行执行了读取。第二种方法可以涉及扩展处理器的高速缓存(例如,通过每个高速缓存行添加一个或多个比特),从而使得处理器101能够为每个高速缓存行标识消耗高速缓存行的一个或多个处理单元。第三种方法可以利用处理器的高速缓存一致性协议来确定要在(多个)文件108中记录的“消耗的”高速缓存行的子集,并且仍然能够重现共享高速缓存的活动。存在其他方法,每种方法都有其自身的优点和缺点(例如,跟踪记录开销、跟踪文件大小、多线程函数等)。
不管记录组件107a所采用的记录策略如何,一些实现可以将一个或多个跟踪数据流记录到(多个)跟踪文件108中。在一些实现中,每个跟踪数据流对应于不同的线程。例如,(多个)跟踪文件108可以包括用于执行应用106的线程的每个单独的处理单元(例如,每个逻辑处理器核心)的单独的跟踪数据流。在其他实现中,每个跟踪数据流对应于多个线程。例如,(多个)跟踪文件108可以包括用于相关处理单元的单独的跟踪数据流(例如,每个处理器插槽的数据流)。在一些实现中,独立于每个其他处理单元的数据分组来记录每个独立处理单元的数据分组,从而使得能够独立地重放在不同处理单元处执行的不同线程。但是,(多个)跟踪文件108可以包括一些信息(无论是表达的还是固有的),这些信息提供不同线程之间的部分顺序。例如,一些实施例可以使用单调递增的数字来记录所有线程中某些“可排序”事件(例如,对共享存储器的访问)的顺序。
重放组件107b消耗(多个)跟踪文件108以重放所记录的(多个)应用106的执行。例如,重放组件107b可以向被跟踪的应用的代码提供在适当的时间从(多个)跟踪文件108获取的记录值,以引起该代码以与其在跟踪记录期间相同的方式执行。然后可以将在重放期间获取的数据用于呈现执行状态(例如,使用用户界面组件107f)和/或作为跟踪分析的基础。
如果包括编索引组件107c,则编索引组件107c处理(多个)跟踪文件108,以便生成针对性能重放、搜索、查询等而优化的跟踪。例如,在记录期间,记录组件107a可以以强调低跟踪开销和/或小跟踪文件大小的方式记录跟踪数据流,但对于性能重放或查询可能不是最佳的。编索引组件107c然后可以处理这些记录的跟踪,以便产生新的优化的跟踪数据流、和/或注释所记录的跟踪数据流的元数据,以便重放。优化的示例可以包括例如以规则的间隔在诸如函数边界或插入等感兴趣位置处插入关键框架(这使得能够从关键框架开始发起重放);插入存储器快照,以总结在跟踪部分期间遇到的存储器位置和/或值;插入反向查找数据结构以快速标识跟踪属性;等等。编索引可以包括对跟踪的静态分析,和/或通过重放组件107b执行跟踪重放以获取相关数据。
如果包括查询组件107d,则查询组件107d可以用于在跟踪文件上执行搜索(例如,关键字和/或自然语言短语)以产生排名结果,和/或在跟踪文件上执行查询(例如,结构化表达式)。这些搜索/查询可以在调试过程中使用,以定位被跟踪应用的执行期间各种有趣事件的发生,诸如所调用的函数、到内核模式的转变、遇到的异常、所访问的存储器地址、读取的存储器值等。
用户界面组件107e提供了用于以下操作的用户界面:通过记录组件107a执行跟踪记录,通过编索引组件107c执行跟踪索引,和/或通过重放组件107b和可能的其他组件(例如,107d-107f)执行跟踪重放/调试。在一些实施例中,用户界面组件107f提供用于以下操作的用户界面:促进用户与调试程序107的交互,诸如浏览应用代码,在正反方向上逐步进行代码执行,设置正反观察点/断点,用于使用查询组件107d执行搜索/查询,使用编索引组件107c发起和配置索引,等等。
存储器生命期组件107f执行对(多个)跟踪文件108的分析,以跟踪在线程的先前执行期间由线程实际使用的存储器区域的生命期。这使得调试程序能够标识(多个)线程何时进行了在活动存储器生命期之外的非故障但不适当的存储器访问,诸如访问在所分配存储器之外的存储器位置,当存储器位置在有效与无效之间转变时不适当地访问存储器位置,等等。因此,存储器生命期组件107f可以标识否则难以发现的编程错误,这些错误导致这些非故障存储器访问在线程的先前执行期间发生。
在一些实施例中,存储器生命期组件107f可以与调试程序107的其他组件协同工作。例如,存储器生命期组件107f可以通过重放组件107c发起跟踪部分的重放以便观察存储器访问行为。可能与编索引组件107c协作以将存储器生命期索引信息添加到(多个)跟踪文件108,可能由查询组件107d用来提供存储器生命期信息作为搜索/查询的结果,等等。
为了促进对存储器生命期跟踪的进一步理解,图2进一步示出了详细的存储器生命期组件200,该存储器生命期组件200可以对应于图1的存储器生命期组件107f。存储器生命期组件200的示例子组件可以包括配对组件201、有效性组件202、检测组件203和通知组件204。
通常,配对组件201将观察到的存储器“分配”与观察到的存储器“解除分配”配对,以便标识受分配/解除分配影响的(多个)存储器位置的(多个)生命期,并且通过扩展来标识对这些存储器位置的访问给定存储器访问在给定时间是否是适当的。“分配”或“解除分配”的特定定义可以根据上下文而变化。例如,“分配”可以对应于对分配函数的快速调用(例如,C标准库中的malloc()函数、C++中的new关键字等),并且“解除分配”可以对应于对解除分配函数的快速调用(例如,C标准库中的free()函数,C++中的delete关键字等)。在另一示例中,“分配”可以对应于向线程的堆栈添加堆栈框架(包括针对局部变量的空间分配),而“解除分配”可以对应于移除该堆栈框架(例如,在函数完成时)。这样,配对组件201可以能够理解与存储器相关的函数的广泛集合,以便配对分配和解除分配。
在一些实施例中,配对组件201被扩展为跟踪相关分配和解除分配函数的三元组。例如,C标准库提供了realloc()函数,该函数用于改变先前通过调用malloc()而分配的所分配存储器大小。因此,配对组件201可以利用三元组来跟踪存储器区域生命期,诸如对malloc()的调用,然后是对realloc()的调用,然后是对free()的调用。在一些实施例中,配对组件201可以将对realloc()的调用视为对malloc()的调用以获取新请求的大小的存储器区域,然后是对free()的调用以重新分配先前分配的存储器,并且然后是仅由对malloc()的最初调用而分配的字节的重新初始化。该重新初始化在稍后结合图4进行说明。其他编程语言提供类似的重新分配函数,并且因此,本文中的实施例不限于C编程语言。例如,某些被管理编程语言使用的运行时包括压缩垃圾收集器(GC),GC可以被视为基于重新分配函数来进行操作,并且配对组件201的实现可以跟踪受这些GC影响的存储器区域的生命期(例如,通过跟踪这些重新分配)。
使用由配对组件201标识的生命期信息,有效性组件202可以在线程的先前执行期间在给定时间应用三个分类相关存储器位置之一:(i)该位置无效(即,该位置在给定时间不对应于任何活动生命期),(ii)该位置有效(即,该位置在给定时间对应于活动生命期,但其内容在给定时间未定义),或者(iii)该位置在给定时间有效,并且在该给定时间具有有效(即,定义的)内容。在执行线程时,给定存储器位置可能已经在执行中的各个点处在这些状态之间转变。有效性组件202可以重放(多个)跟踪文件108以标识这些转变。
当该位置对于有效生命期无效时或当存储器位置对于有效生命期有效但对于有效生命期具有未定义的内容时,检测组件203检测线程何时对该存储器位置执行了非故障存储器访问。这些可能是不适当的存储器访问,即使它们没有引起故障。这些访问类型的示例将在后面给出。
通知组件204提供关于由检测组件203标识的非故障存储器访问的通知。可以向任何适当的组件给出通知,诸如用户界面组件107e、编索引组件107c、查询组件107d、另一计算机系统处的调试程序107、甚至该计算机系统或另一计算机系统处除调试程序107以外的应用。
在一个非限制性实例中,有效性组件202可以将存储器断点放置在所有无效存储器区域和/或存储器位置上。然后可以在分配和解除分配存储器时通过配对组件201和有效性组件202的协作来更新断点。如果在重放期间遇到这些断点之一,则检测组件203可以检测到无效的存储器访问,并且通知通知组件204。
值得注意的是,由于存储器生命期组件200在比特精确执行跟踪上操作,因此它可以能够标识存储器分配的范围,并且从而标识非故障的不适当的存储器访问,而无需编译器符号。即使源代码对于调试程序107不可用(即,当仅编译的二进制文件可用时),这也使得能够执行存储器生命期分析。例如,对于基于非堆栈的分配,比特精确跟踪可以提供足够的信息来标识所使用的分配和解除分配函数(例如,基于有关库导出的信息)。另一方面,对于基于堆栈的分配,如果每个局部变量使用一条指令来分配堆栈框架,则调试程序107可以基于代码执行哪个直接堆栈存储器访问来标识变量。例如,由于局部变量被访问作为距已知指针的偏移(例如,作为距堆栈指针或框架指针的偏移),因此可以通过这些访问来定位它们。还可以间接标识对struct或函数的访问,例如,将其标识为地址的偏移,该地址本身是经由距堆栈指针或框架指针的偏移而获取的。但是,如果使用单个指令来执行堆栈框架的分配,则可以使用其他启发式方法来标识这些分配。然而,存储器生命期组件200可以利用符号(如果有的话)来提供诸如函数名称、变量名称等附加信息;提供更精确的结果;和/或减少所执行的启发式方法的数量或复杂性。
与查询组件107d结合使用,存储器生命期组件200可以提供丰富的功能以用于定位导致非故障但不适当的存储器访问的编码错误。例如,可以构造搜索或查询以标识每个非故障访问以及导致每种错误发生的代码。
图3A-6示出了如何将比特精确跟踪的生命期分析用于标识非故障和不适当的存储器访问的一些特定示例。最初,图3A和3B示出了一个示例,其中当存储器访问超出所分配缓冲区(诸如由分配函数从堆存储器分配的缓冲区)时,可能会发生非故障存储器访问。这些非故障存储器访问使用先前的调试工具很难标识,但是作为比特精确跟踪的分析的一部分,可以使用存储器生命期组件200容易地标识。
特别地,图3A示出了存储器分配300,该存储器分配300可能是由线程对七个字节的块的请求而导致的(例如,使用C标准库对malloc(7)的调用或另一种编程语言中的类似调用)。特别地,存储器分配300示出的存储器范围包括从存储器地址301开始的七个字节。这样,对分配函数的调用可能会将存储器地址301返回给线程,然后线程可以使用距该地址的整数偏移来访问所分配存储器(字节1-7)。例如,图3A示出了将数据A-G写入这七个字节。
除了该七个字节的分配之外,图3A还示出了存储器分配300还可以包括第八“填充”字节302。分配函数可能已经保留了该填充字节302以促进存储器对准(例如,8或16字节存储器对准),以便根据物理存储器和/或存储器总线的特性加快存储器访问速度。从技术上讲,该填充字节302未分配给请求七字节分配的线程(因此,它不是分配的生命期的一部分)。但是,由于在存储器分配300处于活动时,分配函数通常不会将该字节用于任何其他请求的存储器分配,因此线程可能会错误地使用该第八字节来存储和读取数据而不会引起任何错误。例如,图3A示出了线程未适当地将值(即,H)写入填充字节302。
即使分配函数将非映射的保护页面与存储器分配300相邻放置,线程也可能不适当地使用该第八字节来存储和读取数据而不会引起任何错误。例如,图3B描绘了存储器分配300',该存储器分配300'对应于图3A的存储器分配300,但是包括保护303。尽管存在保护303,但是存储器分配300'仍然包括填充字节302',该填充字节302'可以被线程使用而不会引起访问冲突。
存储器生命期组件200可以通过确定在访问时填充字节302/302'的存储器位置是无效的来标识对填充字节302/302'的这些不适当访问(例如,使用有效性组件202)。该位置无效,因为它不是由配对组件201确定的任何有效生命期的一部分。
尽管在图3A的特定情况下在访问该八个字节时可能适当地执行线程,但是线程对存储器的越界使用可能会导致很难重现的间歇性(甚至是随机的)执行错误/故障,因为填充量可能并不总是相同和/或越界存储器访问的程度可能并不总是相同。例如,假定对malloc()的调用中的所请求的缓冲区大小基于变量。在图3A的情况下,该变量的值为7,并且因此一个字节的填充被添加到所分配缓冲区中。但是,如果该变量具有不同的值,则填充的大小可能更大(例如,如果变量的值在1到6之间),或者甚至填充可能被消除(例如,如果变量的值是8、16等)。填充量也可能因以下各项而异:软件环境(例如,所使用的编译器或编译器设置;所使用的操作系统、操作系统版本或操作系统设置;所使用的库或库版本;等)、编译程序的硬件环境、所分配缓冲区与其他缓冲区的相对对准(例如,先前存储器分配的确切顺序和大小)等。此外,距用于存储器访问的存储器分配的基地址(例如,存储器地址301)的偏移可以基于变量,从而导致关于存储器访问是否越界的可变性和/或越界存储器访问的程度(即,在实际访问所分配缓冲区之后有多少字节)。因此,取决于填充的可变性和(多个)越界存储器访问的程度,实际上导致错误/故障的确切执行状态可能很少且难以重现,从而导致(多个)编码错误,导致使用传统技术很难定位越界访问。
如果线程执行重新分配,则可能会导致其他复杂情况。例如,图4示出了存储器分配400,存储器分配400可能是由线程基于指针301调用14字节的重新分配而导致的(例如,使用C标准库使用调用realloc()或另一种编程语言中的类似函数)。在大多数情况下,存储器分配400将由存储器中与分配300不同的部分组成。这样,指向存储器分配400的起始存储器地址的指针401通常将指向与指针301不同的地址。因为这是不同的存储器块,重新分配函数通常会将存储器分配300的内容复制到存储器分配400,但仅复制由原始分配函数实际分配的地址。因此,如图4所示,通常不会将来自填充字节302的值H复制到存储器分配400。因此,如果线程依赖于存储器分配400的字节8处的内容,则它可能会读取除H以外的值。通过检测将值H写入填充字节302/302'的存储器访问是不适当的,存储器生命期组件还可以确定从存储器分配400的字节8中进行的读取读取未定义数据。如图4进一步所示,存储器分配400还可以包括填充字节402以确保字节对准。因此,存储器分配400还包括线程可以在所所分配缓冲区之外写入和/或读取而不发生故障的潜在位置。
在一些实施例中,存储器生命期200组件可以检测超出所分配缓冲区的其他类型的访问。例如,某些分配函数可以使用在所分配缓冲区之前和/或之后的存储器作为页眉或页脚以存储有关分配的簿记信息。存储器生命期200组件可以使用有关这些分配函数如何工作的知识(例如,可以调用它们的不同方式、以及如何根据调用类型来处理标头/页脚)来进一步标识作为页眉/页脚的部分的任何存储器位置。然后,存储器生命期200组件可以将对这些页眉/页脚的存储器访问视为无效。
虽然图3A、3B和4专注于标识缓冲区分配周围的不适当的存储器访问(诸如来自堆),但是图5A和5B示出了可以作为比特精确跟踪的分析的一部分使用存储器生命期组件200轻松地标识的不适当的堆栈存储器访问的示例。例如,图5A示出了在线程的执行期间可能发生的几个堆栈状态500a-500d。最初,在状态500a,线程的堆栈包括堆栈框架501和指向堆栈中的最后的条目的堆栈指针502a。该堆栈框架501之下是在状态500a下对于堆栈框架501的生命期无效的存储器位置。
接下来,在状态500b,添加新的堆栈框架503,而堆栈指针502b现在指向堆栈框架503中的最后的条目。例如,由于线程调用函数,因此可能已经添加了堆栈框架503。堆栈框架503包括四个存储器位置,存储器位置包含内容A、B、C和D;这些存储器位置可能在创建堆栈框架503时被分配用于所调用的函数的局部变量。这些值可以在分配之后由函数写入。这些位置在创建堆栈框架时变为有效,因此写入这些值的存储器访问有效,因为它们发生在堆栈框架503的生命期内。
接下来,在状态500c,移除堆栈框架503,并且堆栈指针502c再次指向堆栈框架501中的最后的条目。例如,由于创建堆栈框架503的函数完成,堆栈框架503可能已经被移除。由于已经移除堆栈框架503,因此先前作为堆栈框架的部分的存储器位置现在无效,并且堆栈框架的生命期已经结束。但是,如图所示,由该函数写入堆栈名503的值可能仍然存在于这些存储器位置。
最后,在状态500d,添加另一堆栈框架504,现在堆栈指针502d指向堆栈框架504中的最后的条目。例如,由于线程再次调用相同的函数,可能已经添加了堆栈框架504。在堆栈框架504中,四个存储器位置再次变为有效位置。但是,在执行中的这一点,对函数的新调用未写入这些存储器位置中的任何一个。因此,它们是有效的存储器位置,但它们包含有关堆栈框架504生命期的未定义值。
然而,如果存在编码错误,则在当前函数写入线程之前,线程可能会从这些存储器位置中的一个或多个读取。因此,举例来说,如果线程读取第一位置(如星号所示),它将读取由该函数的先前实例放置在该位置的值A。该线程将从有效的存储器位置读取,但是就堆栈框架504的生命期而言,它将读取无效数据。在很多情况下,即使读取不适当,该函数实际上也可以无故障地执行。然而,由于跟踪堆栈框架503和/或504的生命期,存储器生命期组件200可以检测到该无效存储器访问。
图5B示出了在线程执行期间可能发生的另一组堆栈状态500e-500f。最初,在状态500e,线程的堆栈包括堆栈框架501和指向堆栈中的最后的条目的堆栈指针502e。该堆栈框架501之下是在状态500e下对于堆栈框架501的生命期无效的存储器位置。
接下来,在状态500f,添加新的堆栈框架505,现在堆栈指针502f指向堆栈框架505中的最后的条目。例如,由于线程调用了函数,因此可能已经添加了堆栈框架505。堆栈框架505包括四个存储器位置;这些存储器位置可能在创建堆栈框架505时被分配用于所调用的函数的局部变量。这些存储器位置可能会在分配之后由函数写入。例如,图5B示出了第一存储器位置已经被写入值A,而其他位置尚未被写入。这四个存储器位置在创建堆栈框架505时变为有效,因此,在堆栈框架处于活动时写入这些位置的任何存储器访问有效,因为它们发生在堆栈框架505的生命期内。
接下来,在状态500g,移除堆栈框架505,并且堆栈指针502g再次指向堆栈框架501中的最后的条目。例如,由于创建堆栈框架505的函数完成,堆栈框架505可能已经被移除。由于已经移除堆栈框架505,因此先前作为堆栈框架的部分的存储器位置现在无效,并且堆栈框架的生命期已经结束。但是,在状态500g,这些位置中的前两个已经被写入(即,值B和C)。这些写入可能已经发生,例如由于编码错误,该编码错误导致由与堆栈框架501相对应的函数进行的超出其堆栈框架的不适当的写入。尽管如此,在很多情况下,这些写入操作仍然可以没有错误地进行。另外,与堆栈框架501相对应的函数还可以从这些位置中的一个或多个(例如,如星号所示的包含值B的第一位置)中读取。再次,该读取是不适当的,但是在很多情况下可能会继续进行而没有错误。然而,由于跟踪堆栈框架505的生命期,存储器生命期组件200可以检测到该无效存储器访问。
另外,在状态500h,已经添加另一堆栈框架506,现在堆栈指针502h指向堆栈框架506中的最后的条目。例如,由于线程调用某个其他函数,所以可能已经添加堆栈框架506。在堆栈框架506中,存在三个存储器位置已经变为有效位置。尽管这些位置中的两个包含在状态500g写入的值(即,B和C),但是关于堆栈框架506的生命期而言,这些值是未定义值。但是,如果存在编码错误,则线程可能会在当前函数写入其之前从这些存储器位置中的一个或多个中读取。因此,例如,如果线程读取第一位置(如星号所示),则它将读取由先前函数不适当地放置在该位置的值B。该线程将从有效存储器位置读取,但是就堆栈框架506的生命期而言,它将读取无效数据。在某些情况下,即使读取不适当,该函数实际上也可以无故障地执行。然而,由于跟踪堆栈框架505和/或506的生命期,存储器生命期组件200可以检测到该无效存储器访问。
其他类型的存储器分配(包括基于堆栈的分配)也可以为超出所分配缓冲区的代码访问存储器提供机会。例如,图6A包括示例C风格的“struct”原语600(A),原语600(A)包括三个64位整数(即,a、b和d)和一个8位整数(即,c)。图6B示出了示例存储器分配601,存储器分配601可以基于struct原语600而在线程的堆栈上被分配。特别地,图6B示出了当代的编译器可以为整数a、b、c和d中的每个保留64位存储器范围。但是,如图所示,整数c的64位存储器范围包括整数本身的8位,后跟56位的填充602。类似于图3A、3B和4中讨论的填充,填充602可能是由编译器添加的,目的是使变量在64位边界上对准,但是其实际上并未分配给struct原语使用。但是,编码错误可能导致在56位填充602内读取和/或写入值。由于未为任何其他目的而保留该存储器,因此这些错误可能不会导致故障或其他执行错误。但是,通过对与struct原语相关的存储器布局601中的存储器位置进行生命期分析,存储器生命期组件200可以确定与56位填充602相对应的存储器位置不是“有效”的,并且因此对这些存储器位置的访问是不适当的。
鉴于前述计算环境和示例,图7示出了用于基于应用的执行的可重放跟踪来检测在应用的先前执行期间的非故障存储器访问的示例方法700的流程图。将关于计算机系统100的组件和数据、图2的存储器生命期组件200以及图3A-6B的示例来描述方法700。
方法700包括动作701:重放应用的先前执行,同时跟踪存储器区域生命期。动作701可以包括从应用的执行的可重放跟踪重放应用的先前执行的一个或多个部分,同时跟踪由应用使用的存储器区域的生命期。例如,计算机系统100可以使用调试程序107的重放组件107b基于(多个)跟踪文件109来重放(多个)应用106之一的先前执行。应用的先前执行可能已经由计算机系统100或另一计算机系统处的记录组件107a记录到(多个)跟踪文件109。(多个)跟踪文件109包含足够的信息以存储该应用的先前执行的比特精确跟踪。这样,重放组件107b能够忠实地重现在应用的先前执行期间由应用执行的动作,包括忠实地重现由该应用执行的存储器访问,包括其从存储器中读取的值。
结合重放,调试程序107可以使用存储器生命期组件107f(即,存储器生命期组件200)以便跟踪由应用106在其执行时使用的一个或多个存储器区域的生命期。特别地,存储器生命期组件200包括配对组件201,该配对组件201可以跟踪存储器区域的生命期何时开始(例如,由于分配函数、堆栈框架的添加、struct的实例化等)以及生命期何时结束(例如,由于解除分配函数、堆栈框架的移除、struct的移除等)。此外,存储器生命期组件200可以跟踪相当复杂的生命期,诸如重新分配函数的使用中涉及的生命期。
基于由存储器生命期组件200跟踪的(多个)生命期,有效性组件202可以确定存储器位置在不同时间的有效性状态。如上所述,有效性状态可以包括无效、关于位置和内容有效、或者关于位置有效但关于内容无效。有效性组件202可以跟踪针对存储器位置的有效性的各种转变,因为由于存储器区域生命期的来临,随着应用106的执行,存储器位置的有效性可能已经改变。
方法700还包括动作702:检测在所跟踪的存储器区域生命期之外的一个或多个非故障存储器访问。动作702可以包括基于跟踪存储器区域的生命期,检测在应用的先前执行期间由应用进行的一个或多个非故障存储器访问。例如,基于由配对组件201跟踪的(多个)生命期和由有效性组件202跟踪的有效性,检测组件203可以检测到由于其是在该位置无效时对存储器位置的访问而不适当的非故障存储器访问,或者检测到当其内容无效时对该位置的访问(例如,在该位置的有效生命期内未定义或无效)。
在动作702中可以检测到的不同的非故障存储器访问的示例在图3A-6B中示出。例如,非故障存储器访问可以是由应用进行的超出请求大小的所分配存储器的存储器访问。这在图3A、3B和4中被证明,其中访问可以是在所请求的堆存储器分配或重新分配之后对填充字节302、302'或402的访问。这一点也在图6中被证明,其中访问可以是对基于堆栈的分配(诸如struct)内的填充字节602的访问。
在另一示例中,非故障存储器访问可以是在至少以下各项的有序序列之后,由应用进行的从堆栈位置的读取:(i)在堆栈位置有效的同时对堆栈位置的写入;(ii)使堆栈位置无效;以及(iii)使堆栈位置有效,并且其中在使堆栈位置有效与读取之间,堆栈位置未被写入。这在图5A中被证明,其中访问是在(i)在位置有效的同时对位置的写入(即,在状态500b下将值A写入堆栈框架503的第一位置);(ii)使位置无效(即,在状态500c下移除堆栈框架503);以及(iii)再次使位置有效(即,在状态500d下添加堆栈框架504)之后从存储器位置(即,在状态500d期间在堆栈框架504中的第一位置,包含值A)的读取。值得注意的是,在图5A中,在状态500c或500d下均未写入该位置,从而导致读取值“A”。因此,尽管在状态500d下存储器位置对于堆栈框架504的生命期有效,但是其内容对于堆栈框架504的生命期无效,从而导致存储器访问不适当。
在另一示例中,非故障存储器访问可以是在至少以下各项的有序序列之后,由应用进行的从堆栈位置的读取:(i)使堆栈位置有效,(ii)使堆栈位置无效,以及(iii)在堆栈位置无效的同时对堆栈位置写入,并且其中在在堆栈位置无效的同时对堆栈位置写入与读取之间,在堆栈位置为有效堆栈位置的同时堆栈位置未被写入。这在图5B中被证明,其中访问是在(i)使该位置有效并且可能对位置写入(即,在状态500f下添加堆栈框架505,并且可能用A的值对其写入),(ii)使该位置无效(即,在状态500g下除去堆栈框架505),以及(iii)在该位置无效的同时对该位置写入(即,在状态500g下写入值B)之后从存储器位置的读取(例如,在状态500g或状态500h下从堆栈框架501之后的第一位置读取值B)。如果在状态500g下从该位置执行读取,则由于该位置无效(即,不是任何活动生命期的一部分)而导致其不适当且越界,或者如果在其在状态500h下被写入之前在状态500h下从该位置执行读取,则由于该位置在堆栈框架506的生命期内包含无效内容,因此该操作是不适当的。
在又一示例中,非故障存储器访问可以是在至少以下各项的有序序列之后,由应用对堆栈位置的写入:(i)使堆栈位置有效,以及(ii)使堆栈位置无效,并且其中堆栈位置在写入时无效。这也在图5B中被证明,其中访问是在在至少以下各项的有序序列之后,由应用对堆栈位置的写入:(i)使该位置有效并且可能对其写入(即,在状态500f下添加堆栈框架505,并且可能用A的值对其写入),以及(ii)然后使该位置无效(即,在状态500g下移除堆栈框架505)之后对存储器位置的写入(例如,在状态500g下的写入之一,写入值B或C)。如果在状态500g下对该位置执行值B和/或C的这些写入中的一个或多个,则由于该位置无效(即,不是任何活动生命期的一部分),它们将不适当且越界。
方法700还包括动作703:提供关于检测到的(多个)存储器访问的通知。动作703可以包括提供关于一个或多个非故障存储器访问的通知。例如,通知组件204向用户界面组件107e提供关于(多个)非故障存储器访问的通知以在用户界面处显示。替代地,通知组件204可以通知任何其他适当的组件,诸如编索引组件107c、查询组件107d或某个其他软件应用。
因此,本文中的实施例应用时间行进跟踪的比特精确跟踪分析以跟踪在线程的先前执行期间由线程实际使用的存储器区域的生命期。这些实施例使用所跟踪的存储器区域的生命期来标识线程何时对所分配存储器之外的(多个)存储器位置进行了非故障但不适当的(多个)访问和/或当存储器位置在有效与无效之间转变时线程何时对(多个)存储器位置进行了非故障但不适当的(多个)访问。这样,实施例可以标识否则难以发现的编程错误,这些错误导致这些非故障存储器访问在线程的先前执行期间发生。
尽管已经用特定于结构特征和/或方法动作的语言描述了主题,但是应当理解,所附权利要求书中定义的主题不必限于上述特征或动作,或者上述动作的顺序。相反,所描述的特征和动作被公开作为实现权利要求的示例形式。
在不脱离本发明的精神或基本特征的情况下,本发明可以以其他特定形式来体现。所描述的实施例在所有方面仅应当被认为是说明性的而非限制性的。因此,本发明的范围由所附权利要求书而不是前面的描述指示。落入权利要求的等同含义和范围内的所有改变均应当被包含在其范围之内。

Claims (15)

1.一种计算机系统,包括:
一个或多个处理器;以及
一个或多个计算机可读介质,其上存储有计算机可执行指令,所述计算机可执行指令由所述一个或多个处理器可执行以基于应用的执行的可重放跟踪来检测在所述应用的先前执行期间的非故障存储器访问,所述计算机可执行指令可执行以引起所述计算机系统至少执行以下各项:
从应用的执行的可重放跟踪重放所述应用的先前执行的一个或多个部分,同时跟踪由所述应用使用的存储器区域的生命期;
基于跟踪所述存储器区域的生命期,检测在所述应用的先前执行期间由所述应用进行的一个或多个非故障存储器访问,包括以下一项或多项:
由所述应用进行的、超出请求大小的所分配存储器的存储器访问;
在至少以下各项的有序序列之后,由所述应用从第一堆栈位置的第一读取:(i)在所述第一堆栈位置有效的同时对所述第一堆栈位置的写入,(ii)使所述第一堆栈位置无效,以及(iii)使所述第一堆栈位置有效,并且其中在使所述第一堆栈位置有效与所述第一读取之间,所述第一堆栈位置未被写入;
在至少以下各项的有序序列之后,由所述应用从第二堆栈位置的第二读取:(i)使所述第二堆栈位置有效,(ii)使所述第二堆栈位置无效,以及(iii)在所述第二堆栈位置无效的同时对所述第二堆栈位置写入,并且其中在当所述第二堆栈位置无效的同时对所述第二堆栈位置写入与所述第二读取之间,在所述第二堆栈位置为有效堆栈位置的同时所述第二堆栈位置未被写入;或者
在至少以下各项的有序序列之后,由所述应用对第三堆栈位置的第一写入:(i)使所述第三堆栈位置有效,以及(ii)使所述第三堆栈位置无效,并且其中所述第三堆栈位置在所述第一写入时无效;以及
提供所述一个或多个非故障存储器访问的通知。
2.根据权利要求1所述的计算机系统,其中所述非故障存储器访问包括由所述应用进行的所述第一读取、由所述应用进行的所述第一读取或由所述应用进行的所述第一写入中的至少一项,并且其中使所述第一堆栈位置无效、使所述第二堆栈位置无效以及所述使所述第三堆栈位置无效中的每一项包括第一堆栈框架从所述应用的堆栈的移除,并且其中使所述第一堆栈位置有效、使所述第二堆栈位置有效以及使所述第三堆栈位置有效中的每一项包括第二堆栈框架向所述应用的堆栈的添加。
3.根据权利要求1所述的计算机系统,其中所述非故障存储器访问包括由所述应用进行的所述第一读取。
4.根据权利要求1所述的计算机系统,其中所述非故障存储器访问包括由所述应用进行的所述第二读取,在使所述第二堆栈位置有效与使所述第二堆栈位置无效之间,所述第二堆栈位置已经被写入。
5.根据权利要求1所述的计算机系统,其中所述非故障存储器访问包括由所述应用进行的所述第一读取、由所述应用进行的所述第二读取或由所述应用进行的所述第一写入中的至少一项,并且其中所述第一堆栈位置、所述第二堆栈位置和所述第三堆栈位置包括函数局部变量。
6.根据权利要求1所述的计算机系统,其中所述非故障存储器访问包括由所述应用进行的、超出请求大小的所分配存储器的存储器访问,并且其中所述非故障存储器访问包括对被分配为存储器对准填充的存储器位置的读取或写入。
7.根据权利要求1所述的计算机系统,其中所述非故障存储器访问包括由所述应用进行的、超出请求大小的所分配存储器的存储器访问,并且其中所述非故障存储器访问包括从未被重新分配函数复制的存储器位置的读取。
8.根据权利要求1所述的计算机系统,其中提供所述一个或多个非故障存储器访问的通知包括以下一项或多项:(i)呈现用户界面通知,或者(ii)通知另一软件组件。
9.根据权利要求1所述的计算机系统,其中所述非故障存储器访问包括由所述应用进行的、超出请求大小的所分配存储器的存储器访问,并且其中所述请求大小的所分配存储器通过对存储器分配函数或重新分配函数的调用而被请求。
10.根据权利要求1所述的计算机系统,其中跟踪由所述应用使用的所述存储器区域的生命期包括将分配函数和解除分配函数配对。
11.根据权利要求1所述的计算机系统,其中跟踪由所述应用使用的所述存储器区域的生命期包括跟踪受堆栈框架添加和移除影响的存储器。
12.根据权利要求1所述的计算机系统,其中提供所述一个或多个非故障存储器访问的通知包括响应于调试程序处的搜索表达或查询表达而提供所述通知。
13.一种在包括一个或多个处理器的计算机系统处实现的、用于基于程序的执行的可重放跟踪来检测在所述程序的先前执行期间的非故障存储器访问的方法,所述方法包括:
从应用的执行的可重放跟踪重放所述应用的先前执行的一个或多个部分,同时跟踪由所述应用使用的堆存储器的一部分的生命期;
基于跟踪所述堆存储器的一部分的生命期,检测在所述应用的先前执行期间由所述应用进行的一个或多个非故障存储器访问,包括检测由所述应用进行的、超出请求大小的存储器的存储器访问;以及
提供所述一个或多个非故障存储器访问的通知。
14.根据权利要求13所述的方法,其中所述非故障存储器访问包括对被分配为存储器对准填充的存储器位置的读取或写入。
15.一种在包括一个或多个处理器的计算机系统处实现的、用于基于程序的执行的可重放跟踪来检测在所述程序的先前执行期间的非故障存储器访问的方法,所述方法包括:
从应用的执行的可重放跟踪重放所述应用的先前执行的一个或多个部分,同时跟踪由所述应用使用的堆栈存储器的生命期;
基于跟踪所述堆栈存储器的生命期,检测在所述应用的先前执行期间由所述应用进行的一个或多个非故障存储器访问,包括以下一项或多项:
在至少以下各项的有序序列之后,由所述应用从第一堆栈位置的第一读取:(i)在所述第一堆栈位置有效的同时对所述第一堆栈位置的写入,(ii)使所述第一堆栈位置无效,以及(iii)使所述第一堆栈位置有效,并且其中在使所述第一堆栈位置有效与所述第一读取之间,所述第一堆栈位置未被写入;
在至少以下各项的有序序列之后,由所述应用从第二堆栈位置的第二读取:(i)使所述第二堆栈位置有效,(ii)使所述第二堆栈位置无效,以及(iii)在所述第二堆栈位置无效的同时对所述第二堆栈位置写入,并且其中在当所述第二堆栈位置无效的同时对所述第二堆栈位置写入与所述第二读取之间,在所述第二堆栈位置为有效堆栈位置的同时所述第二堆栈位置未被写入;或者
在至少以下各项的有序序列之后,由所述应用对第三堆栈位置的第一写入:(i)使所述第三堆栈位置有效,以及(ii)使所述第三堆栈位置无效,并且其中所述第三堆栈位置在所述第一写入时无效;以及
提供所述一个或多个非故障存储器访问的通知。
CN201880085906.4A 2018-01-09 2018-12-18 利用所应用的存储器区域生命期的比特精确跟踪分析 Active CN111602121B (zh)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
US15/865,699 US10514969B2 (en) 2018-01-09 2018-01-09 Bit-accurate-tracing analysis with applied memory region lifetimes
US15/865,699 2018-01-09
PCT/US2018/066103 WO2019139739A1 (en) 2018-01-09 2018-12-18 Bit-accurate-tracing analysis with applied memory region lifetimes

Publications (2)

Publication Number Publication Date
CN111602121A true CN111602121A (zh) 2020-08-28
CN111602121B CN111602121B (zh) 2023-10-24

Family

ID=65013783

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201880085906.4A Active CN111602121B (zh) 2018-01-09 2018-12-18 利用所应用的存储器区域生命期的比特精确跟踪分析

Country Status (4)

Country Link
US (1) US10514969B2 (zh)
EP (1) EP3721346B1 (zh)
CN (1) CN111602121B (zh)
WO (1) WO2019139739A1 (zh)

Families Citing this family (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
JP2022150518A (ja) * 2021-03-26 2022-10-07 富士通株式会社 テスト処理プログラム、テスト処理方法および情報処理装置

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20070089088A1 (en) * 2005-10-14 2007-04-19 Microsoft Corporation Dynamically determining a buffer-stack overrun
CN101095113A (zh) * 2004-12-29 2007-12-26 英特尔公司 多处理器环境中基于事务的共享数据操作
US20080301646A1 (en) * 2007-05-29 2008-12-04 Satish Chandra Gupta Detecting Dangling Pointers and Memory Leaks Within Software
CN104050023A (zh) * 2013-03-14 2014-09-17 英特尔公司 用于实现事务存储器的系统和方法

Family Cites Families (17)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5870607A (en) * 1996-09-11 1999-02-09 Brown University Research Foundation Method and apparatus for selective replay of computer programs
US6145121A (en) * 1997-04-17 2000-11-07 University Of Washington Trace based method for the analysis, benchmarking and tuning of object oriented databases and applications
US6560773B1 (en) * 1997-12-12 2003-05-06 International Business Machines Corporation Method and system for memory leak detection in an object-oriented environment during real-time trace processing
US7512765B2 (en) * 2005-06-08 2009-03-31 Raytheon Company System and method for auditing memory
US7958497B1 (en) 2006-06-07 2011-06-07 Replay Solutions, Inc. State synchronization in recording and replaying computer programs
US7840849B2 (en) * 2006-12-21 2010-11-23 Novell, Inc. Methods and apparatus for debugging software including divisions of an execution history of a debuggee program
US7895477B2 (en) * 2008-06-03 2011-02-22 International Business Machines Corporation Resilience to memory errors with firmware assistance
US8468501B2 (en) 2010-04-21 2013-06-18 International Business Machines Corporation Partial recording of a computer program execution for replay
US8578340B1 (en) * 2010-09-24 2013-11-05 Ca, Inc. Recording and replaying computer program execution with recorded execution event breakpoints
WO2012148841A1 (en) * 2011-04-29 2012-11-01 Google Inc. Method and apparatus for detecting memory access faults
US8732681B2 (en) * 2011-05-16 2014-05-20 Texas Instruments Incorporated Stack analysis for post mortem analysis
US9645913B2 (en) * 2011-08-03 2017-05-09 Daniel Geist Method and apparatus for debugging programs
EP2600252B1 (en) * 2011-12-01 2019-04-03 Undo Ltd System and method for debugging of computer programs
US8977916B2 (en) * 2012-12-04 2015-03-10 Texas Instruments Incorporated Using data watchpoints to detect unitialized memory reads
US9129058B2 (en) * 2013-02-19 2015-09-08 Microsoft Technology Licensing, Llc Application monitoring through continuous record and replay
US9875173B2 (en) * 2014-06-30 2018-01-23 Microsoft Technology Licensing, Llc Time travel debugging in managed runtime
GB201508034D0 (en) * 2015-05-12 2015-06-24 Undo Ltd Debugging systems

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101095113A (zh) * 2004-12-29 2007-12-26 英特尔公司 多处理器环境中基于事务的共享数据操作
US20070089088A1 (en) * 2005-10-14 2007-04-19 Microsoft Corporation Dynamically determining a buffer-stack overrun
US20080301646A1 (en) * 2007-05-29 2008-12-04 Satish Chandra Gupta Detecting Dangling Pointers and Memory Leaks Within Software
CN104050023A (zh) * 2013-03-14 2014-09-17 英特尔公司 用于实现事务存储器的系统和方法

Also Published As

Publication number Publication date
US20190213065A1 (en) 2019-07-11
WO2019139739A1 (en) 2019-07-18
EP3721346A1 (en) 2020-10-14
US10514969B2 (en) 2019-12-24
EP3721346B1 (en) 2024-05-22
CN111602121B (zh) 2023-10-24

Similar Documents

Publication Publication Date Title
EP3665575B1 (en) Cache-based trace recording using cache coherence protocol data
US10540250B2 (en) Reducing storage requirements for storing memory addresses and values
AU2019223807B2 (en) Logging cache influxes by request to a higher-level cache
KR102645481B1 (ko) 상위 계층 캐시의 항목을 기반으로 하위 계층 캐시로의 유입을 로깅함으로써 트레이스 기록
US10558572B2 (en) Decoupling trace data streams using cache coherence protocol data
US10324851B2 (en) Facilitating recording a trace file of code execution using way-locking in a set-associative processor cache
US10599541B2 (en) Efficient breakpoint detection via caches
US11907091B2 (en) Trace recording by logging influxes to an upper-layer shared cache, plus cache coherence protocol transitions among lower-layer caches
US11567854B2 (en) Cross-thread memory indexing in time-travel debugging traces
CN113632067A (zh) 利用跟踪代码的记录执行来仿真非跟踪代码
CN111602121B (zh) 利用所应用的存储器区域生命期的比特精确跟踪分析
US20230342282A1 (en) Memory page markings as logging cues for processor-based execution tracing
Zamfir et al. Automating the debugging of datacenter applications with ADDA
US11442842B2 (en) Exposing memory-backed objects as queryable memory resources
CN117043754A (zh) 执行追踪内的存储器地址压缩
CN117063161A (zh) 执行跟踪内的物理存储器地址省略或混淆
Altekar et al. Automating the debugging of datacenter applications with ADDA

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant