一种用于动态测量c/c++显存泄漏的方式及系统的制做方式
【专利摘要】本发明涉及计算机软件安全剖析领域,提供一种用于动态测量C/C++显存泄漏的方式,所述方式包括如下步骤:查获C/C++源程序中动态显存的显存管理函数;在查获的显存管理函数中加入检测代码,剖析程序所申请的显存资源,推断出显存泄漏的缘由并进行监控;根据Valgrind工具显存泄漏的规则,确定系统中应用程序显存泄漏的缘由并最终给出剖析报告。本发明可动态测量C/C++源程序中显存错误的问题,进而解决静态剖析技术的缺陷。
【专利说明】
一种用于动态测量C/C++显存泄漏的方式及系统
技术领域
[0001]本发明涉及计算机软件安全剖析领域,尤其涉及一种用于动态测量C/C++显存泄露的方式及系统。
【背景技术】
[0002]C++因其灵活性、高效性等特征仍然以来都是主流程序设计语言之一。它与Java等中级语言相比,在编程中程序员须要自己管理显存,并对程序中所涉及的显存操作有很清晰的认识。显存问题很难让人察觉,非常是显存泄露,它不同于其他显存错误,如多次释放、野表针、或者是链表越界等容易曝露下来,显存泄露错误通常隐藏得比较深,在数万行的代码之中找寻显存泄露无异于大海捞针。因而利用显存剖析工具来检验显存错误是特别具有实用价值的,除了才能提升软件的质量,就能减短软件的开发周期。
[0003]-般地,显存泄露的测量方式分为两大类,一类是静态检查方式,另一类是动态检测方式。静态检查方式通过剖析程序源代码,模拟所有可能执行路径,判断程序可能执行路径中存在的安全缺陷。这些方式无需实际执行程序,克服了动态剖析性能开支较大的问题,而且因为静态剖析难以精确判定程序的输入、环境变量等信息,模拟执行路径中可能存在不可行路径。为此,静态剖析技巧较高的误报率是至今未解的一个重要困局。动态测量方式主要原理是在程序中进行动态显存分配时,在堆中作以标记。当程序退出并释放所有已分配的显存时,检测堆上残留的对象,这种残留的对象就是程序中泄露的显存。这些剖析方式才能直接发觉实际发生的程序缺陷。并且,动态特点要求实际执行程序引入较大性能和时间开支,另外因为程序执行的路径覆盖存在死角,测量结果完备性不足,漏报率较高。
[0004]动态测量法的实现主要有以下几种方式:第一种方式是通过重新编撰编译器来实现。重新编撰编译器须要耗费大量的时间,并且须要的人力和物力代价也很高。为此,几乎没有采用该种方式来完成C++显存泄漏检查的工具。第二种方式是对源代码进行更改,通过句型剖析和语义剖析,插入检测代码,将原始的源代码转换为新的源代码。该种方式其实实现的代价比较低,而且因为源代码的转换须要人工参与,手动化程度低,但是得出的结果不太理想,该种方式的应用范围也不太广泛。
【发明内容】
[0005]鉴于上述问题,提出了本发明,便于提供一种克服上述问题或起码部份地解决上述问题的一种用于动态测量C/C++显存泄漏的方式及系统。
[0006]按照本发明的一个方面,提供一种用于动态测量C/C++显存泄漏的方式,所述方式包括如下步骤:
[0007]查获C/C++源程序中动态显存的显存管理函数;
[0008]在查获的显存管理函数中加入检测代码,剖析程序所申请的显存资源,猜想出内存泄漏的缘由并进行监控;
[0009]根据Valgrind工具显存泄漏的规则,确定系统中应用程序显存泄漏的缘由并最终给出剖析报告。
[0010]进一步的,通过Valgrind工具提供的相关API获取所述显存管理函数的控制权。
[0011]进一步的,所述检测代码为显存信息块,所述显存信息块记录所述显存管理函数中所涉及的显存相关信息,所述显存相关信息包括显存的大小,返回给用户显存块首地址、申请的时间、当前堆栈中近来几层函数的调用地址。
[0012]按照本发明的另一方面,提供一种用于动态测量C/C++显存泄漏的系统,所述系统包括显存管理函数插口模块、内存信息块管理模块、内存泄漏检查模块和日志输出模块,其中:
[0013]所述显存管理函数插口模块,用于对C/C++源程序中显存管理函数进行捕获和记录,因而获得这种函数的控制权;
[0014]所述显存信息块管理模块,用于记录C/C++源程序中申请或释放的动态显存块的相关信息的数据结构;
[0015]所述显存泄漏检查模块,用于对显存泄漏的类型进行检查;
[0016]所述日志输出模块,用于输出显存泄漏错误信息并提供可以定位到显存泄漏具体位置的信息。
[0017]进一步的,所述显存管理函数插口模块,具体通过查获C/C++程序中对应的符号信息来获取到该函数的控制权限。
[0018]进一步的,每一个函数族都有一个完全属于本函数族的显存信息块数组,所有的函数族表头都链成一个数组,由全局表针索引;同时,采用生命周期法须要将程序中分配的所有显存信息块统一进行分组管理,以执行到显存分配函数时当前堆栈中的近来五层函数返回地址作为关键字进行分组。
[0019]进一步的,在系统查获申请函数后,将显存信息块加入管理列表,具体流程包括:记录当前分配时间,将当前堆栈中的近来五层函数返回地址的异或值作为组号,判定该组号是否存在,假如存在,则将显存信息块加入该组并更新该组的相关信息;否则,将申请组结点空间并初始化,将该组结点加入显存信息块管理列表中,同时将显存信息块加入该组,并设置该组的相关信息。
[0020]进一步的,在系统查获释放函数后,将显存信息块从管理列表中删掉linux公社,具体流程包括:通过显存块管理信息中记录的组号,找到该显存块所在的组;估算当前显存块的生存时间,判定该显存信息块的生存时间是否小于该组所保存的最大生命周期,倘若是,则将该组中最大生命周期更新为当前显存块的生存周期后,将该显存信息块从该组中删掉;否则,直接将该显存信息块从该组中删掉。
[0021]进一步的,当一个显存块的生存周期小于所在组中最大生命周期的两倍则将该块显存标记为疑似泄露;在C/C++程序结束之后检查各个函数族中是否还有没有释放的显存信息块,假如有则表示存在显存泄露,报告显存泄露错误,显存泄露类型是确定泄露。
[0022]进一步的,所述系统还包括应用程序函数调用跟踪模块,用于在加入检测代码后,对动态显存使用情况进行跟踪,并将动态显存使用信息输出给显存信息块管理模块。
[0023]本发明可动态监测C/C++源程序中显存错误的问题,因而解决静态剖析技术的缺陷。
【附图说明】
[0024]为了更清楚地说明本发明施行例的技术方案,下边将对施行例描述中所须要使用的附图作简单地介绍,显而易见地,下边描述中的附图仅仅是本发明的一些施行例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以依据这种附图获得其他的附图。
[0025]图1为本发明一种施行例的一种用于动态测量C/C++显存泄漏方式的流程示意图。
[0026]图2为本发明一种施行例的一种用于动态测量C/C++显存泄漏系统的框架示意图。[0027]图3为本发明一种施行例的一种用于动态测量C/C++显存泄漏系统的功能结构示意图。
[0028]图4为本发明一种施行例的一种用于动态测量C/C++显存泄漏系统在加入显存信息块时的处理流程示意图。
[0029]图5为本发明一种施行例的一种用于动态测量C/C++显存窃取系统在删掉显存信息块时的处理流程示意图。
【具体施行方法】
[0030]下边将参照附图更详尽的描述本发明的示例性施行例。其实附图中显示了本发明的示例性施行例,但是应该理解,可以以各类方式实现本发明,而不应被这儿论述的施行例所限制。相反,提供这种施行例是为了能更透彻的理解本发明,但是才能将本发明的范围完整的传达给本领域的技术人员。
[0031]本发明的动态监测方式是对中间代码进行更改,即在编译或链接阶段插入检测代码。这些技巧的实现代价介于现有技术中提及的第一种方式和第二种方式之间,并且手动化程度很高,得下来的结果比较令人满意。
[0032]Valgrind工具的检查原理是通过更改可执行文件来进行显存窃取检查,所以不需要重新编译程序。但它并不是在执行前对可执行文件和所有相关的共享库进行一次性修改,而是和应用程序在同一个进程中运行,动态地更改正式执行的下一段代码。Valgrind是插件式设计的,它的Core部份负责对应用程序的整体控制,并把正式更改的代码,转换成一种中间格式,这些格式类似于RISC指令,之后把中间代码传给插件。插件按照要求对中间代码更改,之后把更改后的结果交给Core[0033]基于以上原理,本发明在检查程序存在的显存问题时首先查获显存操作信息,即查获相关显存管理函数的控制权,如C中的操作符mall〇C、free等,C++中的操作符new、delete等。获得显存管理函数的控制权之后,采取监控和替换的形式在被测程序中添加插粧代码,记录显存的操作行为,包括记录显存相关信息(例如显存的大小,返回给用户显存块首地址、申请的时间、当前堆栈中近来几层函数的调用地址等),并对这种信息进行统一管理。记录显存相关信息后,借助Valgrind工具的判断显存窃取的规则和技巧来判断显存出现的错误。本发明测量出显存错误后linux c++ 内存泄露检测工具,报告显存相关错误并提供可以定位该错误的相关fg息。
[0034]具体的,按照本发明的一个方面,提供一种用于动态测量C/C++显存窃取的方式,如图1所示,所述方式包括如下步骤:
[0035]步骤S110,查获C/C++源程序中动态显存的显存管理函数,即捕获和记录C/C++源程序中动态显存的申请函数和释放函数。具体的,通过Va1grind工具提供的相关API(ApplicationProgrammingInterface,应用程序编程插口),获取应用程序中与显存相关函数的控制权。
[0036]步骤S120,在查获的显存管理函数中加入检测代码,剖析程序所申请的显存资源,猜想出显存窃取的缘由并进行监控。具体的linux c++ 内存泄露检测工具,获取执行权限之后,在查获的显存管理函数中插入插粧代码来对显存相关操作进行监控。例如对查获的显存申请函数来说,用插入一个数据结构(例如显存信息块)记录该函数中所涉及的显存相关信息,如申请显存的大小,返回给用户显存块首地址、申请的时间、当前堆栈中近来几层函数的调用地址等,检测并猜想出显存窃取的缘由。
[0037]步骤S130,根据Va1grind工具显存窃取的规则,确定系统中应用程序显存窃取的缘由并最终给出剖析报告。
[0038]按照本发明的另一方面,提供一种用于动态测量C/C++显存窃取的系统,该系统、valgrind以及C/C++源程序的关系如图2所示,检查系统查获应用程序(C/C++)中的申请函数和释放函数,插入检测代码统一进行显存管理,对于申请函数,将显存信息块加入管理列表;对于释放函数,将显存信息块从管理列表中删掉,猜想出显存窃取的缘由并进行监控。以后,借助Valgrind工具显存窃取的规则,最终确定出系统中应用程序显存窃取的缘由,并最终给出剖析报告。
[0039]如图3所示,一种用于动态测量C/C++显存窃取的系统,具体包括显存管理函数接口模块31、内存信息块管理模块32、内存泄漏检查模块33和日志输出模块34。其中显存管理函数插口模块31是测量系统和被测程序的插口模块,日志输出模块34是测量系统和用户的交互模块,显存信息块管理模块32是本发明的核心。具体阐明如下:
[0040]显存管理函数插口模块31,用于对C/C++源程序中显存管理函数进行捕获和记录,因而获得这种函数的控制权。C/C++动态显存接管在定位函数信息时,须要确认函数的符号信息,通过找到指定的符号来确定函数调用的起始处。例如,对于C++中分配动态显存的new和new[]在不同编译器中编译的符号不一样,通过编撰一段只包含new[]和deleted的小程序来查看当前编译器编译出的符号信息,在Linux环境中采用将该程序编译成汇编文件,再查找汇编文件中的指令,便可知在该编译器下对应的符号信息,在C++程序中通过查获对应的符号信息就可以获取到该函数的控制权限。
[0041]显存信息块管理模块32,用于记录C/C++源程序中申请或释放的动态显存块的相关信息的数据结构。对于不同函数族申请的显存信息块置于一个全局数组中进行管理比较混乱并且不容易分辨,因而采用以函数族为单位的管理方法来解决此问题。每一个函数族都有一个完全属于本函数族的显存信息块数组,所有的函数族表头都链成一个数组,由全局表针索引。本发明采用显存块的生命周期法解决运行过程中的显存泄露问题。采用生命周期法须要将程序中分配的所有显存信息块统一进行分组管理,以执行到显存分配函数时当前堆栈中的近来五层函数返回地址作为关键字进行分组。
[0042]结合图4和图5,可理解显存信息块的加入流程和删掉流程。如图4所示,在系统截获申请函数后,将显存信息块加入管理列表,具体流程包括:记录当前分配时间,将当前堆栈中的近来五层函数返回地址的异或值作为组号,判定该组号是否存在,假如存在,则将内存信息块加入该组并更新该组的相关信息;否则,将申请组结点空间并初始化,将该组结点加入显存信息块管理列表中,同时将显存信息块加入该组,并设置该组的相关信息。如图5所示,在系统查获释放函数后,将显存信息块从管理列表中删掉,具体流程包括:通过显存块管理信息中记录的组号,找到该显存块所在的组;估算当前显存块的生存时间(生存周期),判定该显存信息块的生存时间是否小于该组所保存的最大生命周期,倘若是,则将该组中最大生命周期更新为当前显存块的生存周期后,将该显存信息块从该组中删掉;否则,直接将该显存信息块从该组中删掉。
[0043]在好多C/C++程序中,对动态显存的申请和释放都有一定的规律性,将显存块根据函数的调用关系来分组,可以觉得同一组显存的显存块具有相像的行为,也即生存周期应该大致相同。假如有一个组中的显存块生存周期大大超过本组的其他显存块的生存周期,则可以觉得这块显存是可能泄露的显存,称为疑似泄露。显存泄露的判断,是约定当一个内存块的生存周期小于所在组中最大生命周期的两倍则将该块显存标记为疑似泄露,之后再对该显存块进行是否有读写操作的判断,假如该显存块在一段时间内都没有写操作,就认为该显存块可能是泄露的显存,将该显存块报告为泄露的显存块,类型为疑似泄露。
[0044]C/C++程序结束之后检查各个函数族中是否还有没有释放的显存信息块,假如有则表示存在显存泄露,报告显存泄露错误,显存泄露类型是确定泄露。
[0045]显存块管理的算法如下表所示:
[0048]显存泄漏检查模块33,用于对显存泄漏的类型进行监测。显存泄漏主要包括显存泄漏、内存越界访问、内存多重释放以及显存不匹配释放等错误。显存块管理模块给出显存块管理信息,显存泄漏检查模块根据valgrind的显存泄漏的判定规则和技巧,给出显存泄露的错误类型,并将错误类型报告给日志输出模块。
[0049]日志输出模块34,用于输出显存泄漏错误信息并提供可以定位到显存泄漏具体位置的信息。日志输出模块34是测量系统与用户的交互模块,显存泄漏检查模块将显存窃取错误类型报告给日志输出模块,日志输出模块根据这种信息输出显存窃取错误信息并提供可以定位到显存窃取具体位置的信息。
[0050]作为上述施行例的进一步改进,一种用于动态测量C/C++显存窃取的系统还包括应用程序函数调用跟踪模块35,用于在加入检测代码后,对动态显存使用情况进行跟踪,并将动态显存使用信息输出给显存信息块管理模块。
[0051]本发明针对C/C++程序常出现的显存泄露、内存越界访问、内存的不匹配释放等错误进行了研究,剖析了现有的显存错误检查工具和技巧,在基于开源的动态插粧框架工具Valgrind的基础上,采用函数族的显存信息块管理方式和生命周期法,实现了在Linux平台下运行的显存检查工具。该工具能有效地检查出显存泄露、内存越界访问、内存的不匹配释放等问题。
[0052]本说明书中的各个施行例均采用递进的形式描述,各个施行例之间相同相像的部分相互参见即可,每位施行例重点说明的都是与其他施行例的不同之处。尤其,对于装置或系统施行例而言,因为其基本相像于方式施行例,所以描述得比较简单,相关之处参见方式施行例的部份说明即可。以上所描述的装置及系统施行例仅仅是示意性的,其中所述作为分离部件说明的单元可以是或则也可以不是数学上分开的,作为单元显示的部件可以是或者也可以不是数学单元,即可以坐落一个地方,或则也可以分布到多个网路单元上。可以根据实际的须要选择其中的部份或则全部模块来实现本施行例方案的目的。本领域普通技术人员在不付出创造性劳动的情况下,即可以理解并施行。
[0053]以上所述仅为本发明之较佳施行例,并非用以限定本发明的权力要求保护范围。同时以上说明,对于相关技术领域的技术人员应可以理解及施行,因而其他基于本发明所阐明内容所完成的等同改变linux端口映射,均应包含在本权力要求书的涵括范围内。
【主权项】
1.一种用于动态测量C/C++显存泄漏的方式,所述方式包括如下步骤:查获C/C++源程序中动态显存的显存管理函数;在查获的显存管理函数中加入检测代码,剖析程序所申请的显存资源,猜想出显存泄露的缘由并进行监控;根据Valgrind工具显存泄漏的规则,确定系统中应用程序显存泄漏的缘由并最终给出剖析报告。2.按照权力要求1所述的一种用于动态测量C/C++显存泄漏的方式,其特点在于:通过Valgrind工具提供的相关API获取所述显存管理函数的控制权。3.按照权力要求1所述的一种用于动态测量C/C++显存泄漏的方式,其特点在于:所述检测代码为显存信息块,所述显存信息块记录所述显存管理函数中所涉及的显存相关信息,所述显存相关信息包括显存的大小,返回给用户显存块首地址、申请的时间、当前堆栈中近来几层函数的调用地址。4.一种用于动态测量C/C++显存泄漏的系统,所述系统包括显存管理函数插口模块、内存信息块管理模块、内存泄漏检查模块和日志输出模块,其中:所述显存管理函数插口模块,用于对C/C++源程序中显存管理函数进行捕获和记录,从而获得这种函数的控制权;所述显存信息块管理模块,用于记录C/C++源程序中申请或释放的动态显存块的相关信息的数据结构;所述显存泄漏检查模块,用于对显存泄漏的类型进行检查;所述日志输出模块,用于输出显存泄漏错误信息并提供可以定位到显存泄漏具体位置的信息。
5.按照权力要求4所述的一种用于动态测量C/C++显存窃取的系统,其特点在于:所述显存管理函数插口模块,具体通过查获C/C++程序中对应的符号信息来获取到该函数的控制权限。6.按照权力要求4所述的一种用于动态测量C/C++显存窃取的系统,其特点在于:每一个函数族都有一个完全属于本函数族的显存信息块数组,所有的函数族表头都链成一个链表,由全局表针索引;同时,采用生命周期法须要将程序中分配的所有显存信息块统一进行分组管理,以执行到显存分配函数时当前堆栈中的近来五层函数返回地址作为关键字进行分组。7.按照权力要求4所述的一种用于动态测量C/C++显存窃取的系统,其特点在于:在系统查获申请函数后,将显存信息块加入管理列表,具体流程包括:记录当前分配时间,将当前堆栈中的近来五层函数返回地址的异或值作为组号,判定该组号是否存在,假如存在,则将显存信息块加入该组并更新该组的相关信息;否则,将申请组结点空间并初始化,将该组结点加入显存信息块管理列表中,同时将显存信息块加入该组,并设置该组的相关信息。8.按照权力要求4所述的一种用于动态测量C/C++显存窃取的系统,其特点在于:在系统查获释放函数后,将显存信息块从管理列表中删掉,具体流程包括:通过显存块管理信息中记录的组号,找到该显存块所在的组;估算当前显存块的生存时间,判定该显存信息块的生存时间是否小于该组所保存的最大生命周期,假如是,则将该组中最大生命周期更新为当前显存块的生存周期后,将该显存信息块从该组中删掉;否则,直接将该显存信息块从该组中删掉。
9.按照权力要求4所述的一种用于动态测量C/C++显存窃取的系统,其特点在于:当一个显存块的生存周期小于所在组中最大生命周期的两倍则将该块显存标记为疑似泄露;在C/C++程序结束之后检查各个函数族中是否还有没有释放的显存信息块,假如有则表示存在显存泄露,报告显存泄露错误,显存泄露类型是确定泄露。10.按照权力要求4所述的一种用于动态测量C/C++显存窃取的系统,其特点在于:所述系统还包括应用程序函数调用跟踪模块,用于在加入检测代码后,对动态显存使用情况进行跟踪,并将动态显存使用信息输出给显存信息块管理模块。
【文档编号】G06F11/36GK105912458SQ2
【公开日】2016年8月31日
【申请日】2016年3月28日
【发明人】朱朝阳,崔宝江,韩丽芳,周亮,齐鑫蕾,单松玲,李凌,李怡康
【申请人】中国电力科学研究院,国家电网公司,上海邮电学院
文章评论