堆栈信息处理方法、装置、电子设备和存储介质与流程

文档序号:27017166发布日期:2021-10-23 02:05阅读:154来源:国知局
堆栈信息处理方法、装置、电子设备和存储介质与流程

1.本技术涉及信息处理技术领域,特别是涉及一种堆栈信息处理方法、装置、电子设备和存储介质。


背景技术:

2.随着科技水平的提高,出现了各种类型的应用程序(application,app),app广泛应用于用户的设备终端,如手机、平板等。在开发人员完成app的开发后,会将该app发布至网络,用户可以自行下载并使用。用户在使用app的过程中,可能会出现应用程序报错、对应进程消失或者对应服务自动停止的情况,即出现app崩溃(crash)的情况。
3.在出现app崩溃的情况时,开发人员需要确定app崩溃的原因。现有技术中,通常是开发人员首先获取编译该app时生成的dsym文件,然后基于该dsym文件,使用符号化工具进行符号化处理,然后再根据符号化处理的结果来进行分析,从而确定崩溃原因。
4.然而,现有技术的上述处理过程都需要开发人员手动操作,且需要借助其他文件及工具,步骤繁琐,从而影响开发效率。


技术实现要素:

5.基于此,有必要针对上述技术问题,提供一种能够有助于提高开发效率的堆栈信息处理方法、装置、电子设备和存储介质。
6.一种堆栈信息处理方法,所述方法包括:
7.当监测到应用程序通过目标信息发送函数进行函数调用事件,执行预先加载在所述目标信息发送函数中的钩子函数;
8.通过所述钩子函数,获取所述函数调用事件中的函数调用信息,所述函数调用信息包含被调用函数的函数相关信息;
9.根据所述函数调用信息中的所述函数相关信息,更新崩溃堆栈;
10.在所述应用程序运行崩溃时,基于所述崩溃堆栈得到符号化的堆栈信息。
11.一种堆栈信息处理装置,所述装置包括:
12.钩子执行模块,用于当监测到应用程序通过目标信息发送函数进行函数调用事件,执行预先加载在所述目标信息发送函数中的钩子函数;
13.信息获取模块,用于通过所述钩子函数,获取所述函数调用事件中的函数调用信息,所述函数调用信息包含被调用函数的函数相关信息;
14.堆栈更新模块,用于根据所述函数调用信息中的所述函数相关信息,更新崩溃堆栈;
15.信息处理模块,用于在所述应用程序运行崩溃时,基于所述崩溃堆栈得到符号化的堆栈信息。
16.一种电子设备,包括存储器和处理器,所述存储器存储有计算机程序,所述处理器执行所述计算机程序时实现以下步骤:
17.当监测到应用程序通过目标信息发送函数进行函数调用事件,执行预先加载在所述目标信息发送函数中的钩子函数;
18.通过所述钩子函数,获取所述函数调用事件中的函数调用信息,所述函数调用信息包含被调用函数的函数相关信息;
19.根据所述函数调用信息中的所述函数相关信息,更新崩溃堆栈;
20.在所述应用程序运行崩溃时,基于所述崩溃堆栈得到符号化的堆栈信息。
21.一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现以下步骤:
22.当监测到应用程序通过目标信息发送函数进行函数调用事件,执行预先加载在所述目标信息发送函数中的钩子函数;
23.通过所述钩子函数,获取所述函数调用事件中的函数调用信息,所述函数调用信息包含被调用函数的函数相关信息;
24.根据所述函数调用信息中的所述函数相关信息,更新崩溃堆栈;
25.在所述应用程序运行崩溃时,基于所述崩溃堆栈得到符号化的堆栈信息。
26.上述堆栈信息处理方法、装置、电子设备和存储介质,当监测到应用程序通过目标信息发送函数进行函数调用事件,执行预先加载在目标信息发送函数中的钩子函数;通过钩子函数,获取函数调用事件中的函数调用信息,函数调用信息包含被调用函数的函数相关信息;根据函数调用信息中的函数相关信息,更新崩溃堆栈;在应用程序运行崩溃时,基于崩溃堆栈得到符号化的堆栈信息。
27.本技术中,通过预先在目标信息发送函数中加载钩子函数,可以获取应用程序在进行函数调用事件时的函数调用信息,并对崩溃堆栈进行更新。在函数调用出现问题,导致应用程序运行崩溃时,根据崩溃堆栈保存的函数调用信息即可得到符号化的堆栈信息。由于该符号化的堆栈信息包括有正在进行的函数调用事件对应的函数调用信息,而该正在进行的函数调用事件导致了应用程序崩溃,开发人员可以直接根据符号化的堆栈信息确定导致应用程序崩溃的具体原因,而无需依赖dsym文件以及符号化工具等,从而有助于提高软件开发效率。
附图说明
28.图1为一个实施例中堆栈信息处理方法的流程示意图;
29.图2为一个实施例中未被符号化的堆栈信息的实例图;
30.图3为另一个实施例中符号化的堆栈信息的实例图;
31.图4为一个实施例中崩溃堆栈保存函数相关信息的示意图;
32.图5为一个实施例中删除崩溃堆栈中的函数相关信息的示意图;
33.图6为一个实施例中基于崩溃堆栈得到符号化的堆栈信息的流程示意图;
34.图7为另一个实施例中堆栈信息处理方法的流程示意图;
35.图8为一个实施例中显示有符号化的堆栈信息的屏幕界面示意图;
36.图9(a)为一个实施例中现有技术中的函数调用流程的示意图;
37.图9(b)为一个实施例中本技术中的函数调用流程的示意图;
38.图10为一个实施例中函数调用过程中崩溃堆栈的内容管理示意图;
39.图11为一个实施例中堆栈信息处理装置的结构示意图;
40.图12为另一个实施例中堆栈信息处理装置的结构示意图;
41.图13为一个实施例中电子设备的内部结构图。
具体实施方式
42.为了使本技术的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本技术进行进一步详细说明。应当理解,此处描述的具体实施例仅仅用以解释本技术,并不用于限定本技术。
43.首先,对本技术所涉及的专业名词进行解释说明。
44.1、崩溃堆栈:在app出现崩溃的情况时,用于记录当前函数调用信息的数据结构。
45.2、符号化处理:在未进行符号化之前,堆栈内容的是内存地址信息,符号化是指将内存地址信息转换成开发人员可以理解的符号。
46.2、目标信息发送函数:用于在应用运行过程中调用函数来传递消息。示意性地,对于ios系统的app,目标信息发送函数可以为objc_msgsend函数。objc_msgsend函数传递消息时的格式为:objc_msgsend(id self,sel cmd,...)。objc_msgsend函数是参数个数可变的函数,该函数能接收两个或两个以上的参数。第一个参数“id self”表示消息的接收者;第二个参数“sel cmd”表示选择子的类型;后续参数可以为消息中的参数。其中,选择子是指objc_msgsend函数调用的函数的名称,当然,选择子还可以称为方法等,本实施例不对选择子的命名方式作限定。
47.目标信息发送函数在传递消息时会根据接收者与选择子的类型来调用适当的函数。为了完成此操作,目标信息发送函数需要在接收者所属的类中搜寻其“方法列表”(list ofmethods),如果能找到与选择子名称相符的函数,就跳至其实现代码。若是找不到,那就沿着继承体系继续向上查找,等找到合适的函数之后再跳转。如果最终还是找不到相符的函数,那就执行“消息转发”(message forwarding)操作。
48.3、钩子(hook)函数:是一段用以处理系统消息的程序。通过系统调用,可以将hook函数挂入系统的应用程序。hook函数允许程序截获系统的消息或者特定事件。钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。本技术中,hook函数可以截获系统中目标信息发送函数所进行的函数调用事件,即可以获取函数调用信息。
49.4、objective-c:基于ios系统的应用开发所使用的objective-c,是一种通过提供类定义、方法以及属性的动态语言,该语言中没有对象调用方法的概念,而是通过向各个对象方法发送相应信息的方法来实现各种功能。其中,所有的向各个对象方法发送相应信息的操作都是通过目标信息发送(如objc—msgsend)函数来实现的。因此,在ios系统应用程序开发中,只需对目标信息发送函数进行hook,即可截取应用程序的所有函数调用信息。
50.5、线程(thread):是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位,单个线程对应一个单一顺序的控制流。
51.在一个实施例中,如图1所示,提供一种堆栈信息处理方法,以该方法应用于设备终端中可以进行堆栈信息处理的处理器为例进行解释说明,该方法主要包括以下步骤:
52.步骤s100,当监测到应用程序通过目标信息发送函数进行函数调用事件,执行预先加载在目标信息发送函数中的钩子函数。
53.应用程序是指安装在设备终端、用于实现一项或者多项功能的软件程序,设备终端包括安装有ios、android(安卓)等系统的各类移动终端。移动终端中的各种运行的应用程序都是使用相应的编程语言来编写的。例如,在苹果(apple)公司生产的移动终端(例如,iphone系列的手机)中,所运行的应用程序一般都是使用objective_c语言来编写的。objective_c语言是一种面向对象的语言,该语言中没有对象调用方法的概念,而是通过向各个对象方法发送相应信息的方法来实现各种功能。其中,所有的向各个对象方法发送相应信息的操作都是通过目标信息发送(objc_msgsend)函数来实现的。因此,对于ios系统的应用程序,在实现对应的功能时,都需要通过目标信息发送(objc_msgsend)函数来进行函数调用事件。
54.本步骤中,目标信息发送函数中预先加载有钩子函数,具体可以是在应用程序成功启动后,对目标信息发送函数安装钩子。通过对目标信息发送函数安装钩子,处理器可以对系统中目标信息发送函数所进行的各种消息传递进行监视。在监测到应用程序通过目标信息发送函数进行函数调用事件时,表明应用程序开始运行,此时可以开始执行钩子函数的功能。
55.需要说明的是,对于ios系统的应用程序,在进行函数调用事件时,该应用程序并不是直接进行函数调用,而是将需要调用的函数的信息发送至目标信息发送(objc_msgsend)函数,然后在通过目标信息发送(objc_msgsend)函数执行该需要调用的函数。本步骤中,监测到应用程序通过目标信息发送函数进行函数调用事件,具体可以是指监测到应用程序将需要调用的函数的信息发送至目标信息发送函数,即,在监测到应用程序请求调用函数时,即执行钩子函数,以截取该应用程序发送的函数调用请求。
56.步骤s200,通过钩子函数,获取函数调用事件中的函数调用信息,函数调用信息包含被调用函数的函数相关信息。
57.在应用程序进行函数调用事件时,应用程序并不是直接调用相应功能的函数,而是将函数调用事件的相关参数发送至目标信息发送函数,再由目标信息发送函数根据相关参数调用相应的函数。
58.由于预先在目标信息发送函数加载了钩子函数,在应用程序将函数调用事件的相关参数发送至目标信息发送函数时,通过钩子函数即可截取该函数调用事件的相关参数,得到函数调用信息。其中,函数调用信息包含有被调用函数的函数相关信息。
59.步骤s300,根据函数调用信息中的函数相关信息,更新崩溃堆栈。
60.处理器在通过钩子函数得到函数调用事件的函数调用信息之后,基于获取的函数调用信息中的函数相关信息对崩溃堆栈的内容进行更新,以保证崩溃堆栈实时记录有应用程序的当前函数调用信息,当前函数调用信息包含当前被调用函数的函数相关信息。
61.步骤s400,在应用程序运行崩溃时,基于崩溃堆栈得到符号化的堆栈信息。
62.其中,应用程序运行崩溃,具体是指例如应用程序报错、对应进程消失或者对应服务自动停止等情况。现有技术中,应用程序崩溃时,虽然会保存一个相应的堆栈,但是该堆栈所包含的信息并未被符号化,开发人员无法从该堆栈中获取有效信息。例如,如图2所示,为未被符号化的堆栈信息的实例图,该未被符号化的堆栈信息包含内存调用的相关信息,
开发人员基于该内存调用的相关信息无法识别应用程序的崩溃原因。
63.而本实施中,在应用程序运行崩溃时,由于崩溃堆栈中保存有应用程序的当前函数调用信息,处理器可以基于崩溃堆栈得到应用程序正在进行的函数调用事件中,被调用函数的函数相关信息,即,得到符号化的堆栈信息,基于符号化的堆栈信息,开发人员可以直接识别出应用程序运行崩溃的原因,从而,可以对应用程序进行开发改进。例如,如图3所示,为符号化的堆栈信息的实例图,该符号化的堆栈信息包含被调用函数的函数相关信息,从而,开发人员可以基于被调用函数的函数相关信息确定崩溃原因。
64.本实施例中,通过预先在目标信息发送函数中加载钩子函数,可以获取应用程序在进行函数调用事件时的函数调用信息,并对崩溃堆栈进行更新。在函数调用出现问题,导致应用程序运行崩溃时,根据崩溃堆栈保存的函数调用信息即可得到符号化的堆栈信息。由于该符号化的堆栈信息包括有正在进行的函数调用事件对应的函数调用信息,而该正在进行的函数调用事件导致了应用程序崩溃,开发人员可以直接根据符号化的堆栈信息确定导致应用程序崩溃的具体原因,而无需依赖dsym文件以及符号化工具等,从而有助于提高软件开发效率。
65.在一个实施例中,根据函数调用信息中的函数相关信息,更新崩溃堆栈,包括:在进行新的函数调用事件时,将第一函数的函数相关信息保存至崩溃堆栈。
66.其中,第一函数为新进行的函数调用事件中,被目标信息发送函数调用的函数。在应用程序通过目标信息发送函数进行新的函数调用事件时,处理器通过钩子函数获取第一函数的函数相关信息,并将第一函数的函数相关信息保存至崩溃堆栈。具体地,在应用程序将调用第一函数的请求发送至目标信息发送函数时,处理器通过钩子函数截获该函数调用请求,并将第一函数的函数相关信息进行保存,然后,目标信息发送函数执行该第一函数。
67.在将函数相关信息保存至崩溃堆栈时,新存入的信息保存于栈顶位置。例如,如图4所示,为崩溃堆栈保存函数相关信息的示意图,对于初始的崩溃堆栈(即未保存信息的堆栈),在存入第一次函数调用事件中所调用的函数的函数相关信息info_1时,info_1保存于崩溃堆栈的栈顶位置。在存入第二次函数调用事件中所调用的函数的函数相关信息info_2时,重新将info_2保存于崩溃堆栈的栈顶位置,info_1保存于info_2的下一栏。其他的函数相关信息的存入原理与info_1和info_2的原理相同,在此不再赘述。
68.可选地,函数相关信息包括函数对应的类名以及函数名。其中,类名可以理解为功能集合,函数名可以理解为具体的功能。例如,当类名为“运算”时,函数名可以是“加减乘除”;当类名为“图像处理”时,函数名可以是“卷积、池化、空洞卷积”等。函数相关信息具体可以是通过钩子函数截取的函数调用事件的相关参数得到。
69.不同的类通常包含多个函数,而不同的类之间也可能出现函数名称相同的情况。例如,类名name_1和name_2都包含函数func_a,此外,类名name_1还包含函数func_b,类名name_2还包含函数func_c。在符号化的堆栈信息中,若函数相关信息仅包含类名,例如仅包含name_1,开发人员无法确定是函数func_a还是函数func_b出现了问题;若函数相关信息仅包含函数名,例如func_a,开发人员也无法确定是name_1中的函数func_a出现问题,还是name_2中的函数func_a出现问题。
70.因此,本实施中,函数相关信息同时包括函数对应的类名以及函数名,开发人员可以准确判断具体是哪个函数出现了问题,从而可以快速定位程序崩溃原因,便于进行后续
的应用程序优化开发处理。
71.可选地,将第一函数的函数相关信息保存至崩溃堆栈之前,还包括:若不存在崩溃堆栈,新建用于保存函数相关信息的崩溃堆栈。从而,通过新建崩溃堆栈,可以便于进行函数相关信息的保存。
72.在一个实施例中,根据函数调用信息中的函数相关信息,更新崩溃堆栈,包括:在函数调用事件完成后,将第二函数的函数相关信息从崩溃堆栈中删除。
73.其中,第二函数为已完成的函数调用事件中,被目标信息发送函数调用的函数。由于崩溃堆栈中保存的是正在进行的函数调用事件中被调用函数的函数相关信息,因此,在函数调用事件完成后,需要将调用完成的函数从崩溃堆栈中删除。具体地,某单个函数的调用完成后,目标信息发送函数停止调用该单个函数,此时,可以将该单个函数的函数相关信息从崩溃堆栈中删除。
74.具体地,如图5所示,为删除崩溃堆栈中的函数相关信息的示意图。对于初始的崩溃堆栈(即保存有i个函数相关信息的堆栈),在第i次函数调用事件完成后,将栈顶位置的函数相关信息info_i从崩溃堆栈中删除,此时,栈顶位置的函数相关信息为info_i-1;在第i-1次函数调用事件完成后,将栈顶位置的函数相关信息info_i-1从崩溃堆栈中删除,此时,栈顶位置的函数相关信息为info_i-2。其他的函数相关信息的删除原理与info_i和info_i-1的原理相同,在此不再赘述。
75.在一个实施例中,当应用程序只对应单个线程时,基于单个线程与单个崩溃堆栈的对应关系,该应用程序也只对应单个崩溃堆栈。单个线程对应一个单一顺序的控制流,因此,基于该单个线程对应的单个崩溃堆栈即可得到符号化的堆栈信息。
76.在一个实施例中,应用程序可能存在多线程并发执行的情况,即应用程序在运行过程中,存在至少两个线程,每个线程并行执行不同的任务。对应地,如图6所示,在应用程序运行崩溃时,若应用程序对应的线程数量为至少两个,基于崩溃堆栈得到符号化的堆栈信息,包括步骤s420至步骤s440。
77.步骤s420,确定至少两个线程中的问题线程,问题线程为导致应用程序运行崩溃的线程;
78.步骤s440,基于问题线程对应的崩溃堆栈得到符号化的堆栈信息,符号化的堆栈信息包括问题线程对应的正在进行的函数调用事件中,被调用函数的函数相关信息。
79.具体地,对于多线程并发执行的情况,在应用程序崩溃时,系统会自动输出具体是哪个线程出现问题的提示信息,因此,本实施例可以基于系统信息确定多线程中的问题线程,即基于系统提示信息确定导致应用程序运行崩溃的线程。可以理解,在实际应用中,也可以通过其他方式确定问题线程,在此不做限定。
80.在确定问题线程后,基于该问题线程对应的崩溃堆栈即可得到符号化的堆栈信息,符号化的堆栈信息包括问题线程对应的正在进行的函数调用事件中,被调用函数的函数相关信息。从而,开发人员可以基于问题线程对应的函数相关信息确定程序崩溃原因。
81.在一个实施例中,如图7所示,堆栈信息处理方法还包括步骤s510:输出符号化的堆栈信息。
82.处理器在得到符号化的堆栈信息后,可以输出该符号化的堆栈信息,从而,开发人员可以输出的信息确定程序崩溃原因。
83.具体地,符号化的堆栈信息的输出,具体可以是采取显示的方式实现。例如,如图8所示,在应用程序崩溃后,当用户再次打开该应用程序时,可以将符号化的堆栈信息显示于终端的屏幕,用户可以将显示有符号化的堆栈信息的屏幕直接出示给开发人员查看。或者,用户也可以采取截图或者复制的形式,将符号化的堆栈信息发送至开发人员。
84.此外,符号化的堆栈信息的输出,具体可以是采取数据传输的方式实现。例如,在应用程序崩溃后,处理器通过本技术的堆栈信息处理方法得到符号化的堆栈信息之后,自动将符号化的堆栈信息发送至预设的目标终端或者目标服务器等,从而,用户无需进行任何操作,开发人员可以通过目标终端或者目标服务器得到符号化的堆栈信息。
85.本实施例通过输出符号化的堆栈信息,可以便于开发人员基于符号化的堆栈信息快速定位程序崩溃原因,从而提高开发效率。
86.在一个实施例中,参考图7,堆栈信息处理方法还包括步骤s520:输出应用程序对应的问题函数的函数相关信息。其中,问题函数为导致应用程序运行崩溃的函数,问题函数基于符号化的堆栈信息确定得到。
87.具体地,在应用程序出现崩溃时,崩溃原因可能存在以下几种情况:
88.(1)栈顶位置的函数为系统函数。栈顶位置的函数,即应用程序最近一次调用的函数,当该函数为系统函数时,应用程序的崩溃通常是由该系统函数的调用问题导致的。此时,可以认为,是位于栈顶位置的下一层位置的函数调用该系统函数,导致应用程序崩溃。此时,问题函数可以包含该系统函数以及位于栈顶位置的下一层位置的其他函数。例如,参考图3,图中第二行的函数为系统函数(ns开头的函数为系统函数),则可以认为是第三行的函数调用该系统函数出现了问题,该第三行的函数的类名具体为readinjoyadinfo,函数名具体为getreportinfowithfeedbacktag。
89.(2)栈顶位置的函数为非系统函数。此时,应用程序运行崩溃的原因可能是由该栈顶位置的函数引起的,即该非系统函数为问题函数。
90.另外,应用程序的崩溃也可能是由该非系统函数的调用问题导致的。即,问题函数也可能是包含该非系统函数以及位于栈顶位置的下一层位置的其他函数。
91.可以理解,在实际应用中,确定问题函数的方式并不仅仅局限于以上两种,也可以是采用其他确定方式确定问题函数,在此不做限定。
92.处理器在确定崩溃原因后,可以采用显示、数据传输等方式实现输出问题函数的函数相关信息的目的。
93.本实施例中,通过基于符号化的堆栈信息确定问题函数,然后输出该问题函数的函数相关信息,开发人员无需人工定位崩溃原因,从而进一步提高开发人员的开发效率。
94.在一个实施例中,参考图7,堆栈信息处理方法还包括步骤s530:输出符号化的堆栈信息,以及应用程序对应的问题函数的函数相关信息。
95.本实施例中,处理器可以采用显示、数据传输等方式实现输出符号化的堆栈信息以及输出问题函数的函数相关信息的目的,不同的信息的输出方式可以相同,也可以不同。从而,通过输出问题函数的函数相关信息,可以有助于提高开发人员的开发效率。通过输出符号化的堆栈信息,开发人员也可以对问题函数进行验证,从而保证程序崩溃原因的准确性。
96.在一个实施例中,提供本技术的堆栈信息处理方法的应用实例,该应用实例主要
包括以下处理流程:
97.(1)用户的ios设备上安装有某app,用户在成功启动该app后,处理器在目标信息发送(objc_msgsend)函数安装钩子函数。
98.(2)在监测到该app通过目标信息发送函数进行函数调用事件(向目标信息发送函数发送函数调用请求)时,执行目标信息发送函数中的钩子函数,以获取函数调用事件中的函数调用信息,函数调用信息包含被调用函数的函数相关信息。
99.(3)定义函数第一管理函数before_objc_msgsend,该第一管理函数用于在不存在崩溃堆栈时,新建用于保存函数相关信息的崩溃堆栈;以及在存在崩溃堆栈时,将第一函数的函数相关信息保存至崩溃堆栈,第一函数为新进行的函数调用事件中,被目标信息发送函数调用的函数;
100.定义第二管理函数after_objc_msgsend,该第二管理函数用于在函数调用事件完成后,将第二函数的函数相关信息从崩溃堆栈中删除,第二函数为已完成的函数调用事件中,被目标信息发送函数调用的函数。
101.在获取函数调用信息后,若不存在崩溃堆栈,通过第一管理函数before_objc_msgsend新建崩溃堆栈,并将第一函数的函数相关信息保存至崩溃堆栈;若存在崩溃堆栈,则通过第一管理函数before_objc_msgsend直接将第一函数的函数相关信息保存至崩溃堆栈。新存入的函数相关信息保存于崩溃堆栈的栈顶位置。
102.(4)通过目标信息发送(objc_msgsend)函数进行函数的调用。
103.(5)在函数调用完成后,若程序正常运行,则通过第二管理函数after_objc_msgsend删除崩溃堆栈中第二函数的函数相关信息;若应用程序崩溃,则崩溃堆栈仍保存有函数相关信息。
104.如图9(a)及图9(b)所示,以调用类名为sfeedsview,函数名为playanimation的函数为例,分别为现有技术及本技术中函数调用流程的示意图。
105.参考图9(a),现有技术中,在app向目标信息发送(objc_msgsend)函数发送调用函数[sfeedsview playanimation]的请求后,由函数objc_msgsend直接调用执行函数[sfeedsviewplayanimation],直至函数调用完成。该过程中,若程序出现崩溃,开发人员无法得知是由于调用函数[sfeedsview playanimation]导致程序崩溃。
[0106]
参考图9(b),在本技术的技术方案中,在app向目标信息发送(objc_msgsend)函数发送调用函数[sfeedsviewplayanimation]的请求后,处理器通过钩子函数截获该函数调用信息(函数调用请求)。在函数objc_msgsend进行函数调用之前,处理器通过第一管理函数before_objc_msgsend将函数相关信息添加至崩溃堆栈内。然后,函数objc_msgsend再调用执行函数[sfeedsview playanimation]。在调用完成后,处理器通过第二管理函数after_objc_msgsend将函数[sfeedsviewplayanimation]的函数相关信息从崩溃堆栈中删除,函数调用完成。
[0107]
另外,若调用函数[sfeedsview playanimation],若导致应用程序崩溃,此时,由于函数[sfeedsview playanimation]的函数相关信息仍保存在崩溃堆栈内,因此,处理器可以基于崩溃堆栈得到符号化的堆栈信息,从而,开发人员可以根据符号化的堆栈信息确定是由于调用函数[sfeedsview playanimation]导致程序崩溃。
[0108]
(6)在应用程序运行崩溃后,若应用程序为单线程运行,基于该单线程对应的崩溃
堆栈得到符号化的堆栈信息。
[0109]
若应用程序为多线程并发执行,则首先确定多线程中的问题线程,然后基于问题线程对应的崩溃堆栈得到符号化的堆栈信息。
[0110]
(7)输出符号化的堆栈信息,和/或,输出应用程序对应的问题函数的函数相关信息。从而,应用程序的开发人员可以基于输出的信息确定程序崩溃原因,从而进行后续的开发研究。
[0111]
在一个实施例中,对崩溃堆栈的内容管理进行解释说明。
[0112]
以下为函数调用的具体代码示例,本实施例中,调用的函数依次包括类名为test的函数one、函数two和函数three。
[0113]
1.@implementation test
[0114]
2.-(void)one{
[0115]
3.[selftwo];
[0116]
4.}
[0117]
5.
[0118]
6.-(void)two{
[0119]
7.[selfthree];
[0120]
8.}
[0121]
9.
[0122]
10.-(void)three{
[0123]
11.nslog(@"hello world!");
[0124]
12.}
[0125]
13.@end
[0126]
如图10所示,在app需要调用函数[test one]时,app首先发送调用函数[test one]的请求,此时,处理器通过钩子函数获取函数调用信息(即调用函数[test one]的请求),然后通过第一管理函数before_objc_msgsend将函数[test one]的函数相关信息存入崩溃堆栈(若不存在崩溃堆栈,则先新建再存入),此时,崩溃堆栈的栈顶位置的函数为函数[test one]。
[0127]
然后,由函数objc_msgsend调用函数[test one],即通过函数objc_msgsend执行函数[test one]。在该过程中,需要进一步调用函数[test two],则再通过第一管理函数before_objc_msgsend将函数[test two]的函数相关信息存入崩溃堆栈,此时,崩溃堆栈的栈顶位置的函数变为函数[test two],函数[test one]位于函数[testtwo]的下一层。
[0128]
然后,由函数objc_msgsend调用函数[test two],即通过函数objc_msgsend执行函数[test two]。在该过程中,需要进一步调用函数[testthree],则再通过第一管理函数before_objc_msgsend将函数[test three]的函数相关信息存入崩溃堆栈,此时,崩溃堆栈的栈顶位置的函数变为函数[testthree],函数[test two]位于函数[testthree]的下一层,函数[test one]位于函数[test two]的下一层。
[0129]
然后,函数objc_msgsend调用函数[test three],即通过函数objc_msgsend执行函数[testthree]。
[0130]
若函数[test three]调用正常,则通过第二管理函数after_objc_msgsend将函数
[test three]的函数相关信息从崩溃堆栈中删除,此时,崩溃堆栈的栈顶位置的函数变为函数[testtwo],函数[test one]位于函数[test two]的下一层。
[0131]
在完成函数[test three]的调用后,若函数[test two]调用正常,则通过第二管理函数after_objc_msgsend将函数[testtwo]的函数相关信息从崩溃堆栈中删除,此时,崩溃堆栈的栈顶位置的函数变为函数[test one]。
[0132]
在完成函数[test two]的调用后,若函数[test one]调用正常,则通过第二管理函数after_objc_msgsend将函数[test one]的函数相关信息从崩溃堆栈中删除,此时,崩溃堆栈内的内容为空。
[0133]
而在函数的调用过程中,例如,在函数objc_msgsend调用函数[test three]时,若出现异常导致应用程序崩溃,此时,崩溃堆栈中保存有函数[testthree]、函数[testtwo]、函数[test one]的函数相关信息,此时,函数[test three]位于栈顶位置。基于该崩溃堆栈,可以得到包含上述三个函数的符号化的堆栈信息,从而,开发人员可以基于该符号化的堆栈信息快速定位崩溃原因。
[0134]
在合理条件下应当理解,虽然前文各实施例涉及的流程图中的各个步骤按照箭头的指示依次显示,但是这些步骤并不是必然按照箭头指示的顺序依次执行。除非本文中有明确的说明,这些步骤的执行并没有严格的顺序限制,这些步骤可以以其它的顺序执行。而且,各流程图中的至少一部分步骤可以包括多个子步骤或者多个阶段,这些子步骤或者阶段并不必然是在同一时刻执行完成,而是可以在不同的时刻执行,这些子步骤或者阶段的执行顺序也不必然是依次进行,而是可以与其它步骤或者其它步骤的子步骤或者阶段的至少一部分轮流或者交替地执行。
[0135]
在一个实施例中,如图11所示,提供一种堆栈信息处理装置,该装置主要包括以下模块:
[0136]
钩子执行模块100,用于当监测到应用程序通过目标信息发送函数进行函数调用事件,执行预先加载在目标信息发送函数中的钩子函数;
[0137]
信息获取模块200,用于通过钩子函数,获取函数调用事件中的函数调用信息,函数调用信息包含被调用函数的函数相关信息;
[0138]
堆栈更新模块300,用于根据函数调用信息中的函数相关信息,更新崩溃堆栈;
[0139]
信息处理模块400,用于在应用程序运行崩溃时,基于崩溃堆栈得到符号化的堆栈信息。
[0140]
本技术中,通过预先在目标信息发送函数中加载钩子函数,可以获取应用程序在进行函数调用事件时的函数调用信息,并对崩溃堆栈进行更新。在函数调用出现问题,导致应用程序运行崩溃时,根据崩溃堆栈保存的函数调用信息即可得到符号化的堆栈信息。由于该符号化的堆栈信息包括有正在进行的函数调用事件对应的函数调用信息,而该正在进行的函数调用事件导致了应用程序崩溃,开发人员可以直接根据符号化的堆栈信息确定导致应用程序崩溃的具体原因,而无需依赖dsym文件以及符号化工具等,从而有助于提高软件开发效率。
[0141]
在一个实施例中,堆栈更新模块300包括信息存入单元;信息存入单元用于在进行新的函数调用事件时,将第一函数的函数相关信息保存至所述崩溃堆栈,所述第一函数为新进行的函数调用事件中,被所述目标信息发送函数调用的函数。
[0142]
在一个实施例中,堆栈更新模块300还包括堆栈建立单元:堆栈建立单元用于在不存在崩溃堆栈时,新建用于保存函数相关信息的崩溃堆栈。
[0143]
在一个实施例中,堆栈更新模块300还包括信息删除单元;信息删除单元用于在函数调用事件完成后,将第二函数的函数相关信息从所述崩溃堆栈中删除,所述第二函数为已完成的函数调用事件中,被所述目标信息发送函数调用的函数。
[0144]
在一个实施例中,信息处理模块400还包括问题线程确定单元以及堆栈信息符号化单元;问题线程确定单元用于确定至少两个线程中的问题线程,所述问题线程为导致所述应用程序运行崩溃的线程;堆栈信息符号化单元用于基于所述问题线程对应的崩溃堆栈得到符号化的堆栈信息,所述符号化的堆栈信息包括所述问题线程对应的正在进行的函数调用事件中,被调用函数的函数相关信息。
[0145]
在一个实施例中,如图12所示,堆栈信息处理装置,还包括:信息输出模块500,用于输出所述符号化的堆栈信息;和/或,输出所述应用程序对应的问题函数的函数相关信息,所述问题函数为导致所述应用程序运行崩溃的函数,所述问题函数基于所述符号化的堆栈信息确定得到。
[0146]
在一个实施例中,所述函数相关信息包括函数对应的类名以及函数名。
[0147]
关于堆栈信息处理装置的具体限定可以参见上文中对于堆栈信息处理方法的限定,在此不再赘述。上述堆栈信息处理装置中的各个模块可全部或部分通过软件、硬件及其组合来实现。上述各模块可以硬件形式内嵌于或独立于电子设备中的处理器中,也可以以软件形式存储于电子设备中的存储器中,以便于处理器调用执行以上各个模块对应的操作。
[0148]
在一个实施例中,提供了一种电子设备,该电子设备可以是终端,其内部结构图可以如图13所示。该电子设备包括通过系统总线连接的处理器、存储器、通信接口、显示屏和输入装置。其中,该电子设备的处理器用于提供计算和控制能力。该电子设备的存储器包括非易失性存储介质、内存储器。该非易失性存储介质存储有操作系统和计算机程序。该内存储器为非易失性存储介质中的操作系统和计算机程序的运行提供环境。该电子设备的通信接口用于与外部的终端进行有线或无线方式的通信,无线方式可通过wifi、运营商网络、nfc(近场通信)或其他技术实现。该计算机程序被处理器执行时以实现一种堆栈信息处理方法。该电子设备的显示屏可以是液晶显示屏或者电子墨水显示屏,该电子设备的输入装置可以是显示屏上覆盖的触摸层,也可以是电子设备外壳上设置的按键、轨迹球或触控板,还可以是外接的键盘、触控板或鼠标等。
[0149]
本领域技术人员可以理解,图13中示出的结构,仅仅是与本技术方案相关的部分结构的框图,并不构成对本技术方案所应用于其上的电子设备的限定,具体的电子设备可以包括比图中所示更多或更少的部件,或者组合某些部件,或者具有不同的部件布置。
[0150]
在一个实施例中,还提供了一种电子设备,包括存储器和处理器,存储器中存储有计算机程序,该处理器执行计算机程序时实现上述各方法实施例中的步骤。
[0151]
在一个实施例中,提供了一种计算机可读存储介质,存储有计算机程序,该计算机程序被处理器执行时实现上述各方法实施例中的步骤。
[0152]
本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,所述的计算机程序可存储于一非易失性计算机
可读取存储介质中,该计算机程序在执行时,可包括如上述各方法的实施例的流程。其中,本技术所提供的各实施例中所使用的对存储器、存储、数据库或其它介质的任何引用,均可包括非易失性和易失性存储器中的至少一种。非易失性存储器可包括只读存储器(read-only memory,rom)、磁带、软盘、闪存或光存储器等。易失性存储器可包括随机存取存储器(random access memory,ram)或外部高速缓冲存储器。作为说明而非局限,ram可以是多种形式,比如静态随机存取存储器(static random access memory,sram)或动态随机存取存储器(dynamic randomaccess memory,dram)等。
[0153]
以上实施例的各技术特征可以进行任意的组合,为使描述简洁,未对上述实施例中的各个技术特征所有可能的组合都进行描述,然而,只要这些技术特征的组合不存在矛盾,都应当认为是本说明书记载的范围。
[0154]
以上所述实施例仅表达了本技术的几种实施方式,其描述较为具体和详细,但并不能因此而理解为对发明专利范围的限制。应当指出的是,对于本领域的普通技术人员来说,在不脱离本技术构思的前提下,还可以做出若干变形和改进,这些都属于本技术的保护范围。因此,本技术专利的保护范围应以所附权利要求为准。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1