一种应用程序故障的定位方法技术

技术编号:2855939 阅读:267 留言:0更新日期:2012-04-11 18:40
本发明专利技术公开一种应用程序故障的定位方法,包括以下步骤:应用程序编译时,为自编码函数做一个在入口处调用的钩子函数;程序启动后,建立该程序的进程共享内存区,并为每一个线程分配线程共享内存区;运行到所述自编码函数时调用钩子函数,将当前的执行指令地址标记(EIP)和当前运行函数返回地址标记(RET)压入相应线程共享内存区的堆栈区,并将程序堆栈中的RET修改为隐式调用函数的入口地址;函数返回时自动调用隐式调用函数,将压入的EIP和RET弹出,并恢复程序堆栈的RET;程序发生故障退出后,根据所述堆栈区的当前指针可获得应用程序正在运行的函数和嵌套层次,即使应用程序堆栈被破坏,也能实现对故障的准确定位。

【技术实现步骤摘要】

本专利技术涉及计算机领域中的基于Microsoft Windows操作系统的C语言应用软件开发,尤其涉及一种应用程序故障的查错方法。
技术介绍
由于Microsoft Windows操作系统在个人电脑的广泛应用,大量的软件企业开发了越来越多的Windows应用程序,很多应用是使用C语言开发的,由于软件开发者的技能水平和程序的复杂程度不同,不少程序代码中会有这样或那样的BUG(故障),严重的BUG可能导致应用程序死掉。现在比较通用的查错方法是使用WINDOWS提供的结构化异常处理或运行调试版本,很多非法地址访问、DIV BY ZERO(被0除)等异常都可以捕获。现有的查错方法是在程序产生故障导致程序退出时,从程序的堆栈中查找当前的EIP(执行指令地址)和RET(返回地址)来判断具体在哪个函数中运行出错,从而实现定位。但是,即使在调试的环境下,由于有些BUG会将程序的堆栈修改,例如函数局部变量的使用不当有可能导致堆栈区的非法修改,现有的这些方法就很难有所作为了,特别是一些作为服务运行的程序需要长时间运行,出了问题难以定位故障的原因。
技术实现思路
本专利技术所要解决的技术问题是提供,能够定位包括堆栈被破坏在内的更多的故障。为了解决上述技术问题,本专利技术提供了,包括以下步骤(a)在应用程序编译时,为每一个自编码函数做一个在函数入口处调用的钩子函数,并提供一个在自编码函数返回时调用的隐式调用函数; (b)该应用程序启动后,建立该应用程序的进程共享内存区,在该进程共享内存区中为该应用程序的每一个线程分配一个线程共享内存区;(c)该应用程序运行到所述自编码函数时调用该钩子函数;(d)该钩子函数取得当前执行指令的地址标记和当前运行函数的返回地址标记,压入相应线程共享内存区的堆栈区,同时将该应用程序堆栈中当前运行函数的返回地址修改为该隐式调用函数的入口地址;(e)当前运行函数返回时自动调用该隐式调用函数,该隐式调用函数将压入的当前执行指令的地址标记和当前运行函数的返回地址标记弹出,并在该应用程序堆栈区中恢复当前运行函数的返回地址;(f)程序继续运行,在每一自编码函数调用均采用步骤(c)到步骤(d)的方法处理,如果程序正常退出,释放该应用程序的进程共享内存区,结束;如果发生故障退出,执行下一步;(g)保存该应用程序的进程共享内存的数据,根据所述堆栈区的当前指针获得应用程序正在运行的函数和嵌套层次,对故障进行准确定位。进一步地,为了获取发生故障时的上下文信息,所述步骤(d)中,还将当前执行指令的地址标记依序保存到相应线程共享内存区的链表区,步骤(g)中,还对该链表区数据分析,获得该线程最近执行过的函数。进一步地,为了在正常的运行环境下也能实现对应用程序故障的定位,可采用跟踪动态库来实现上述处理,即所述步骤(a)之前先建立一个包含所述钩子函数和隐式调用函数实现代码的跟踪动态库,所述应用程序在编译时静态连接该跟踪动态库,实现对所述钩子函数的调用,在该应用程序启动后,该动态库在处理进程建立消息和线程建立消息时分别创建所述进程共享内存区和线程共享内存区。进一步地,为了实现对是否启动故障定位的选择,在所述步骤(c)中,所述钩子函数还检查所述进程共享内存区中的标记字,判断是否启动故障定位,如果启动,再执行步骤(d),如果不启动,直接执行步骤(f)。进一步地,上述定位方法可具有以下特点所述动态库在处理进程建立消息和线程建立消息时还分别建立线程局部存储标识和对应的各线程唯一标识,各线程唯一标识又对应于各自的线程共享内存区,所述钩子函数和隐式调用函数是通过所述线程局部存储标识找到相应的线程唯一标识,再找到该线程的共享内存区的。进一步地,为了实现对多个应用程序的管理,在步骤(b)建立所述进程共享内存区后,还可将该应用程序的名称注册到一个管理共享内存区,并记录该应用程序名称与该应用程序进程共享内存区的对应关系。该管理共享内存可由所述动态库创建,或者由一个管理程序创建。进一步地,上述定位方法可具有以下特点所述步骤(g)中可由一个管理程序定时检测所述管理共享内存区内各应用程序的运行状态,如果某一应用程序不再运行,则根据该应用程序名称找到该应用程序的进程共享内存区并保存其数据。进一步地,为了减少对应用程序的改动,在步骤(a)编译时可采用支持在每个函数入口自动调用钩子函数的编译器,并在跟踪动态库中将钩子函数命名为该编译器为该自动调用的钩子函数指定的名称。与现有技术Windows中提供的结构化异常处理和调试版本调试环境相比,本专利技术应用程序故障的定位方法具有以下优点A,通过建立共享内存,能够定位更多的异常,例如堆栈破坏的异常;B,通过在共享内存中建立堆栈区,能够显示故障时函数的嵌套情况;C,通过使用windows动态连接库,能够在正常的运行环境中定位应用程序故障;D,通过在建立多个线程共享内存区,能够对多线程的应用程序进行准确定位;E,由于在链表区按顺序记录了最近执行过的函数,所以能够得到更多的上下文信息;F,对于被跟踪的应用程序的改动很少,编译器支持启用_penter钩子函数时,只需要在跟踪动态库增加钩子函数_penter的实现代码即可;G,采用隐式调用函数来将当前运行函数的EIP和RET弹出堆栈,避免了显示函数调用时须在函数每一个RETURN增加显示函数的繁琐。附图说明图1是本专利技术实施例共享内存的结构图。图2是本专利技术实施例应用程序函数调用过程的示意图。具体实施例方式本实施例应用程序的定位方法包括以下步骤步骤一,建立跟踪动态库,其中包含钩子函数和隐式调用函数的实现代码;步骤二,启动管理程序,判断是否已存在管理共享内存区,如没有则建立该内存区;步骤三,被跟踪的应用程序在编译时静态连接所需动态库,为所有自编代码的函数做一个在函数入口处调用的钩子函数,并提供一个在函数返回时调用的隐式调用函数;步骤四,应用程序启动后,动态库在处理进程建立消息时,建立以该应用程序名称命名的进程共享内存区以及线程局部存储标识,该进程共享内存区中设置有一个缺省的启动故障定位标记;步骤五,动态库将应用程序注册到管理共享内存区中,建立该应用程序名称与该应用程序进程共享内存区的对应关系,管理程序修改该进程共享内存区的启动故障定位标记;步骤六,动态库处理线程建立消息时设置该线程的唯一标识值(可有多个,标识可依线程建立次序从0递增),并根据线程唯一标识值从进程共享内存区中为该线程分配一个线程共享内存区;建立的共享内存的结构如图1所示,在管理共享内存区中记录了多个运行的应用程序的名称,每个应用程序名称对应于该程序的进程共享内存区,进程共享内存区中保存有一个启动故障定位标记字(该标志位可以由应用程序写缺省值,也可以由管理程序修改),并为每个线程分配了一个线程共享内存区,每个线程共享内存区又进一步分为链表区和堆栈区,其存储数据的方法将在下面步骤中介绍,同时参照图2。步骤七,被跟踪的应用程序运行到某个函数时调用钩子函数,钩子函数首先根据进程共享内存区的标记字判断是否启动了故障定位功能,如果是,执行下一步,否则直接运行完当前函数,再执行步骤210;步骤八,钩子函数取得当前的EIP(执行指令的地址)标记和当前运行函数的RET(返回地址)标记,修改被跟踪应用程序的堆栈,将当前运行函数的返回地址修改为本文档来自技高网...

【技术保护点】
一种应用程序故障的定位方法,包括以下步骤:(a)在应用程序编译时,为每一个自编码函数生成一个在函数入口处调用的钩子函数,并提供一个在自编码函数返回时调用的隐式调用函数;(b)该应用程序启动后,建立该应用程序的进程共享内存区, 在该进程共享内存区中为该应用程序的每一个线程分配一个线程共享内存区;(c)该应用程序运行到所述自编码函数时调用该钩子函数;(d)该钩子函数取得当前执行指令的地址标记和当前运行函数的返回地址标记,压入相应线程共享内存区的堆栈区 ,同时将该应用程序堆栈中当前运行函数的返回地址修改为该隐式调用函数的入口地址;(e)当前运行函数返回时自动调用该隐式调用函数,该隐式调用函数将压入的当前执行指令的地址标记和当前运行函数的返回地址标记弹出,并在该应用程序堆栈区中恢复当 前运行函数的返回地址;(f)程序继续运行,在每一自编码函数调用均采用步骤(c)到步骤(d)的方法处理,如果程序正常退出,释放该应用程序的进程共享内存区,结束;如果发生故障退出,执行下一步;(g)保存该应用程序的进程共享内存的 数据,根据所述堆栈区的当前指针获得应用程序正在运行的函数和嵌套层次,对故障进行准确定位。...

【技术特征摘要】

【专利技术属性】
技术研发人员:董伟杰王新余
申请(专利权)人:中兴通讯股份有限公司
类型:发明
国别省市:94[中国|深圳]

网友询问留言 已有0条评论
  • 还没有人留言评论。发表了对其他浏览者有用的留言会获得科技券。

1