CN107133144B - 一种动态监测堆内存使用错误的内存监测装置及方法 - Google Patents

一种动态监测堆内存使用错误的内存监测装置及方法 Download PDF

Info

Publication number
CN107133144B
CN107133144B CN201710301196.1A CN201710301196A CN107133144B CN 107133144 B CN107133144 B CN 107133144B CN 201710301196 A CN201710301196 A CN 201710301196A CN 107133144 B CN107133144 B CN 107133144B
Authority
CN
China
Prior art keywords
memory
management area
monitoring device
address
monitored software
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.)
Active
Application number
CN201710301196.1A
Other languages
English (en)
Other versions
CN107133144A (zh
Inventor
赵鲁波
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.)
Shandong Inspur Business System Co Ltd
Original Assignee
Shandong Inspur Business System Co Ltd
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 Shandong Inspur Business System Co Ltd filed Critical Shandong Inspur Business System Co Ltd
Priority to CN201710301196.1A priority Critical patent/CN107133144B/zh
Publication of CN107133144A publication Critical patent/CN107133144A/zh
Application granted granted Critical
Publication of CN107133144B publication Critical patent/CN107133144B/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/30Monitoring
    • G06F11/3003Monitoring arrangements specially adapted to the computing system or computing system component being monitored
    • G06F11/3037Monitoring arrangements specially adapted to the computing system or computing system component being monitored where the computing system component is a memory, e.g. virtual memory, cache

Landscapes

  • Engineering & Computer Science (AREA)
  • Computing Systems (AREA)
  • Physics & Mathematics (AREA)
  • Theoretical Computer Science (AREA)
  • Mathematical Physics (AREA)
  • Quality & Reliability (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Debugging And Monitoring (AREA)
  • Storage Device Security (AREA)

Abstract

本发明公开了一种动态监测堆内存使用错误的内存监测装置及方法,其中内存监测装置包括内存申请接口及内存释放接口、构造函数接口、内存管理模块、析构函数接口、异常处理接口,方法则是基于该内存监测装置,通过导入运行内存中,从堆中申请内存,进行二次封装并记录管理,然后将封装后的内存地址返回给被监测软件;当被监测软件对该内存地址越界读写时,内存监测模块中止运行被监测软件并将错误信息输出;当被监测软件正常退出时,内存监测装置输出所有未释放内存的信息。本发明的一种动态监测堆内存使用错误的内存监测装置及方法与现有技术相比,执行效率高,对被监测软件的运行效率的影响很小;定位精准,对内存问题的覆盖面广。

Description

一种动态监测堆内存使用错误的内存监测装置及方法
技术领域
本发明涉及计算机技术领域,具体地说是一种动态监测堆内存使用错误的内存监测装置及方法。
背景技术
软件的可靠性对于一个系统来说至关重要,而内存问题则是影响软件可靠性的重中之中,例如非法的内存访问可能会导致系统死机,也可能会导致不可预料的运行结果,而内存泄漏则会使系统可用内存越来越少,导致系统运行越来越慢甚至会死机。因此,追踪内存错误是一个软件开发人员必不可少的工作。
常见的动态内存分析工具诸如valgrind等,由于功能过于庞大、依赖太多,导致这些工具本身就需要占用很多系统资源,再加上移植性的考虑,并不适合在一些资源紧张的嵌入式系统中使用。
另外一些现有的动态内存工具,由于设计上的原因,总是存在这样那样的缺陷,例如无法覆盖所有的内存错误,或者效率低下从而影响原软件的运行速度。
为了解决这一难题,本发明提出了种动态监测堆内存使用错误的内存监测装置及方法。
发明内容
本发明的技术任务是针对以上不足之处,提供一种动态监测堆内存使用错误的内存监测装置及方法。
一种动态监测堆内存使用错误的内存监测装置,该内存监测装置导入运行在内存中,其结构包括,
内存申请接口及内存释放接口,用于对系统默认的内存申请、释放接口进行拦截;
构造函数接口,提供整个装置被载入内存后默认执行的构造函数,并监测构造函数参数的配置初始化;
内存管理模块,用于对内存进行二次封装、管理记录;
析构函数接口,提供进程退出时默认执行的析构函数,此接口内将所有已泄露内存的详细信息显示输出给用户;
异常处理接口,提供异常处理函数,捕获到内存非法访问的异常,并将异常指令处的详细信息输出给用户。
所述内存监测装置以动态库的形式存在,配合被监测软件一并导入运行内存中,内存监测装置将被监测软件的内存申请及释放接口截获,并从堆中申请一段内存,然后对这段内存进行封装处理,再返回给调用者,即被监测软件;当被监测软件对这段内存进行非法处理时,内存监测装置检测到并及时告知用户;当被监测软件退出时,内存监测装置打印输出所有已泄露内存的信息,帮助用户进行问题定位。
所述构造函数接口提供被调用的构造函数后,进行初始化工作,其过程为:解析动态符号表,获取系统原有的内存申请及释放接口指针,并当作本装置内的私有内存接口;解析系统环境变量,获取函数栈帧深度及内存管理区的保护级别,该系统环境变量在运行本内存监测装置及被监测软件之前设置,设置的内容包括需要记录的内存对应的函数栈帧深度及保护级别,保护级别分为不可读写、只读、可读写三种级别;初始化全局双向链表,用于将来记录内存地址。
一种动态监测堆内存使用错误的方法,其实现过程为:
一、首先将内存监测装置导入运行内存中,截获被监测软件的内存申请函数及内存释放函数的调用;
二、内存监测装置从堆中申请内存,进行二次封装并记录管理,然后将封装后的内存地址返回给被监测软件;
三、当被监测软件对该内存地址进行越界读写时,内存监测模块立刻让被监测软件中止运行并将错误信息输出给软件调试人员;当被监测软件正常退出时,内存监测装置自动将所有尚未释放的内存的详细信息显示输出给软件调试人员。
运行被监测软件时,将内存监测装置动态插入被监测软件的运行地址空间;内存监测装置通过动态符号表的重定位功能,拦截所有申请内存及释放内存相关的系统接口,将本监测装置内的内存分配及释放接口替换掉被监测软件的原内存申请及释放接口地址。
步骤二中,当被监测软件运行至内存进行分配调用时,内存监测装置截获该调用,得到申请内存的大小,然后通过本内存监测装置内部私有的内存申请接口,从堆内存中申请一段可容纳前置管理区、用户申请内存大小及后置管理区的内存,即这块内存分成三段:前置管理区、即将返回给被监测软件的用户内存区、后置管理区,其中前置管理区、后置管理区均包括不可读写、只读、可读写三种保护级别;前置管理区及后置管理区用于对内存区用户内存区进行二次封装,其中前置管理区位于用户内存区的起始地址的左侧,后置管理区位于用户内存区的结束地址的右侧;所述内存监测装置将申请该内存的函数的堆栈信息、用户内存区大小、魔数字存入前置管理区,然后将用户内存区的首地址插入一个全局的双向链表,在前置管理区中记录用户内存区在双向链表中的节点指针;最后将魔数字存储在后置管理区;内存监测装置将前置管理区及后置管理区设置为不可读写的权限;最后内存监测装置将内存地址用户内存区返回给被监测软件。
步骤二中,前置管理区、后置管理区存储信息的具体过程为:
将从堆中申请的这段内存的起始地址填入前置管理区的相应位置;
将固定的魔数字填入前置管理区和后置管理区的相应位置;
根据函数栈帧深度,申请一段内存,获取当前函数栈的相关信息,然后将这段内存的起始地址填入前置管理区的相应位置;
把即将返回给被监测软件的内存地址,加入全局的双向链表中,并将对应的链表节点指针存入前置管理区的相应位置;
设置前置管理区及后置管理区的内存访问权限;
将用户内存区的起始地址返回给被监测软件。
步骤三中,当内存监测装置拦截到释放内存的系统接口调用时,根据传入的内存地址,即用户内存区存储内容,得到相应的前置内存管理区地址,将前后管理区的内存访问权限改成可读写,然后从前置内存管理区地址中查找到记录用户内存区的双向链表的节点指针,再将用户内存区从双向链表中删除,最后释放该内存;
当被监测软件对用户内存区的访问发生越界时,触发系统信号,使得被监测软件中止运行,内存监测装置捕获到中止运行的信号,然后将当前的函数调用栈信息显示输出给软件调试人员;
当进程正常退出时,内存监测装置在析构函数中,将全局双向链表中的所有未释放内存的详细信息显示出来,软件调试人员便可以得知哪些地方发生了内存泄漏。
当被监测软件调用内存释放接口时,内存监测装置将截获其接口调用,得到被释放内存的起始地址,并对该内存地址做如下判断及操作:
step1,将该内存地址对应的前置管理区、后置管理区的内存访问权限修改为可读写模式;
step2,判断前置及后置管理区内的魔数字是否与默认的值一致,如果不一致,说明被监测软件传入的这段内存不是一个合法申请的内存地址,输出错误信息给软件调试人员;如果一致,则执行step3;
step3,判断前置管理区的链表节点指针是否为空,如果为空,说明这段内存已经被释放过了,被监测软件执行了错误的二次释放,输出错误信息给软件调试人员;如果不为空,则根据链表节点指针快速定位到双向链表中的节点,并将该节点从双向链表中删除,然后将前置管理区的链表节点指针置为空;
step4,得到前置管理区的起始地址,然后调用内存监测装置内的私有接口来释放这段内存。
当被监测软件对已申请的内存地址发生访问越界时,触发系统异常,进入内存监测装置内的异常处理函数,异常处理函数根据包括异常地址、栈顶地址的寄存器值,解析并输出显示当前的函数栈详细信息给软件调试人员,该详细信息包括文件名称、函数名称、调用行数;
当被监测软件正常退出时,内存监测装置的析构函数被调用,析构函数内部,遍历全局双向链表的所有节点,显示每个内存的详细信息,包括内存地址、内存大小;
根据前置管理区内的起始地址中的每一个返回地址,在动态符号表中解析出对应的文件名、函数名、所在行数。
本发明的一种动态监测堆内存使用错误的内存监测装置及方法和现有技术相比,具有以下有益效果:
本发明的一种动态监测堆内存使用错误的内存监测装置及方法,首先不用修改被监测软件的原二进制文件,也即不用重新编译被监测软件;其次在于可仅在需要的时候再将内存监测装置导入进程内;被监测的内存通过前后两个管理区信息,实现了内存错误的精准定位;前置管理区内的链表节点指针设计,巧妙的实现了用户内存地址在全局双向链表中的快速定位,避免了遍历链表带来的系统开销,从而不会对被监测软件的性能产生较大影响;实现了函数调用栈的详细记录;实现了对内存的读写越界的监测;体积精简,可移植性好;执行效率高,对被监测软件的运行效率的影响很小;定位精准,对内存问题的覆盖面广,实用性强,适用范围广泛,具有很好的推广应用价值。
附图说明
附图1为本发明实施例中方法的实现示意图。
具体实施方式
下面结合附图及具体实施例对本发明作进一步说明。
一种动态监测堆内存使用错误的内存监测装置,该内存监测装置导入运行在内存中,其结构包括,
内存申请接口及内存释放接口,用于对系统默认的内存申请、释放接口进行拦截;
构造函数接口,提供整个装置被载入内存后默认执行的构造函数,并监测构造函数参数的配置初始化;
内存管理模块,用于对内存进行二次封装、管理记录;
析构函数接口,提供进程退出时默认执行的析构函数,此接口内将所有已泄露内存的详细信息显示输出给用户;
异常处理接口,提供异常处理函数,捕获到内存非法访问的异常,并将异常指令处的详细信息输出给用户。
所述内存监测装置作为一个独立的文件,一般以动态库的形式存在,可用不同的编译工具链编译生成运行在不同平台上的版本,在用户需要用来监测某个软件的内存问题时,系统将本内存监测装置与被监测软件一并导入运行内存中,本内存监测装置会将被监测软件的内存申请及释放接口截获,本装置则利用其它方法从堆中申请足够大的内存,然后对这段内存进行封装处理,再返回给调用者(被监测软件);当被监测软件对这段内存进行非法处理时,本内存监测装置能立刻检测到并及时告知用户;当被监测软件退出时,本装置将打印输出所有已泄露内存的详细信息,帮助用户进行问题定位。
所述构造函数接口提供被调用的构造函数后,进行初始化工作,其过程为:解析动态符号表,获取系统原有的内存申请及释放接口指针,并当作本装置内的私有内存接口;解析系统环境变量,获取函数栈帧深度及内存管理区的保护级别,该系统环境变量在运行本内存监测装置及被监测软件之前设置,设置的内容包括需要记录的内存对应的函数栈帧深度及保护级别,保护级别分为不可读写、只读、可读写三种级别;初始化全局双向链表,用于将来记录内存地址。
一种动态监测堆内存使用错误的方法,其实现过程为:
针对堆内存heap使用错误问题,在不修改被监测软件的二进制文件的前提下向运行内存中插入监测装置;截获被监测软件的内存申请函数及内存释放函数的调用;
内存监测装置从堆中申请内存进行二次封装并记录管理,然后将封装后的内存地址返回给被监测软件;
当被监测软件对该内存地址进行越界读写时,内存监测模块立刻让被监测软件中止运行并将错误信息输出给软件调试人员;
当被监测软件正常退出时,内存监测装置自动将所有尚未释放的内存的详细信息显示输出给软件调试人员。
即:
在不修改被监测软件的原始二进制文件的前提下,运行被监测软件时,将内存监测装置动态插入被监测软件的运行地址空间;
内存监测装置利用动态符号表的重定位功能,拦截所有申请内存及释放内存相关的系统接口;
内存监测装置拦截到申请内存的系统接口调用之后,从堆中申请一段更大的内存,将这块内存分成三段:前置管理区PRE_MM_ZONE、即将返回给调用者的用户内存区MEM_FOR_USER、后置管理区POST_MM_ZONE,PRE_MM_ZONE及POST_MM_ZONE的用途是对内存区MEM_FOR_USER进行二次封装,其中PRE_MM_ZONE位于MEM_FOR_USER的起始地址的左侧(更低地址处),POST_MM_ZONE位于MEM_FOR_USER的结束地址的右侧(更高地址处);
内存监测装置将申请该内存的函数调用栈信息、用户内存区大小、魔数字等存入PRE_MM_ZONE,然后将MEM_FOR_USER的首地址插入一个全局的双向链表,然后在PRE_MM_ZONE中记录MEM_FOR_USER在双向链表中的节点指针;最后将魔数字存储POST_MM_ZONE;
内存监测装置将前置管理区PRE_MM_ZONE及后置管理区POST_MM_ZONE设置为不可读写的权限;
内存监测装置将内存地址MEM_FOR_USER返回给调用者;
当内存监测装置拦截到释放内存的系统接口调用时,根据传入的内存地址(MEM_FOR_USER)计算得到相应的前置内存管理区地址,首先将前后管理区的内存访问权限改成可读写,然后从前置内存管理区地址中查找到记录MEM_FOR_USER的双向链表的节点指针,然后将MEM_FOR_USER从双向链表中删除,然后释放该内存;
当被监测软件对MEM_FOR_USER的访问发生越界时,比如试图读写PRE_MM_ZONE或者POST_MM_ZONE中的内容,由于这段内存没有读写权限,将触发系统信号,使得被监测软件中止运行,内存监测装置中能够及时捕获到中止运行的信号,然后将当前的函数调用栈信息显示输出给软件调试人员;
当进程正常退出时,内存监测装置会在析构函数中,将全局双向链表中的所有未释放内存的详细信息显示出来,软件调试人员便可以得知哪些地方发生了内存泄漏。
内存监测装置的关键参数可手工配置,包括函数栈的层数、当发生读越界时是否触发系统信号;当被监测软件退出时,可自动打印显示当前所有已泄漏内存的详细信息,包括调用者的函数栈信息,内存大小等;
内存监测装置在对即将返回给调用者的内存地址进行二次封装时,函数调用栈信息仅存储了返回地址,而没有存储所在文件名称、函数名称及所在行数,这保证了被监测软件的运行效率;当且仅当需要列举打印当前所有未释放内存的信息时,才将函数返回地址通过动态符号表来转换成文件名称+函数名称+所在行数的字符串,然后输出到终端。
结合附图1,本发明的具体执行步骤如下:
(1)运行本内存监测装置及被监测软件之前,通过系统环境变量设置如下参数:
需要记录的内存对应的函数栈帧深度,也即图1中的”frame depth”;
前置管理区PRE_MM_ZONE及后置管理区POST_MM_ZONE的保护级别(或者说访问权限),分为不可读写、只读、可读写三种级别。
(2)用户运行被监测软件,并通过系统命令将本装置插入被监测软件的运行内存中,本监测装置内的内存分配/释放接口将替换掉被监测软件的原内存申请/释放接口地址。
(3)本监测装置的构造函数被调用,进行初始化工作,包括:解析动态符号表,获取系统原有的内存申请/释放接口指针,当作本装置内的私有内存接口;解析系统环境变量,获取函数栈帧深度及内存管理区的保护级别;初始化全局双向链表,用于将来记录内存地址。
(4)当被监测软件运行至内存分配调用时,本内存监测装置将截获该调用,得到申请内存的大小,然后利用本装置内部私有的内存申请接口,从堆内存中申请一段足够容纳前置管理区、用户申请内存大小及后置管理区的内存。然后做如下操作:
step1,将从堆中申请的这段内存的起始地址填入前置管理区的相应位置,也即图1的ptr_real;
step2,将固定的魔数字填入前置管理区和后置管理区的相应位置,也即图1的magic number;
step3,根据函数栈帧深度,申请一段内存,获取当前函数栈的相关寄存器值,按照函数栈帧结构来循环解析得到每一层函数栈的返回地址,并依次填入这段内存(请见图1的address 0~n),然后将这段内存的起始地址填入前置管理区的相应位置,也即图1的frameinfos;
step4,把即将返回给调用者的内存地址,也即图1的MEM_FOR_USER的起始地址,加入全局的双向链表中,并将对应的链表节点指针存入前置管理区的相应位置,也即图1的list node ptr;
step5,设置前置管理区及后置管理区的内存访问权限;
step6,将MEM_FOR_USER的起始地址返回给调用者。
(5)当被监测软件调用内存释放接口时,本内存监测装置将截获其接口调用,得到被释放内存的起始地址,并对该内存地址做如下判断及操作:
step1,将该内存地址对应的前置管理区、后置管理区的内存访问权限修改为可读写模式;
step2,判断前置及后置管理区内的magic number是否与默认的值一致,如果不一致,说明被监测软件传入的这段内存不是一个合法申请的内存地址,输出错误信息给软件调试人员;如果一致,则执行step3;
step3,判断前置管理区的链表节点指针(也即图1的list node ptr)是否为空,如果为空,说明这段内存已经被释放过了,被监测软件执行了错误的二次释放,输出错误信息给软件调试人员;如果不为空,则根据list node ptr快速定位到双向链表中的节点,并将该节点从双向链表中删除,然后将前置管理区的list node ptr置为空;
step4,得到前置管理区的起始地址,也即图1的ptr_real,然后调用本装置内的私有接口来释放这段内存。
(6)当被监测软件对已申请的内存地址发生访问越界时,例如访问到了前置管理区或者后置管理区,如果访问权限不允许,则会触发系统异常,进入本装置内的异常处理函数,异常处理函数内会根据相关寄存器如异常地址、栈顶地址等值,解析并输出显示当前的函数栈详细信息给软件调试人员,包括文件名称、函数名称、调用行数等。
(7)当被监测软件正常退出时,本内存监测装置的析构函数被调用,析构函数内部,会遍历全局双向链表的所有节点,显示每个内存的详细信息,包括:
内存地址,内存大小;
根据前置管理区内的frame infos中的每一个返回地址address,在动态符号表中解析出对应的文件名,函数名,所在行数。
本方案不局限于某个芯片架构或某种操作系统,现在以基于ARM架构的嵌入式Linux系统为例,提供一种实施方案,具体实施步骤:
1)以C语言作为本发明装置的编程语言,将最终代码用arm的交叉编译工具编译生成动态库libmmonitor.so。
2)在libmmonitor.so内部,将至少实现如下函数:
__attribute__ ((constructor)) void mm_init(void) 本函数是进程运行时的构造函数;
void* malloc(int size) 本函数将用来截获原系统库的malloc函数;
void free(void*p) 本函数将用来截获原系统库的free函数;
__attribute__ ((destructor)) void mm_uninit (void) 本函数是进程退出时的析构函数;
void sig_handler(int sig, siginfo_t *info, void *secret) 本函数作为异常处理函数,当被监测软件发生内存访问越界时,将进入本函数内。
3)对于前置管理区及后置管理区,可用结构体来定义,如下:
typedef struct
{
int user_size;
void* list_node_ptr;
unsigned long* frame_infos;
int frame_depth;
void* ptr_real;
unsigned int magic_number;
}PreMMZone_t;
typedef struct
{
unsigned int magic_number;
}PostMMZone_t。
运行被监测软件及本装置之前,可设置环境变量如下:
export MMONITOR_FRAME_DEPTH=8 表示对每个内存地址,最多记录8层函数返回地址
export MMONITOR_MEM_ACCESS=0 表示将前置/后置管理区将设置成不可读写的权限,我们可假定0代表不可读写,1代表只读,2代表可读写;
5)利用LD_PRELOAD来加载本装置的动态库文件libmmonitor.so及被监测的软件;
6)在被监测软件的main函数入口执行之前,本装置的构造函数mm_init将被执行,在本函数内部,将做如下操作:
利用getenv函数解析环境变量,并将其保存到相关的全局变量中;
利用dlsym函数解析获得系统默认的malloc及free接口的符号指针,以实现本装置内部私有的内存函数_priv_malloc及_priv_free;
7)当被监测软件调用malloc(SIZE)时,实际上调用到本装置内的malloc函数内,函数内有如下操作:
根据SIZE值、结构体PreMMZone_t的大小、PostMMZone_t的大小等,再考虑到地址对其问题,综合计算出实际要分配的内存大小,调用_priv_malloc来分配一段内存记为real_mem_ptr,并计算出即将返回给调用者的内存地址记为user_ptr;
分配一段内存并利用backtrace函数获取当前的栈帧的多层返回地址并存入这段内存,将这段内存的首地址存入结构体PreMMZone_t中;
将real_mem_ptr插入全局的双向链表,对应的链表节点指针记为curr_node;
将curr_node赋给结构体PreMMZone_t的成员list_node_ptr;
将前置管理区及后置管理区的结构体其它成员赋值;
利用mprotect函数对前置管理区、后置管理区的相关内存范围进行访问权限设置;
将user_ptr作为malloc的返回值返回;
8)当被监测软件调用free(user_ptr)时,实际上调用到了本装置的free函数内,函数内有如下操作:
step1,利用mprotect函数对user_ptr的前置管理区及后置管理区进行权限修改,改成可读写模式;
step2,判断结构体内的magic_number是否与默认值一致,如果不一致,说明被监测软件传入的这段内存不是一个合法申请的内存地址,输出错误信息给软件调试人员;
step3,判断PreMMZone_t的成员list_node_ptr是否为空,如果为空,说明该内存地址发生了二次释放,输出错误信息给软件调试人员;如果不为空,则根据list_node_ptr快速定位到双向链表中的节点,并将该节点从双向链表中删除,然后将前置管理区的list_node_ptr置为空;
step4,得到前置管理区的成员ptr_real,调用本装置内的私有接口_priv_free来释放该地址。
9)当被监测软件对已申请的内存地址发生访问越界时,例如访问到了前置管理区或者后置管理区,如果访问权限不允许,则会触发系统异常,进入本装置内的异常处理函数sig_handler,函数内会利用backtrace系列系统函数解析并输出显示当前的函数栈详细信息给软件调试人员,包括文件名称、函数名称、调用行数等。
10)当被监测软件正常退出时,本内存监测装置的析构函数mm_uninit 被调用,mm_uninit 内部会遍历全局双向链表的所有节点,显示每个内存的详细信息,包括:
内存地址,内存大小;
根据每个内存地址的前置管理区内的frame_infos指向的数组中的每一个返回地址,在动态符号表中解析出对应的文件名,函数名,所在行数,并显示输出给软件调试人员。
通过上面具体实施方式,所述技术领域的技术人员可容易的实现本发明。但是应当理解,本发明并不限于上述的具体实施方式。在公开的实施方式的基础上,所述技术领域的技术人员可任意组合不同的技术特征,从而实现不同的技术方案。
除说明书所述的技术特征外,均为本专业技术人员的已知技术。

Claims (10)

1.一种动态监测堆内存使用错误的内存监测装置,其特征在于,该内存监测装置导入运行在内存中,其结构包括,
内存申请接口及内存释放接口,用于对系统默认的内存申请、释放接口进行拦截;
构造函数接口,提供整个装置被载入内存后默认执行的构造函数,并监测构造函数参数的配置初始化;
内存管理模块,用于对内存进行二次封装、管理记录;
析构函数接口,提供进程退出时默认执行的析构函数,此接口内将所有已泄露内存的详细信息显示输出给用户;
异常处理接口,提供异常处理函数,捕获到内存非法访问的异常,并将异常指令处的详细信息输出给用户。
2.根据权利要求1所述的动态监测堆内存使用错误的内存监测装置,其特征在于,所述内存监测装置以动态库的形式存在,配合被监测软件一并导入运行内存中,内存监测装置将被监测软件的内存申请及释放接口截获,并从堆中申请一段内存,然后对这段内存进行封装处理,再返回给调用者,即被监测软件;当被监测软件对这段内存进行非法处理时,内存监测装置检测到并及时告知用户;当被监测软件退出时,内存监测装置打印输出所有已泄露内存的信息,帮助用户进行问题定位。
3.根据权利要求1或2所述的动态监测堆内存使用错误的内存监测装置,其特征在于,所述构造函数接口提供被调用的构造函数后,进行初始化工作,其过程为:解析动态符号表,获取系统原有的内存申请及释放接口指针,并当作本装置内的私有内存接口;解析系统环境变量,获取函数栈帧深度及内存管理区的保护级别,该系统环境变量在运行本内存监测装置及被监测软件之前设置,设置的内容包括需要记录的内存对应的函数栈帧深度及保护级别,保护级别分为不可读写、只读、可读写三种级别;初始化全局双向链表,用于将来记录内存地址。
4.一种动态监测堆内存使用错误的方法,其特征在于,其实现过程为:
一、首先将内存监测装置导入运行内存中,截获被监测软件的内存申请函数及内存释放函数的调用;
二、内存监测装置从堆中申请内存,进行二次封装并记录管理,然后将封装后的内存地址返回给被监测软件;
三、当被监测软件对该内存地址进行越界读写时,内存监测模块立刻让被监测软件中止运行并将错误信息输出给软件调试人员;当被监测软件正常退出时,内存监测装置自动将所有尚未释放的内存的详细信息显示输出给软件调试人员。
5.根据权利要求4所述的一种动态监测堆内存使用错误的方法,其特征在于,运行被监测软件时,将内存监测装置动态插入被监测软件的运行地址空间;内存监测装置通过动态符号表的重定位功能,拦截所有申请内存及释放内存相关的系统接口,将本监测装置内的内存分配及释放接口替换掉被监测软件的原内存申请及释放接口地址。
6.根据权利要求4或5所述的一种动态监测堆内存使用错误的方法,其特征在于,步骤二中,当被监测软件运行至内存进行分配调用时,内存监测装置截获该调用,得到申请内存的大小,然后通过本内存监测装置内部私有的内存申请接口,从堆内存中申请一段可容纳前置管理区、用户申请内存大小及后置管理区的内存,即这块内存分成三段:前置管理区、即将返回给被监测软件的用户内存区、后置管理区,其中前置管理区、后置管理区均包括不可读写、只读、可读写三种保护级别;前置管理区及后置管理区用于对用户内存区进行二次封装,其中前置管理区位于用户内存区的起始地址的左侧,后置管理区位于用户内存区的结束地址的右侧;所述内存监测装置将申请该内存的函数的堆栈信息、用户内存区大小、魔数字存入前置管理区,然后将用户内存区的首地址插入一个全局的双向链表,在前置管理区中记录用户内存区在双向链表中的节点指针;最后将魔数字存储在后置管理区;内存监测装置将前置管理区及后置管理区设置为不可读写的权限;最后内存监测装置将用户内存区的内存地址返回给被监测软件。
7.根据权利要求6所述的一种动态监测堆内存使用错误的方法,其特征在于,步骤二中,前置管理区、后置管理区存储信息的具体过程为:
将从堆中申请的这段内存的起始地址填入前置管理区的相应位置;
将固定的魔数字填入前置管理区和后置管理区的相应位置;
根据函数栈帧深度,申请一段内存,获取当前函数栈的相关信息,然后将这段内存的起始地址填入前置管理区的相应位置;
把即将返回给被监测软件的内存地址,加入全局的双向链表中,并将对应的链表节点指针存入前置管理区的相应位置;
设置前置管理区及后置管理区的内存访问权限;
将用户内存区的起始地址返回给被监测软件。
8.根据权利要求6所述的一种动态监测堆内存使用错误的方法,其特征在于,步骤三中,当内存监测装置拦截到释放内存的系统接口调用时,根据传入的内存地址,即用户内存区存储内容,得到相应的前置管理区的内存地址,将前置管理区、后置管理区的内存访问权限改成可读写,然后从前置管理区的内存地址中查找到记录用户内存区的双向链表的节点指针,再将用户内存区从双向链表中删除,最后释放该内存;
当被监测软件对用户内存区的访问发生越界时,触发系统信号,使得被监测软件中止运行,内存监测装置捕获到中止运行的信号,然后将当前的函数调用栈信息显示输出给软件调试人员;
当进程正常退出时,内存监测装置在析构函数中,将全局双向链表中的所有未释放内存的详细信息显示出来,软件调试人员便可以得知哪些地方发生了内存泄漏。
9.根据权利要求8所述的一种动态监测堆内存使用错误的方法,其特征在于,当被监测软件调用内存释放接口时,内存监测装置将截获其接口调用,得到被释放内存的起始地址,并对该被释放内存的起始地址做如下判断及操作:
step1,将该被释放内存的起始地址对应的前置管理区、后置管理区的内存访问权限修改为可读写模式;
step2,判断前置管理区及后置管理区内的魔数字是否与默认的值一致,如果不一致,说明被监测软件传入的这段内存不是一个合法申请的被释放内存的起始地址,输出错误信息给软件调试人员;如果一致,则执行step3;
step3,判断前置管理区的链表节点指针是否为空,如果为空,说明这段内存已经被释放过了,被监测软件执行了错误的二次释放,输出错误信息给软件调试人员;如果不为空,则根据链表节点指针快速定位到双向链表中的节点,并将该节点从双向链表中删除,然后将前置管理区的链表节点指针置为空;
step4,得到前置管理区的起始地址,然后调用内存监测装置内的私有接口来释放这段内存。
10.根据权利要求8所述的一种动态监测堆内存使用错误的方法,其特征在于,当被监测软件对已申请的内存地址发生访问越界时,触发系统异常,进入内存监测装置内的异常处理函数,异常处理函数根据包括异常地址、栈顶地址的寄存器值,解析并输出显示当前的函数栈详细信息给软件调试人员,该详细信息包括文件名称、函数名称、调用行数;
当被监测软件正常退出时,内存监测装置的析构函数被调用,析构函数内部,遍历全局双向链表的所有节点,显示每个内存的详细信息,包括内存地址、内存大小;
根据前置管理区内的起始地址中的每一个返回地址,在动态符号表中解析出对应的文件名、函数名、所在行数。
CN201710301196.1A 2017-05-02 2017-05-02 一种动态监测堆内存使用错误的内存监测装置及方法 Active CN107133144B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201710301196.1A CN107133144B (zh) 2017-05-02 2017-05-02 一种动态监测堆内存使用错误的内存监测装置及方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201710301196.1A CN107133144B (zh) 2017-05-02 2017-05-02 一种动态监测堆内存使用错误的内存监测装置及方法

Publications (2)

Publication Number Publication Date
CN107133144A CN107133144A (zh) 2017-09-05
CN107133144B true CN107133144B (zh) 2020-03-17

Family

ID=59716232

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201710301196.1A Active CN107133144B (zh) 2017-05-02 2017-05-02 一种动态监测堆内存使用错误的内存监测装置及方法

Country Status (1)

Country Link
CN (1) CN107133144B (zh)

Families Citing this family (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN107943681A (zh) * 2017-12-08 2018-04-20 郑州云海信息技术有限公司 内存占用情况分析方法、装置、设备及计算机存储介质
CN108874602B (zh) * 2018-06-15 2021-10-22 郑州云海信息技术有限公司 一种自动设置和配置imdt并收集信息的方法及系统
CN110780818B (zh) * 2019-10-24 2023-05-30 山东浪潮科学研究院有限公司 一种基于量子测控系统软件读取任意数据的文件实现方法
CN110764914B (zh) * 2019-10-28 2022-09-20 锐捷网络股份有限公司 内存改写的定位方法及装置
CN111813641B (zh) * 2020-06-19 2024-05-17 北京字节跳动网络技术有限公司 崩溃信息收集的方法、装置、介质和设备
CN112650645B (zh) * 2020-12-24 2023-05-30 大连市共进科技有限公司 堆内存使用情况监测方法、装置和5g基站设备

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP1256904B1 (fr) * 2001-05-07 2006-11-15 Dan Serbanescu Carte et lecteur sans contacts à deux niveaux de sécurité physique de communication
CN101814049A (zh) * 2010-03-23 2010-08-25 北京大学 一种内存泄漏探测方法
CN105912458A (zh) * 2016-03-28 2016-08-31 中国电力科学研究院 一种用于动态检测c/c++内存泄露的方法及系统

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP1256904B1 (fr) * 2001-05-07 2006-11-15 Dan Serbanescu Carte et lecteur sans contacts à deux niveaux de sécurité physique de communication
CN101814049A (zh) * 2010-03-23 2010-08-25 北京大学 一种内存泄漏探测方法
CN105912458A (zh) * 2016-03-28 2016-08-31 中国电力科学研究院 一种用于动态检测c/c++内存泄露的方法及系统

Non-Patent Citations (2)

* Cited by examiner, † Cited by third party
Title
利用虚拟化平台进行内存泄露探测;汪小林等;《计算机学报》;20100331;第33卷(第03期);全文 *
有效实现内存管理的方法;潘立登等;《北京化工大学学报》;20001231;第27卷(第03期);全文 *

Also Published As

Publication number Publication date
CN107133144A (zh) 2017-09-05

Similar Documents

Publication Publication Date Title
CN107133144B (zh) 一种动态监测堆内存使用错误的内存监测装置及方法
US6634020B1 (en) Uninitialized memory watch
US9727436B2 (en) Adding a profiling agent to a virtual machine to permit performance and memory consumption analysis within unit tests
US8539452B2 (en) Virtual machine tool interface for tracking objects
US7661035B2 (en) Method and system for instruction tracing with enhanced interrupt avoidance
CN107066390B (zh) 一种动态内存泄漏检测方法及系统
US8887141B2 (en) Automatically modifying a native code module accessed from virtual machine bytecode to determine execution information
US20070234296A1 (en) Software variation for robustness through randomized execution contexts
US9459991B2 (en) Heap dump object identification in a heap dump analysis tool
TW201335752A (zh) 記憶體檢測系統及方法
US20060277371A1 (en) System and method to instrument references to shared memory
US7434020B2 (en) Overwrite detection diagnostic for memory heap
CN111506500B (zh) 内存泄露检测方法、装置、电子设备及可读存储介质
CN100392606C (zh) 一种定位虚拟操作系统内存泄漏的方法
CN104461880B (zh) 一种嵌入式系统中自动检测内存越界的方法及系统
US20240095174A1 (en) Method for detecting error of operating system kernel memory in real time
US20040015864A1 (en) Method and system for testing memory operations of computer program
Seo et al. A profiling method by PCB hooking and its application for memory fault detection in embedded system operational test
US7657792B2 (en) Identifying race conditions involving asynchronous memory updates
US7350045B2 (en) Dynamic memory heap tagging
CN113987507A (zh) 堆内存漏洞检测方法、装置、存储介质及电子设备
US20130305099A1 (en) Method, system, and computer program product
CN117149644A (zh) 内存溢出检测方法、装置、操作系统、设备及存储介质
US20090172368A1 (en) Hardware Based Runtime Error Detection
CN114065208A (zh) 一种面向堆内存错误的检测方法及装置

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