CN100349131C - 一种应用程序故障的定位方法 - Google Patents

一种应用程序故障的定位方法 Download PDF

Info

Publication number
CN100349131C
CN100349131C CNB2004100707625A CN200410070762A CN100349131C CN 100349131 C CN100349131 C CN 100349131C CN B2004100707625 A CNB2004100707625 A CN B2004100707625A CN 200410070762 A CN200410070762 A CN 200410070762A CN 100349131 C CN100349131 C CN 100349131C
Authority
CN
China
Prior art keywords
function
thread
application program
shared drive
program
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
CNB2004100707625A
Other languages
English (en)
Other versions
CN1728106A (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.)
ZTE Corp
Original Assignee
ZTE Corp
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 ZTE Corp filed Critical ZTE Corp
Priority to CNB2004100707625A priority Critical patent/CN100349131C/zh
Publication of CN1728106A publication Critical patent/CN1728106A/zh
Application granted granted Critical
Publication of CN100349131C publication Critical patent/CN100349131C/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Landscapes

  • Debugging And Monitoring (AREA)

Abstract

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

Description

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

Claims (7)

1、一种应用程序故障的定位方法,包括以下步骤:
(a)在应用程序编译时,为每一个自编码函数生成一个在函数入口处调用的钩子函数,并提供一个在自编码函数返回时调用的隐式调用函数;
(b)该应用程序启动后,建立该应用程序的进程共享内存区,在该进程共享内存区中为该应用程序的每一个线程分配一个线程共享内存区,该进程共享内存区中设置有一个缺省的启动故障定位标记;
(c)该应用程序运行到所述自编码函数时调用该钩子函数,钩子函数检查所述进程共享内存区中的启动故障定位标记,判断是否启动故障定位,如果启动,执行步骤(d),如果不启动,直接执行步骤(f);
(d)该钩子函数取得当前执行指令的地址标记和当前运行函数的返回地址标记,压入相应线程共享内存区的堆栈区,同时将该应用程序堆栈中当前运行函数的返回地址修改为该隐式调用函数的入口地址;
(e)当前运行函数返回时自动调用该隐式调用函数,该隐式调用函数将压入的当前执行指令的地址标记和当前运行函数的返回地址标记弹出,并在该应用程序堆栈区中恢复当前运行函数的返回地址;
(f)程序继续运行,在每一自编码函数调用均采用步骤(c)到步骤(e)的方法处理,如果程序正常退出,释放该应用程序的进程共享内存区,结束;如果发生故障退出,执行下一步;
(g)保存该应用程序的进程共享内存区的数据,根据所述线程共享内存区的堆栈区的当前指针获得所述应用程序正在运行的函数和嵌套层次,对故障进行准确定位。
2、如权利要求1所述的定位方法,其特征在于,所述步骤(d)中,还将当前执行指令的地址标记依序保存到相应线程共享内存区的链表区,步骤(g)中,还对该链表区数据分析,获得该线程最近执行过的函数。
3、如权利要求1或2所述的定位方法,其特征在于,所述步骤(a)之前先建立一个包含所述钩子函数和隐式调用函数实现代码的跟踪动态库,所述应用程序在编译时静态连接该跟踪动态库,实现对所述钩子函数的调用,在该应用程序启动后,该动态库在处理进程建立消息和线程建立消息时分别创建所述进程共享内存区和线程共享内存区。
4、如权利要求3所述的定位方法,其特征在于,所述动态库在处理进程建立消息和线程建立消息时还分别建立线程局部存储标识和对应的各线程唯一标识,各线程唯一标识又对应于各自的线程共享内存区,所述钩子函数和隐式调用函数是通过所述线程局部存储标识找到相应的线程唯一标识,再找到该线程的共享内存区的。
5、如权利要求1或2所述的定位方法,其特征在于,在步骤(b)建立所述进程共享内存区后,还将该应用程序的名称注册到一个管理共享内存区,并记录该应用程序名称与该应用程序进程共享内存区的对应关系。
6、如权利要求5所述的方法,其特征在于,所述管理共享内存区是由动态库创建的,或者由一个管理程序创建的。
7、如权利要求3所述的定位方法,其特征在于,在步骤(a)编译时采用支持在每个函数入口自动调用钩子函数的编译器,并在所述跟踪动态库中将钩子函数命名为该编译器为该自动调用的钩子函数指定的名称。
CNB2004100707625A 2004-07-26 2004-07-26 一种应用程序故障的定位方法 Active CN100349131C (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CNB2004100707625A CN100349131C (zh) 2004-07-26 2004-07-26 一种应用程序故障的定位方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CNB2004100707625A CN100349131C (zh) 2004-07-26 2004-07-26 一种应用程序故障的定位方法

Publications (2)

Publication Number Publication Date
CN1728106A CN1728106A (zh) 2006-02-01
CN100349131C true CN100349131C (zh) 2007-11-14

Family

ID=35927394

Family Applications (1)

Application Number Title Priority Date Filing Date
CNB2004100707625A Active CN100349131C (zh) 2004-07-26 2004-07-26 一种应用程序故障的定位方法

Country Status (1)

Country Link
CN (1) CN100349131C (zh)

Families Citing this family (21)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101295278B (zh) * 2007-04-23 2010-08-11 大唐移动通信设备有限公司 定位被改写代码段所在进程的方法及装置
CN101739519B (zh) * 2008-11-24 2013-01-16 财团法人资讯工业策进会 用于一硬件的监控装置及监控方法
CN101782954B (zh) * 2009-01-20 2013-05-01 联想(北京)有限公司 一种异常进程的检测装置及方法
CN101866300B (zh) * 2009-04-14 2013-08-07 上海科泰世纪科技有限公司 线程托管函数的方法
CN102467452B (zh) * 2010-11-16 2014-08-27 北京中电华大电子设计有限责任公司 一种静态存储分配的局部非静态数据的存储空间分配方法
CN103309796B (zh) * 2012-03-09 2016-06-15 腾讯科技(深圳)有限公司 一种组件对象模型对象的监控方法和装置
US8984325B2 (en) * 2012-05-30 2015-03-17 Symantec Corporation Systems and methods for disaster recovery of multi-tier applications
CN104572046B (zh) * 2013-10-16 2019-01-11 腾讯科技(深圳)有限公司 一种堆栈还原方法和计算机系统
CN105740120B (zh) * 2014-12-11 2018-08-17 中国科学院软件研究所 基于共享内存的软件运行过程实时监测与控制方法及系统
CN106251876A (zh) * 2015-06-12 2016-12-21 徐文波 基于hook技术的音效混合方法与系统
CN106681811B (zh) * 2016-12-08 2021-09-14 腾讯科技(深圳)有限公司 基于线程池的多线程调度方法及装置
CN109240815B (zh) * 2018-08-24 2021-07-23 珠海格力电器股份有限公司 一种共享堆栈的多任务运行方法、装置及设备
CN110874301B (zh) * 2018-08-30 2022-09-13 腾讯科技(深圳)有限公司 程序卡顿信息的获取方法和装置
CN109388537B (zh) * 2018-08-31 2023-02-03 创新先进技术有限公司 运行信息跟踪方法、装置及计算机可读存储介质
CN110908819B (zh) * 2018-09-17 2023-07-04 千寻位置网络有限公司 定位代码运行崩溃的方法及装置、终端、存储器
CN109739770B (zh) * 2019-01-04 2022-06-10 百度在线网络技术(北京)有限公司 小程序的调试方法及装置
CN109960659B (zh) * 2019-03-29 2022-11-01 阿波罗智联(北京)科技有限公司 用于检测应用程序的方法和装置
CN111190833B (zh) * 2019-11-26 2023-03-24 腾讯云计算(北京)有限责任公司 敏感数据检测方法、装置、存储介质及设备
CN113535143A (zh) * 2020-04-21 2021-10-22 腾讯科技(深圳)有限公司 堆栈信息处理方法、装置、电子设备和存储介质
CN112363779A (zh) * 2020-11-25 2021-02-12 王志平 一种动态链接程序的安全控制方法
CN113805971B (zh) * 2021-09-23 2023-10-13 武汉深之度科技有限公司 一种应用程序运行方法、计算设备及存储介质

Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP1096382A2 (en) * 1999-10-26 2001-05-02 Iontas Limited Monitoring of computer usage

Patent Citations (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
EP1096382A2 (en) * 1999-10-26 2001-05-02 Iontas Limited Monitoring of computer usage

Non-Patent Citations (2)

* Cited by examiner, † Cited by third party
Title
Win32下钩子的使用 胡波,潘峰.微机算计应用,第20卷第5期 1999 *
Windows系统中的钩子技术 邱继英,李文超.辽宁大学学报,第28卷第1期 2001 *

Also Published As

Publication number Publication date
CN1728106A (zh) 2006-02-01

Similar Documents

Publication Publication Date Title
CN100349131C (zh) 一种应用程序故障的定位方法
US7316005B2 (en) Data race detection using sequential program analysis
CN100430904C (zh) Just-My-Code调试技术
CN100442245C (zh) 用于分析运行时存储器访问错误的方法和系统
US7865872B2 (en) Producer graph oriented programming framework with undo, redo, and abort execution support
US8762971B2 (en) Servicing a production program in an integrated development environment
US7353427B2 (en) Method and apparatus for breakpoint analysis of computer programming code using unexpected code path conditions
EP2359247B1 (en) Transforming user script code for debugging
CN101645119B (zh) 一种基于虚拟硬件环境的恶意代码自动分析方法及系统
CN101339533B (zh) 基于分区的诊断Java系统的内存泄漏的方法及装置
CN100555218C (zh) 用于改善片上仿真系统中高级语言的仿真速度的装置和方法
US7519630B2 (en) Method and system for automated testing of versioned information handling system applications
CN101446918B (zh) 一种实现用户态调试器调试单个函数的方法及系统
CN1329836C (zh) 定位程序异常的方法
US20110258608A1 (en) Method and apparatus to locate bottleneck of java program
US20050086648A1 (en) Object-based systematic state space exploration of software
US20030154464A1 (en) Stack unique signatures for program procedures and methods
US20050223360A1 (en) System and method for providing a generic user interface testing framework
US7320121B2 (en) Computer-implemented system and method for generating embedded code to add functionality to a user application
CN105528231B (zh) 一种基于中间辅助函数的软件动态升级方法及系统
US7523446B2 (en) User-space return probes
CN101154185A (zh) 软件运行时执行恢复与重放方法
US20050229161A1 (en) Generic user interface testing framework with load-time libraries
CN101403979A (zh) 一种自旋锁的加锁方法及计算机系统
US20040025084A1 (en) Computer-implemented exception handling system and method

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C14 Grant of patent or utility model
GR01 Patent grant
EE01 Entry into force of recordation of patent licensing contract

Assignee: Nanjing Zhongxing Software Co., Ltd.

Assignor: ZTE Corporation

Contract fulfillment period: 2008.9.1 to 2014.9.1 contract change

Contract record no.: 2008320001059

Denomination of invention: Method for positioning malfunction of application program

Granted publication date: 20071114

License type: Exclusive license

Record date: 20081027

LIC Patent licence contract for exploitation submitted for record

Free format text: EXCLUSIVE LICENSE; TIME LIMIT OF IMPLEMENTING CONTACT: 2008.9.1 TO 2014.9.1; CHANGE OF CONTRACT

Name of requester: NANJING ZHONGXING SOFTWARE CO.,LTD.

Effective date: 20081027