首页 / 专利库 / 专利权 / 申请 / 国际申请 / 明显错误 / 一种内存重复释放错误检测方法

一种内存重复释放错误检测方法

阅读:914发布:2020-05-14

专利汇可以提供一种内存重复释放错误检测方法专利检索,专利查询,专利分析的服务。并且本 发明 公开了一种内存重复释放错误检测方法,属于 软件 工程技术领域。本方法包括建立内存池和操作队列池、将被调试程序对内存池中内存 块 的每一次 申请 或释放操作记录到该内存块所对应的操作队列中、判断是否明显重复释放、根据操作队列所记录的信息在程序代码中 定位 导致程序错误的代码 位置 等步骤。本发明方法严谨、简洁而紧凑,并且便于实现,尤其是采用了内存池和操作队列池这种数据结构为内存调用排错提供了坚实 基础 ,相对于 现有技术 能够更加简单高效地定位代码中引起内存重复释放错误的位置,是对现有代码排查调试技术的一种重要改进。,下面是一种内存重复释放错误检测方法专利的具体信息内容。

1.一种内存重复释放错误检测方法,其特征在于,包括以下步骤:
(1)建立内存池和操作队列池;操作队列池中的操作队列与内存池中的内存一一对应,每一个内存块包括内存块标识字段、占用状态字段和存储数据字段,操作队列中的每个元素包括操作类型字段、代码文件标识字段、代码行号字段和操作时间字段;
(2)将被调试程序对内存池中内存块的每一次申请或释放操作记录到该内存块所对应的操作队列中;
(3)对于每一次内存操作,若该次操作的类型为释放内存,且该次操作所对应的内存块的占用状态字段为未占用,则引发人为系统崩溃;
(4)当系统发生自然崩溃或人为崩溃时,根据崩溃现场确定引起系统崩溃的内存块,从操作队列池中查找该内存块所对应的操作队列,根据该操作队列所记录的信息在程序代码中定位导致程序错误的代码位置
所述自然崩溃是指,被调试程序的不同模块之间由于存在潜在的逻辑错误,导致一个模块申请的内存被另一个模块释放,此时当申请内存的模块再次读取该内存块时所导致的系统崩溃;
所述步骤(4)中根据操作队列所记录的信息在程序代码中定位导致程序错误的代码位置的具体方式为:
(401)将操作队列中的元素顺序反转并另行存储,形成原操作队列的镜像操作队列;
(402)从当前镜像操作队列的头部开始逐一取出元素,直到取出操作类型为释放的元素;
(403)从当前镜像操作队列的头部再取出一个元素,判断该元素的操作类型,若操作类型也为释放,则定位两次连续释放操作所对应的代码位置,结束检测;若操作类型为申请,则继续后续步骤;
(404)判断最后取出的两个元素的对应操作是否逻辑匹配,若匹配则重复步骤(402),否则继续后续步骤;
(405)从当前镜像操作队列的头部开始向后查找第一个与当前最后一个被取出的释放元素逻辑匹配的申请元素,再从该申请元素开始向前查找最近的释放元素,判断该最近的释放元素是否与本步骤中的申请元素逻辑匹配,若是则定位本步骤中所涉两个释放元素的对应代码位置,结束检测;否则从当前镜像操作队列的头部开始逐一取出元素直至取出本步骤所述的最近的释放元素,然后重复本步骤(405)。
2.根据权利要求1所述的内存重复释放错误检测方法,其特征在于,所述操作队列的存储形式为环形队列。

说明书全文

一种内存重复释放错误检测方法

技术领域

[0001] 本发明涉及软件工程技术领域,特别是指一种内存重复释放错误检测方法。

背景技术

[0002] 一些高级编程语言如C、C++,因为执行效率高,开发程序灵活等特点,受到程序员的广泛欢迎;尤其是C语言在嵌入式系统开发领域占据十分重要的地位。然而这类开发语言在内存的管理上却存在不足,尤其是申请堆中的动态内存,需要开发人员自己去维护。一旦出现内存重复释放或者访问非法地址的内存等情况,就会引发程序的严重异常,甚至崩溃。对小规模程序,这个缺陷并不突出,内存操作有问题时通过代码走查和调试便可十分容易地定位到问题,但对于包含百万行代码的大型项目,程序执行逻辑可能非常复杂,在这种场景下定位内存错误操作这类问题会变得十分困难。
[0003] 目前国内外科研人员和软件开发人员研究实践了许多内存管理的方法,防止开发人员操作内存错误,主要包括预防和静态代码走查两种技术。
[0004] 1.预防技术
[0005] 开发人员在开发程序时涉及到管理堆中的内存时要格外注意,一般遵循“哪里申请,哪里释放”的原则,防止只有在不适当的位置重复释放内存。这种策略有很多失效的场景,例如在很多协议开发中,不同层次之间通过消息机制传递信息,经常需要在发送层申请该消息内存,在接收层处理该消息,并且负责释放;同样在一些程序开发中,需要在被调函数中申请堆内存,然后将该内存地址返回给调用函数使用并最后释放。可见,预防策略只在小范围程序中可取。
[0006] 2.静态代码走查技术
[0007] 测试阶段遇到内存的错误操作时,最直接的想法是根据系统崩溃现场导出函数调用栈,定位到引起系统崩溃的内存(即目标内存块),采用静态代码走查的方式定位程序中的错误。
[0008] 这种方式主要有两个不足:
[0009] 1)系统崩溃现场中的函数调用栈是引起系统崩溃的“伪”原因;
[0010] 系统崩溃时可以通过一些手段获取崩溃前的函数调用栈,如在嵌入式开发中使用TRACE32(德国Lauterbach公司研制开发的一款仿真测试工具)抓取崩溃现场。函数调用栈详细记录了系统崩溃前的执行流程,并说明崩溃的原因。但是很多场景下它不是系统崩溃的根本原因,只是最后表现在这里,例如内存重复释放引起的系统崩溃,因此,根据函数调用栈去定位问题经常没有收获
[0011] 2)静态代码走查方式十分困难
[0012] 在一些大型项目中,通常包含上百万行的代码,为了考虑更好的移植性,兼容更多的接口,程序中往往包含大量的宏定义开关,这导致确定有效代码十分困难;即使成功确定了有效代码,由于程序的执行逻辑可能非常复杂,代码走查需要遍历的分支可能非常多,因而还是十分耗费精
[0013] 总之,现有技术中的内存检测方法存在适用范围有限、排错复杂、效率低下等问题,难以适应繁重的调试工作。

发明内容

[0014] 有鉴于此,本发明提出一种内存重复释放错误检测方法,其能够简单高效地定位代码中引起内存错误释放的位置,快速排查代码中的逻辑错误。
[0015] 基于上述目的,本发明提供的技术方案是:
[0016] 一种内存重复释放错误检测方法,其包括以下步骤:
[0017] (1)建立内存池和操作队列池;操作队列池中的操作队列与内存池中的内存块一一对应,每一个内存块包括内存块标识字段、占用状态字段和存储数据字段,操作队列中的每个元素包括操作类型字段、代码文件标识字段、代码行号字段和操作时间字段;
[0018] (2)将被调试程序对内存池中内存块的每一次申请或释放操作记录到该内存块所对应的操作队列中;
[0019] (3)对于每一次内存操作,若该次操作的类型为释放内存,且该次操作所对应的内存块的占用状态字段为未占用,则引发人为系统崩溃;
[0020] (4)当系统发生自然崩溃或人为崩溃时,根据崩溃现场确定引起系统崩溃的内存块,从操作队列池中查找该内存块所对应的操作队列,根据该操作队列所记录的信息在程序代码中定位导致程序错误的代码位置。
[0021] 可选的,步骤(4)中根据操作队列所记录的信息在程序代码中定位导致程序错误的代码位置的具体方式为:
[0022] (401)将操作队列中的元素顺序反转并另行存储,形成原操作队列的镜像操作队列;
[0023] (402)从当前镜像操作队列的头部开始逐一取出元素,直到取出操作类型为释放的元素;
[0024] (403)从当前镜像操作队列的头部再取出一个元素,判断该元素的操作类型,若操作类型也为释放,则定位两次连续释放操作所对应的代码位置,结束检测;若操作类型为申请,则继续后续步骤;
[0025] (404)判断最后取出的两个元素的对应操作是否逻辑匹配,若匹配则重复步骤(402),否则继续后续步骤;
[0026] (405)从当前镜像操作队列的头部开始向后查找第一个与当前最后一个被取出的释放元素逻辑匹配的申请元素,再从该申请元素开始向前查找最近的释放元素,判断该最近的释放元素是否与本步骤中的申请元素逻辑匹配,若是则定位本步骤中所涉两个释放元素的对应代码位置,结束检测;否则从当前镜像操作队列的头部开始逐一取出元素直至取出本步骤所述的最近的释放元素,然后重复本步骤(405)。
[0027] 可选的,操作队列的存储形式为环形队列。
[0028] 从上面的叙述可以看出,本发明技术方案的有益效果在于:
[0029] 1、本发明利用操作队列池详细而完备地记录内存块的使用情况,为内存调用排错提供了坚实基础
[0030] 2、本发明方法通过引入人为系统崩溃的方式提高了对代码错误的敏感度,便于快速暴露错误所在。
[0031] 3、本发明成功解决了现有技术中预防技术和静态代码走查技术等技术的缺点,不需要根据宏定义确定有效代码,不需要走查大量的程序,依据系统动态唯一的执行流程,不但可定位到明显的内存重复释放Bug,也可以发现隐藏在复杂流程中内存重复释放的Bug,提高了解决系统崩溃问题的效率。
[0032] 总之,本发明方法严谨、简洁而紧凑,并且便于实现,尤其是采用了内存池和操作队列池这种数据结构为内存调用排错提供了坚实基础,相对于现有技术能够更加简单高效地定位代码中引起内存重复释放错误的位置,是对现有代码排查调试技术的一种重要改进。附图说明
[0033] 为了更加清楚地描述本专利,下面提供一幅或多幅附图,这些附图旨在对本专利的背景技术、技术原理和/或某些具体实施方案做出辅助说明。需要注意的是,这些附图可以给出也可以不给出一些在本专利文字部分已有描述且属于本领域普通技术人员公知常识的具体细节;并且,因为本领域的普通技术人员完全可以结合本专利已公开的文字内容和/或附图内容,在不付出任何创造性劳动的情况下设计出更多的附图,因此下面这些附图可以涵盖也可以不涵盖本专利文字部分所叙述的所有技术方案。此外,这些附图的具体内涵需要结合本专利的文字内容予以确定,当本专利的文字内容与这些附图中的某个明显结构不相符时,需要结合本领域的公知常识以及本专利其他部分的叙述来综合判断到底是本专利的文字部分存在笔误,还是附图中存在绘制错误。特别地,以下附图均为实例性质的图片,并非旨在暗示本专利的保护范围,本领域的普通技术人员通过参考本专利所公开的文字内容和/或附图内容,可以在不付出任何创造性劳动的情况下设计出更多的附图,这些新附图所代表的技术方案依然在本专利的保护范围之内。
[0034] 图1是本发明实施例中内存的数据结构示意图;
[0035] 图2是本发明实施例中系统运行时的流程图
[0036] 图3是本发明实施例中排错过程的流程图。

具体实施方式

[0037] 为了便于本领域技术人员对本专利技术方案的理解,同时,为了使本专利的技术目的、技术方案和有益效果更加清楚,并使权利要求书的保护范围得到充分支持,下面以具体案例的形式对本专利的技术方案做出进一步的、更详细的说明。
[0038] 一种内存重复释放错误检测方法,其包括以下步骤:
[0039] (1)建立内存池和操作队列池;操作队列池中的操作队列与内存池中的内存块一一对应,每一个内存块包括内存块标识字段、占用状态字段和存储数据字段,操作队列中的每个元素包括操作类型字段、代码文件标识字段、代码行号字段和操作时间字段;
[0040] (2)将被调试程序对内存池中内存块的每一次申请或释放操作记录到该内存块所对应的操作队列中;
[0041] (3)对于每一次内存操作,若该次操作的类型为释放内存,且该次操作所对应的内存块的占用状态字段为未占用,则引发人为系统崩溃;
[0042] (4)当系统发生自然崩溃或人为崩溃时,根据崩溃现场确定引起系统崩溃的内存块,从操作队列池中查找该内存块所对应的操作队列,根据该操作队列所记录的信息在程序代码中定位导致程序错误的代码位置。
[0043] 可选的,步骤(4)中根据操作队列所记录的信息在程序代码中定位导致程序错误的代码位置的具体方式为:
[0044] (401)将操作队列中的元素顺序反转并另行存储,形成原操作队列的镜像操作队列;
[0045] (402)从当前镜像操作队列的头部开始逐一取出元素,直到取出操作类型为释放的元素;
[0046] (403)从当前镜像操作队列的头部再取出一个元素,判断该元素的操作类型,若操作类型也为释放,则定位两次连续释放操作所对应的代码位置,结束检测;若操作类型为申请,则继续后续步骤;
[0047] (404)判断最后取出的两个元素的对应操作是否逻辑匹配,若匹配则重复步骤(402),否则继续后续步骤;
[0048] (405)从当前镜像操作队列的头部开始向后查找第一个与当前最后一个被取出的释放元素逻辑匹配的申请元素,再从该申请元素开始向前查找最近的释放元素,判断该最近的释放元素是否与本步骤中的申请元素逻辑匹配,若是则定位本步骤中所涉两个释放元素的对应代码位置,结束检测;否则从当前镜像操作队列的头部开始逐一取出元素直至取出本步骤所述的最近的释放元素,然后重复本步骤(405)。
[0049] 这种将原操作队列另存为镜像队列的方式别具匠心,因为后续的排查都是按照时间顺序向前排查的,采用这种镜像队列的数据结构恰好使得“按照时间顺序排查”这一操作与队列的“先进先出”规则相符合,并且排查后的元素被从队列中剔除,这使得排查过程非常容易通过迭代的方式实现,可见这种镜像队列的数据结构有利于提高排错算法的算法效率。
[0050] 可选的,操作队列的存储形式为环形队列。
[0051] 具体的,如图2和3所示,一种内存重复释放错误检测方法,其包括以下步骤:
[0052] 步骤1,建立如图1所示的内存池和操作队列池;
[0053] 对于内存池,将整个内存区划分为T个内存块,这些内存块可以大小相等,也可以大小不等,每个内存块包含块头信息(内存块的状态和标识M_ID)。内存块实现时可以采用类似如下的结构体:
[0054]
[0055] 当内存块已经分配给应用程序时,其状态为占用态;当释放内存块时,其状态由占用态转化为空闲态。标识M_ID从0到T-1,是每个内存块在内存池中的唯一标识,同时是内存池到操作队列池映射的关键;对于操作队列池,它包含T个大小相等的内存块,每个内存块是一个操作队列,能够容纳内存池中内存块的N次操作,每个操作包含四项信息:操作类型(申请或释放)、文件标识、行号和时间。当应用程序申请或释放内存池中的内存时,要向操作队列中添加操作,待系统崩溃时分析使用。操作队列实现时可以采用类似如下的结构体:
[0056]
[0057] 因为内存池中的内存块会被反复操作,操作队列池中有限的内存空间不允许完全记录内存块的所有操作,所以可以设置每个操作队列最多只记录N次操作,并将操作队列设置为环形队列的存储形式。
[0058] 步骤2,启动系统,执行被调试程序,被调试程序的所有内存操作均在内存池中进行,且每次操作都被记录在操作队列池中。
[0059] 系统在启动时调用系统API申请内存池和操作队列池中的内存,对其进行初始化,同时为应用程序提供申请内存和释放内存函数的接口,不再是系统调用malloc和free那种方式,在应用程序调用这些接口时需要提供调用的文件标识、行号和系统时间,以便在操作队列中记录这些信息。当应用程序申请指定大小的内存时,系统从内存池中寻找空闲态且大小满足的内存块M返回给应用程序,修改M的块头状态信息为占用态,根据M的块头信息M_ID查找操作队列池中对应的操作队列,将应用程序提供的文件标识、行号和系统时间信息组合成一个操作,并添加到操作队列中,同时操作队列的队尾指针后移;当应用程序释放某个地址的内存块M时,系统根据M的块头信息M_ID,查找操作队列池中对应的操作队列,将应用程序提供的文件标识、行号和系统时间信息组合成一个操作,并添加到操作队列中,同时操作队列的队尾指针后移,完成后查询M的块头状态,若为占用态,将其修改为空闲态,该释放操作结束,若为空闲态,当前操作释放了本来为空闲态的内存,这是明显的内存重复释放。
[0060] 值得注意的是,由于已经被申请的内存块将处于被占用的状态而无法被其他进程或线程所申请,因此操作队列中不会出现连续两个申请操作。若操作队列中连续出现两个释放操作,则属于明显的内存重复释放错误,此时本方法会引起系统的人为崩溃,从而及时终止程序并进入排错流程,便于快速暴露并排查错误。一般情况下,操作队列中的所有操作是以申请和释放相间的形式排列的,但是被调试程序的不同模块之间可能存在潜在的逻辑错误,导致一个模块申请的内存被另一个模块释放,则当申请内存的模块再次读取该内存块时就会出现读取错误,从而导致系统的自然崩溃,此时本方法即会进入排错流程帮助用户查找错误所在。
[0061] 步骤3,当系统发生崩溃时进入排错流程。该流程如图3所示:
[0062] ①将操作队列中的元素顺序反转并另行存储,形成原操作队列的镜像操作队列;
[0063] ②从当前镜像操作队列的头部开始逐一取出元素,直到取出操作类型为释放的元素P;
[0064] ③从当前镜像操作队列的头部再取出一个元素Q,判断该元素Q的操作类型,若操作类型也为释放,则定位两次连续释放操作所对应的代码位置,结束检测;若操作类型为申请,则继续后续步骤;
[0065] ④判断最后取出的两个元素P和Q的对应操作是否逻辑匹配,若匹配则重复步骤②,否则继续后续步骤;
[0066] ⑤从当前镜像操作队列的头部开始向后查找第一个与当前最后一个被取出的释放元素逻辑匹配的申请元素,再从该申请元素开始在当前镜像操作队列中向前查找最近的释放元素,判断该最近的释放元素是否与本步骤中的申请元素逻辑匹配,若是则表示一个申请操作出现了连续两个逻辑匹配的释放操作,这是一个潜在的内存重复释放错误,此时可以定位这两个释放操作的对应代码位置,结束检测;否则表示该最近的释放元素可能是引起内存错误的原因,此时从当前镜像操作队列的头部开始逐一取出元素直至取出该最近的释放元素,然后重复本步骤⑤。
[0067] 本领域技术人员应当理解,以上方法中的“当前”显然是指该“当前”所在语境的对应时刻,因此不同步骤中的“当前镜像操作队列”显然不一定是元素相同的队列。
[0068] 以上方法中所谓“逻辑匹配”是指申请操作与释放操作对应的代码不存在逻辑错误。
[0069] 以上方法中,从队列中“取出”一个队列元素后该队列元素即被从该队列中删除。
[0070] 总之,本发明成功解决了预防技术、静态代码走查技术等技术的缺点,不需要根据宏定义确定有效代码,不需要走查大量的程序,依据系统动态唯一的执行流程,不但可定位到明显的内存重复释放Bug,也可以发现隐藏在复杂流程中内存重复释放的Bug,提高了解决系统崩溃问题的效率,是对现有技术的一种重要改进。
[0071] 需要注意的是,本专利权利要求书中所谓的“步骤”是指用于实现本专利方法的任一具体流程中的一个必要环节,并不包含对步骤执行顺序的限定,本领域普通技术人员完全能够在理解了本专利某一权项中各步骤间的内在逻辑的基础上,对这些步骤的具体执行顺序做出各种符合这种内在逻辑的实际安排。因此,任何一种应用了本专利某一权项中所有步骤的、符合这些步骤间的内在逻辑的、用于实现本专利方法的,且具有特定执行顺序的具体步骤序列,均在本专利的保护范围之内。
[0072] 需要理解的是,上述对于本专利具体实施方式的叙述仅仅是为了便于本领域普通技术人员理解本专利方案而列举的个例性描述,并非暗示本专利的保护范围仅仅被限制在这些个例中,本领域普通技术人员完全可以在对本专利技术方案做出充分理解的前提下,以不付出任何创造性劳动的形式,通过对本专利所列举的各个例采取组合技术特征、替换部分技术特征、加入更多技术特征等等方式,得到更多的具体实施方式,所有这些具体实施方式均在本专利权利要求书的涵盖范围之内,因此,这些新的具体实施方式也应在本专利的保护范围之内。
[0073] 此外,出于简化叙述的目的,本专利也可能没有列举一些寻常的具体实施方案,这些方案是本领域普通技术人员在理解了本专利技术方案后能够自然而然想到的,显然,这些方案也应包含在本专利的保护范围之内。
[0074] 出于简化叙述的目的,上述各具体实施方式对于技术细节的公开程度可能仅仅达到本领域技术人员可以自行决断的程度,即,对于上述具体实施方式没有公开的技术细节,本领域普通技术人员完全可以在不付出任何创造性劳动的情况下,在本专利技术方案的充分提示下,借助于教科书、工具书、论文、专利、音像制品等等已公开文献予以完成,或者,这些细节是在本领域普通技术人员的通常理解下,可以根据实际情况自行作出决定的内容。可见,即使不公开这些技术细节,也不会对本专利技术方案的公开充分性造成影响。
[0075] 总之,在结合了本专利说明书对权利要求书保护范围的解释作用的基础上,任何落入本专利权利要求书涵盖范围的具体实施方案,均在本专利的保护范围之内。
高效检索全球专利

专利汇是专利免费检索,专利查询,专利分析-国家发明专利查询检索分析平台,是提供专利分析,专利查询,专利检索等数据服务功能的知识产权数据服务商。

我们的产品包含105个国家的1.26亿组数据,免费查、免费专利分析。

申请试用

分析报告

专利汇分析报告产品可以对行业情报数据进行梳理分析,涉及维度包括行业专利基本状况分析、地域分析、技术分析、发明人分析、申请人分析、专利权人分析、失效分析、核心专利分析、法律分析、研发重点分析、企业专利处境分析、技术处境分析、专利寿命分析、企业定位分析、引证分析等超过60个分析角度,系统通过AI智能系统对图表进行解读,只需1分钟,一键生成行业专利分析报告。

申请试用

QQ群二维码
意见反馈