掌桥专利:专业的专利平台
掌桥专利
首页

线程快照解析方法、装置、设备和存储介质

文献发布时间:2023-06-19 11:35:49


线程快照解析方法、装置、设备和存储介质

技术领域

本公开涉及计算机技术领域,尤其涉及一种线程快照解析方法、装置、设备和存储介质。

背景技术

随着软件开发技术的发展,可安装在用户终端上的应用程序层出不穷,例如新闻类应用程序、教育类应用程序、或者娱乐类应用程序等,极大地改善了人们的生活方式。

软件开发商对已发布版本的应用程序进行运行性能的监控,有助于及时发现程序运行过程中的异常状态,从而及时对应用程序进行改进,保证用户对应用程序的使用体验。

然而,由于用户终端的差异性,无法保证准确获取应用程序运行过程中的相关程序信息,进而导致无法准确分析应用程序的运行性能。

发明内容

为了解决上述技术问题或者至少部分地解决上述技术问题,本公开实施例提供了一种线程快照解析方法、装置、设备和存储介质。

第一方面,本公开实施例提供了一种线程快照解析方法,包括:

在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址;其中,所述程序计数器地址用于标识程序运行过程中正在执行的函数指令地址;

获取所述应用程序的符号表文件,并确定所述符号表文件中记录的主函数的初始起始地址、初始结束地址、以及所述应用程序对应的代码段的虚拟偏移值;

基于所述至少一个目标程序计数器地址、所述初始起始地址、所述初始结束地址、以及所述虚拟偏移值,确定与所述预设运行周期中的线程快照对应的至少一个偏移地址区间;

基于预设策略和所述至少一个偏移地址区间,确定与所述预设运行周期中的线程快照对应的目标偏移地址;其中,所述预设策略用于定义确定所述目标偏移地址的规则;

基于所述目标偏移地址,对所述预设运行周期中的线程快照进行符号化解析。

第二方面,本公开实施例还提供了一种线程快照解析装置,包括:

目标程序计数器地址确定模块,用于在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址;其中,所述程序计数器地址用于标识程序运行过程中正在执行的函数指令地址;

符号表文件获取模块,用于获取所述应用程序的符号表文件,并确定所述符号表文件中记录的主函数的初始起始地址、初始结束地址、以及所述应用程序对应的代码段的虚拟偏移值;

偏移地址区间确定模块,用于基于所述至少一个目标程序计数器地址、所述初始起始地址、所述初始结束地址、以及所述虚拟偏移值,确定与所述预设运行周期中的线程快照对应的至少一个偏移地址区间;

目标偏移地址确定模块,用于基于预设策略和所述至少一个偏移地址区间,确定与所述预设运行周期中的线程快照对应的目标偏移地址;其中,所述预设策略用于定义确定所述目标偏移地址的规则;

线程快照解析模块,用于基于所述目标偏移地址,对所述预设运行周期中的线程快照进行符号化解析。

第三方面,本公开实施例还提供了一种电子设备,包括存储器和处理器,其中,所述存储器中存储有计算机程序,当所述计算机程序被所述处理器执行时,使得所述电子设备实现本公开实施例提供的任一所述的线程快照解析方法。

第四方面,本公开实施例还提供了一种计算机可读存储介质,所述存储介质中存储有计算机程序,当所述计算机程序被计算设备执行时,使得所述计算设备实现本公开实施例提供的任一所述的线程快照解析方法。

本公开实施例提供的技术方案与现有技术相比至少具有如下优点:在本公开实施例中,通过在应用程序的预设运行周期内,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址(或称为PC地址),确定至少一个目标程序计数器地址,然后结合应用程序的符号表文件中记录的信息,预测程序运行过程中为函数分配的目标偏移地址,进而基于该目标偏移地址,对预设运行周期中的线程快照进行符号化解析,具体而言,基于目标偏移地址可以获取程序运行过程中函数的真实地址,基于函数的真实地址可以确定函数名等描述信息,也即本公开实施例实现了准确获取应用程序运行过程中的相关程序信息,进而有助于实现对应用程序的运行性能的准确监控与分析,解决了现有方案中无法准确获取应用程序运行过程中的相关程序信息,导致无法准确地监控与分析应用程序的运行性能的问题。并且,采用本公开实施例的技术方案,无需通过调试应用程序的源代码,即可实现对应用程序运行性能的监控和分析,提高了程序运行性能监控和分析的效率。

附图说明

此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理。

为了更清楚地说明本公开实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。

图1为本公开实施例提供的一种线程快照解析方法的流程图;

图2为本公开实施例提供的另一种线程快照解析方法的流程图;

图3为本公开实施例提供的另一种线程快照解析方法的流程图;

图4为本公开实施例提供的一种与待监控设备建立通信的处理架构示意图;

图5为本公开实施例提供的一种线程快照解析装置的结构示意图;

图6为本公开实施例提供的一种电子设备的结构示意图。

具体实施方式

为了能够更清楚地理解本公开的上述目的、特征和优点,下面将对本公开的方案进行进一步描述。需要说明的是,在不冲突的情况下,本公开的实施例及实施例中的特征可以相互组合。

在下面的描述中阐述了很多具体细节以便于充分理解本公开,但本公开还可以采用其他不同于在此描述的方式来实施;显然,说明书中的实施例只是本公开的一部分实施例,而不是全部的实施例。

图1为本公开实施例提供的一种线程快照解析方法的流程图,该方法可以适用于如何对应用程序运行过程中的各个线程快照(指应用程序运行的特定时刻,代码调用栈的程序计数器地址,或称为PC地址)进行符号化解析,从而得到程序运行过程中各个函数的函数名等描述信息,以用于监控与分析该应用程序的运行性能。

其中,程序计数器(Program Counter,PC)地址(或称为PC地址)是指程序计数器中存储的指令地址,可以用于标识程序运行过程中正在执行的函数指令地址。具体而言,程序计数器是一个中央处理器(Central Processing Unit,CPU)中的寄存器,用于指示计算机在其程序序列中的位置,在一些微处理器中,程序计数器还可以被称为指令指针、指令地址寄存器,或者指令计数器等。

本公开实施例中提及的应用程序可以是安装在电子设备上的至少一种类型的应用程序,例如视频交互类应用程序等。电子设备可以是具有计算能力的至少一种类型的设备,例如终端或者服务器等。安装应用程序的电子设备中的操作系统例如可以iOS系统等。

本公开实施例提供的线程快照解析方法可以由线程快照解析装置执行,该装置可以采用软件和/或硬件实现,并可集成在用于执行本公开实施例技术方案的电子设备上。

如图1所示,本公开实施例提供的线程快照解析方法可以包括:

S101、在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址;其中,程序计数器地址用于标识程序运行过程中正在执行的函数指令地址。

在应用程序运行过程中,主线程的调用栈中第二层栈帧用于存储主函数(main函数)的相关信息,即主线程的调用栈中第二层栈帧对应的一定是主函数。在程序运行过程中的主线程和子线程未提前确定的情况下,可以获取程序运行过程中各个线程的调用栈中第二层栈帧对应的程序计数器地址,并按照程序计数器地址筛选策略(例如在每个线程中程序计数器地址的出现次数,一个程序计数器地址是否出现在至少两个线程中等),从获取的多个程序计数器地址中确定出至少一个目标程序计数器地址,作为有效程序计数器地址,以用于预测程序运行过程中线程快照对应的偏移地址(即程序运行过程中函数的偏移地址)。程序运行过程中各个函数的偏移地址是相同的。

预设运行周期的时间长度可以根据需求进行设置,本公开实施例不作具体限定。通过按照预设运行周期,周期性地获取各个线程的调用栈中第二层栈帧对应的程序计数器地址,以用于预测程序运行过程中函数的偏移地址,可以确保偏移地址的预测准确性。

可选地,在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址,包括:

在应用程序的预设运行周期中,确定每个线程的调用栈中第二层栈帧对应的程序计数器地址,在该线程中的出现总次数;

基于每个线程中的每个程序计数器地址的出现总次数m,以及各个线程中的线程快照总数之和sum,确定每个线程中的每个程序计数器地址的出现次数占比p,例如p=(m/sum)×100%;

将出现次数占比大于或等于第二占比阈值、且只出现在一个线程中的程序计数器地址确定为至少一个目标程序计数器地址。其中,第二占比阈值的取值可以视情况而定,本公开实施例不作具体限定。

由于正常情况下,程序运行过程中只有主线程的调用栈中第二层栈帧对应主函数,并且主函数在主线程的各个调用栈中均会出现,因此,在获取的多个程序计数器地址中,只出现在一个线程中的程序计数器地址的置信度高于同时在多个线程中出现的程序计数器地址的置信度,且出现次数占比大于或等于第二占比阈值的程序计数器地址的置信度,高于出现次数占比小于第二占比阈值的程序计数器地址的置信度。即将出现次数占比大于或等于第二占比阈值、且只出现在一个线程中的程序计数器地址确定为至少一个目标程序计数器地址,为后续正确预测偏移地址奠定了基础。

应用程序的预设运行周期中可以包括多个线程,具体以其中的线程1和线程2为例,对目标程序计数器地址的确定过程进行示例性说明,并且多个线程中线程快照总数之和为100,即多个线程中的程序计数器地址总数为100个,其中:

在线程1中:

程序计数器地址A的出现总次数为10次,出现次数占比为10%;

程序计数器地址B的出现总次数为1次,出现次数占比为1%;

程序计数器地址C的出现总次数为2次,出现次数占比为2%;

在线程2中:

程序计数器地址C的出现总次数为5次,出现次数占比为5%;

程序计数器地址D的出现总次数为8次,出现次数占比为8%;

当然,还包括其他线程中程序计数器地址的出现次数以及出现次数占比,在此不再给出具体示例。

假设第二占比阈值为1.5%,上述程序计数器地址B的出现次数占比为1%,小于1.5%,所以程序计数器地址B需要被过滤掉,程序计数器地址C由于在线程1和线程2中均出现,所以程序计数器地址C也需要被过滤掉,最终程序计数器地址A和程序计数器地址D可以作为目标程序计数器地址。

S102、获取应用程序的符号表文件,并确定符号表文件中记录的主函数的初始起始地址、初始结束地址、以及应用程序对应的代码段的虚拟偏移值。

每个应用程序均有各自对应的符号表(dsym)文件,符号表是一种内存地址与函数名、文件名、行号的映射表,并且在程序安装包打包阶段生成。由于程序运行过程中主线程的调用栈中第二层栈帧对应主函数,属于一个确定的已知条件,因此,可以从应用程序的符号表文件中获取预先记录的主函数的初始起始地址main_low_pc、初始结束地址main_high_pc,以及当前应用程序对应的代码段text section的虚拟偏移值vm,作为参与预测偏移地址的因素。

S103、基于至少一个目标程序计数器地址、初始起始地址、初始结束地址、以及虚拟偏移值,确定与预设运行周期中的线程快照对应的至少一个偏移地址区间。

针对每个目标程序计数器地址,可以按照以下方式计算对应的偏移地址区间[offset_min,offset_max],计算过程中每个目标程序计数器地址采用pc表示:

偏移地址区间的最大端点值可以表示为:

offset_max=pc-main_low_pc+vm;

偏移地址区间的最小端点值可以表示为:

offset_min=pc-main_high_pc+vm。

目标程序计数器地址的数量与偏移地址区间的数量相同。

S104、基于预设策略和至少一个偏移地址区间,确定与预设运行周期中的线程快照对应的目标偏移地址;其中,预设策略用于定义确定目标偏移地址的规则。

示例性地,预设策略可以包括:目标偏移地址处于偏移地址区间,并且为10的N次方的整数倍,例如偏移地址是1000的整数倍等,因此,当得到多个偏移地址区间后,可以确定每个偏移地址区间中是否存在符合预测策略的地址值,如果存在,即可以作为目标偏移地址。此处需要说明的是,偏移地址区间可以计算得到多个,但通常该区间内符合预设策略的地址值的数量有限,因此,本方案可以得到较为准确的目标偏移地址。

如果基于预设策略和至少一个偏移地址区间,确定出至少两个符合预设策略的地址值,则可以按照参与确定偏移地址区间的目标程序计数器地址的出现次数占比,从至少两个符合预设策略的地址值中确定出一个目标偏移地址。具体地,优选将参与确定偏移地址区间的目标程序计数器地址的出现次数占比超过第一占比阈值(取值可以灵活确定)时,该偏移地址区间中符合预设策略的地址值,作为目标偏移地址。

例如,基于预设策略和偏移地址区间1,确定出偏移地址区间1中符合预设策略的地址值d1;基于预设策略和偏移地址区间2,确定出偏移地址区间2中符合预设策略的地址值d2;由于参与确定偏移地址区间1的目标程序计数器地址A的出现次数占比为x1,小于第一占比阈值,然而参与确定偏移地址区间2的目标程序计数器地址B的出现次数占比为x2,大于第一占比阈值,则可以将偏移地址区间2中符合预设策略的地址值d2确定为目标偏移地址。继续以该示例为例,如果参与确定偏移地址区间1的目标程序计数器地址A的出现次数占比、参与确定偏移地址区间2的目标程序计数器地址B的出现次数占比均大于第一占比阈值,则可以将地址值d1和地址值d2中,值最小的地址值作为目标偏移地址。

由于主函数是程序运行过程中的一个入口函数,偏移地址越小,基于程序运行过程主函数的程序计数器地址和偏移地址,得到的主函数的实际地址越大,即主函数的实际结束位置越靠后,准确性相对越高。

S105、基于目标偏移地址,对预设运行周期中的线程快照进行符号化解析。

具体地,基于目标偏移地址,以及应用程序的预设运行周期中各个线程的调用栈的程序计数器地址,可以还原得到各个线程中各个函数的真实地址(即程序开发过程中定义的函数地址),然后利用应用程序的符号表文件,基于各个函数的真实地址,可以得到各个函数的函数名、函数所在文件的文件名、函数在文件中对应的行号(代码行号)等描述信息,也即符号化解析结果,最后基于各个函数的描述信息,实现监控与分析该应用程序的运行性能。

此外,应用程序运行过程中,每个线程快照都有对应的时间戳,通过对线程快照进行自下到上的相同项合并,函数堆栈中第一次出现的时刻为该函数的开始时刻,最后一次出现的时刻为该函数的结束时刻。根据线程快照中的函数调用关系与各个函数的开始时刻、结束时刻,即可绘制出火焰图,用于分析应用程序的运行性能。具体而言,火焰图是函数调用关系与时间分布的展现形式,纵向表示调用栈的深度,横向表示消耗的时间,火焰图上一个格子的宽度越大,说明该格子对应的函数可能是程序运行过程中的瓶颈,因此,火焰图是当前对应用程序进行性能分析的利器。

在本公开实施例中,通过在应用程序的预设运行周期内,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址,然后结合应用程序的符号表文件中记录的信息,预测程序运行过程中为函数分配的目标偏移地址,进而基于该目标偏移地址,对预设运行周期中的线程快照进行符号化解析,具体而言,基于目标偏移地址可以获取程序运行过程中函数的真实地址,基于函数的真实地址可以确定函数名等描述信息,也即本公开实施例实现了准确获取应用程序运行过程中的相关程序信息,进而有助于实现对应用程序的运行性能的准确监控与分析,解决了现有方案中无法准确获取应用程序运行过程中的相关程序信息,导致无法准确地监控与分析应用程序的运行性能的问题。并且,本方案通过对程序运行过程中函数的偏移地址进行预测,基于偏移地址即可实现对线程快照的符号化解析,无需对应用程序进行调试,具有便捷、高效的优势,同时也解决了由于无法进行程序调试导致无法分析程序运行性能的问题。

在上述技术方案的基础上,可选地,基于预设策略和至少一个偏移地址区间,确定与预设运行周期中的线程快照对应的目标偏移地址,包括:

基于每个偏移地址区间的最大端点值offset_max和最小端点值offset_min,确定每个偏移地址区间对应的目标整数align,该过程可以称为对最大端点值和最小端点值进行向下对齐处理;其中,目标整数为10的N次方,例如N等于3,目标整数为1000,从程序编写的角度,目标整数可以表示为align=int(0x1000);

对每个偏移地址区间的最小端点值offset_min和目标整数align之间的商值向下取整,得到每个偏移地址区间对应的第一倍数值;

示例性地,从程序编写的角度,第一倍数值可以表示为:offset_min/align;

将每个偏移地址区间对应的第一倍数值加1,得到第二倍数值,并基于第二倍数值和每个偏移地址区间对应的目标整数align的乘积,得到至少一个候选偏移地址offset;

示例性地,从程序编写的角度,候选偏移地址可以表示为:

offset=(offset_min/align+1)×align;

基于每个候选偏移地址offset和对应的偏移地址区间的数值关系、以及每个目标程序计数器地址的出现次数占比,从至少一个候选偏移地址中,确定与预设运行周期中的线程快照对应的目标偏移地址offset

进一步地,基于每个候选偏移地址和对应的偏移地址区间的数值关系、以及每个目标程序计数器地址的出现次数占比,从至少一个候选偏移地址中,确定与预设运行周期中的线程快照对应的目标偏移地址,包括:

如果候选偏移地址处于对应的偏移地址区间,且参与确定该偏移地址区间的目标程序计数器地址的出现次数占比超过第一占比阈值,则将该候选偏移地址确定为目标偏移地址,即有效的预测偏移地址,否则,不作为目标偏移地址。

并且,如果满足候选偏移地址处于对应的偏移地址区间,且参与确定该偏移地址区间的目标程序计数器地址的出现次数占比超过第一占比阈值的情况下,候选偏移地址的数量为至少两个,则将至少两个候选偏移地址中的最小值确定为目标偏移地址。

在上述技术方案的基础上,可选地,在基于目标偏移地址,对预设运行周期中的线程快照进行符号化解析之前,本公开实施例提供的方法还可以包括:

确定符号表文件中记录的代码段的加载地址addr(即代码段的首地址)和代码段的空间占用大小size;

基于加载地址addr、代码段的空间占用大小size和虚拟偏移值vm,确定应用程序对应的位置参数lib_size,具体可以表示如下:

lib_size=addr-vm+size;

相应地,基于目标偏移地址,对预设运行周期中的线程快照进行符号化解析,包括:

将预设运行周期中各个线程快照中大于目标偏移地址offset

基于目标偏移地址,对待解析程序计数器地址进行符号化解析。

其中,各个线程快照中小于或等于目标偏移地址offset

本公开实施例通过计算应用程序对应的位置参数,并基于目标偏移地址和位置参数对程序运行过程中各个线程快照中的地址进行过滤,确定出待解析程序计数器地址,提高了符号化解析的效率。

图2为本公开实施例提供的另一种线程快照解析方法的流程图,用于对本公开实施例进行示例性说明,但不应理解为对本公开实施例的具体限定。如图2所示,在应用程序运行过程中,可以按照预设运行周期,获取各个线程的线程快照,并且确定是否获取到线程快照对应的偏移地址,如果获取到,则可以直接基于获取的偏移地址,对当前运行周期内的线程快照进行符号化解析,如果未能获取到偏移地址,则可以按照线程ID,对获取的线程快照进行拆分;从各个线程的线程快照中,获取线程的调用栈中第二层栈帧对应的程序计数器地址,并且,针对每个线程,获取相同数量的程序计数器地址;

遍历程序计数器地址,并确定程序计数器地址的出现次数占比(具体计算可以参考前述实施例中的解释)是否大于阈值(具体指代前述第二占比阈值),如果否,则继续遍历程序计数器地址,如果是,则确定程序计数器地址是否出现在其他线程中,即一个程序计数器地址是否同时在至少两个线程中出现;如果出现在其他线程,则继续遍历程序计数器地址,如果未出现在其他线程,则在当前程序计数器地址可以作为目标程序计数器地址,获取应用程序的符号表(dsym)文件,并从中获取预先记录的主函数的初始起始地址main_low_pc、初始结束地址main_high_pc,以及应用程序对应的代码段text section的虚拟偏移值vm、加载地址addr、以及空间占用大小size;利用从符号表(dsym)文件中获取的各个数据以及目标程序计数器地址(可以采用pc表示),计算偏移地址区间[offset_min,offset_max]、以及应用程序对应的位置参数lib_size,其中:

偏移地址区间的最大端点值可以表示为:

offset_max=pc-main_low_pc+vm;

偏移地址区间的最小端点值可以表示为:

offset_min=pc-main_high_pc+vm;

位置参数lib_size可以表示为:lib_size=addr-vm+size;

对最大端点值offset_max和最小端点值offset_min进行向下对齐处理,确定每个偏移地址区间对应的目标整数align,目标整数align例如可以表示为align=int(0x1000);基于最小端点值offset_min和目标整数align,计算候选偏移地址offset,候选偏移地址offset可以表示为:

offset=(offset_min/align+1)×align;

确定候选偏移地址offset是否处于偏移地址区间中,如果否,则当前候选偏移地址不属于目标偏移地址,则继续遍历获取的程序计数器地址,执行目标程序计数器地址的确定操作以及候选偏移地址的计算操作,如果是,则表示当前候选偏移地址属于目标偏移地址的概率较大;进一步地,可以针对得到的各个处于偏移地址区间的候选偏移地址,从中确定出目标偏移地址offset

确定出目标偏移地址offset

图3为本公开实施例提供的另一种线程快照解析方法的流程图,基于上述技术方案进一步进行优化与扩展,并可以与上述各个可选实施方式进行结合。

如图3所示,本公开实施例提供的线程快照解析方法可以包括:

S301、根据设备标识,确定待监控设备。

在本公开实施例中,需要进行运行性能分析的应用程序可以安装在待监控设备上,例如移动终端、平板电脑等。待监控设备的数量可以为一个或多个。在执行本公开实施例的技术方案的过程中,可以根据设备标识(用于唯一性标识设备),确定当前的待监控设备。

S302、根据应用程序标识,确定待监控设备中待监控的应用程序。

每个待监控设备中可以安装多种类型的应用程序。应用程序标识用于唯一性区分不同的应用程序,因此,可以根据应用程序标识确定待监控设备中待监控的应用程序,从而避免监控对象出错。

S303、与待监控设备建立通信,获取在应用程序的预设运行周期中各个线程的线程快照,以及各个线程的线程ID。

确定待监控设备以及待监控的应用程序后,用于执行本公开实施例技术方案的电子设备可以采用能够实现设备之间数据传输的通信建立方式,与待监控设备建立通信连接,从而在待监控的应用程序的运行过程中,按照预设运行周期,获取各个线程的线程快照,以及各个线程的线程ID。线程ID用于唯一性区分不同的线程。例如,针对iOS操作系统的待监控设备,可以利用libimobiledevice技术与待监控设备建立通信。其中,libimobiledevice是一个跨平台的软件协议库和工具,可以用来实现非iOS操作系统的电子设备与iOS设备(即以iOS操作系统作为操作系统的电子设备)之间的本地通信。

图4为本公开实施例提供的一种与待监控设备建立通信的处理架构示意图,具体以待监控设备的操作系统为iOS操作系统为例,对本公开实施例进行示例性说明,但不应理解为对本公开实施例的具体限定。如图4所示,待监控设备可以包括待监控设备1、待监控设备2和待监控设备3,可以根据设备标识确定当前待监控设备,然后根据应用程序标识,确定当前待监控设备中待监控的应用程序,其中,设备标识和应用程序标识可以作为配置信息(Config信息)在指定数据通道中传递,以使得通过该指定数据通道可以准确地获取到需求的应用程序运行过程中的线程快照数据。

利用libimobiledevice技术与当前待监控设备建立通信后,由于当前待监控设备处于锁屏状态的情况下,会影响线程快照的采集,因此,在进行线程快照的采集之前,对当前待监控设备是否处于锁屏状态进行检测;如果确定当前待监控设备处于锁屏状态,则无法采集应用程序运行过程中各个线程的线程快照,当前线程快照的采集流程即结束;如果确定当前待监控设备处于解锁状态,则开启待监控设备中的挂载服务(start server“mobile_image_mounter”),确定是否挂载Developer Image文件(指待监控设备中所有数据采集服务的集合的镜像文件,挂载这个镜像文件的设备能使用各个数据采集服务)。

由于开启待监控设备中的Instruments Server后台服务(是iOS设备采集内核与性能数据的一种后台服务),需要挂载iOS设备的Developer Image文件,因此需要判断Developer Image文件是否已经挂载过,如果没有挂载,则需要执行对应设备版本的Developer Image文件的下载与设备挂载,随后开启待监控设备中的Instruments Server后台服务(start server“instruments.remoteserver”),通过基于libimobiledevice技术封装好的socket接口进行通信,对指定数据通道(如activitytracetap通道)请求应用程序运行过程中各个线程的线程快照。示例性地,在采集线程快照的过程中,可以基于数据采集服务中数据结构体的定义(例如数据采集服务kpdecode中所采集数据的结构体的定义),通过threadInfo.pid(即进程标识符或进程ID)与threadInfo.tid(即线程标识符或线程ID)区分线程快照所属的进程与线程,准确提取待监控的应用程序运行过程中各个线程的线程快照。

S304、基于线程ID对获取的线程快照进行拆分,并从每个线程的线程快照中,确定每个线程的调用栈中第二层栈帧对应的程序计数器地址。

在程序运行过程中,每个线程中均可以包括至少一个调用栈。按照线程ID对获取的线程快照进行拆分,可以实现对获取的线程快照的分类,进而可以针对每个线程中的线程快照,确定出符合条件的目标程序计数器地址。例如,可以将每个线程中,出现次数占比大于或等于第二占比阈值、且只出现在一个线程中的程序计数器地址确定为目标程序计数器地址。

S305、在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址;其中,程序计数器地址用于标识程序运行过程中正在执行的函数指令地址。

S306、获取应用程序的符号表文件,并确定符号表文件中记录的主函数的初始起始地址、初始结束地址、以及应用程序对应的代码段的虚拟偏移值。

S307、基于至少一个目标程序计数器地址、初始起始地址、初始结束地址、以及虚拟偏移值,确定与预设运行周期中的线程快照对应的至少一个偏移地址区间。

S308、基于预设策略和至少一个偏移地址区间,确定与预设运行周期中的线程快照对应的目标偏移地址;其中,预设策略用于定义确定目标偏移地址的规则。

S309、基于目标偏移地址,对预设运行周期中的线程快照进行符号化解析。

其中,符号化解析结果中包括函数名、函数所在文件名、函数在文件中对应的行号中的至少一种。

S310、确定经过符号化解析后的各个线程的调用栈中第二层栈帧对应的解析函数名。

S311、确定至少一个解析函数名中是否存在主函数的函数名,以及该函数名是否只出现在一个线程中,并根据确定结果对目标偏移地址进行验证。

由于正常情况下,程序运行过程中只有主线程的调用栈中第二层栈帧对应主函数,如果目标偏移地址的预测是准确的,则基于目标偏移地址对预设运行周期中的线程快照进行符号化解析后,至少一个解析函数名中必然存在主函数的函数名,且只出现在一个线程中,该线程即主线程。因此,如果确定至少一个解析函数名中存在主函数的函数名,且该函数名只出现在一个线程中,则目标偏移地址验证通过,目标偏移地址属于真实的偏移地址,进而基于目标偏移地址得到的符号化解析结果也是可靠的;如果确定至少一个解析函数名中不存在主函数的函数名,或者存在,但是该函数名出现在至少两个线程中,则目标偏移地址验证不通过,目标偏移地址不属于真实的偏移地址,进而基于目标偏移地址得到的符号化解析结果也是不可靠的,此时,可以再次执行本公开实施例的技术方案,对偏移地址进行预估,直至得到准确的目标偏移地址。

可选地,如果在应用程序的启动过程中,执行对预设运行周期中的线程快照进行符号化解析的操作,则本公开实施例提供的方法还包括:确定至少一个解析函数名中是否存在程序启动函数DidFinishLaunch的函数名,以使确定结果参与目标偏移地址的验证。程序启动函数在应用程序的启动阶段,属于必须执行的函数,因此,如果预设运行周期处于应用程序的启动阶段,至少一个解析函数名中存在程序启动函数DidFinishLaunch的函数名,则可以确定目标偏移地址验证通过,否则验证不通过。

当然,针对应用程序的启动阶段,也可以同时确定至少一个解析函数名中是否存在程序启动函数DidFinishLaunch的函数名以及主函数的函数名,如果两个函数名均存在,则目标偏移值验证通过,如果只存在程序启动函数DidFinishLaunch的函数名或者主函数的函数名,则可以认为目标偏移地址验证不通过。通过设置双重函数名的校验,可以进一步提高目标偏移地址的预测准确性。

在上述技术方案的基础上,进一步地,本公开实施例提供的线程快照解析方法还可以包括:基于预设运行周期中的线程快照的符号化解析结果,监控应用程序的运行性能;其中,符号化解析结果中包括函数名、函数所在文件名、函数在文件中对应的行号中的至少一种。例如,可以根据各个函数的运行时间周期,绘制火焰图,以实现对应用程序的运行性能的分析。

在本公开实施例中,通过对应用程序的预设运行周期中各个线程的线程快照进行聚合与过滤,并基于本方案提供的偏移地址预测方式对偏移地址进行预测,得到目标偏移地址,然后基于目标偏移地址对各个线程快照进行符号化解析,同时根据符号化解析结果对目标偏移地址进行验证,即反证偏移地址的预测结果是否准确,直至过滤出置信度最高的目标偏移地址(即置信度最高的偏移地址预估值),并作为最终的真实偏移地址对所有线程快照进行再次地符号化解析,此时的符号化解析结果可以作为有效的解析结果,用于应用程序的运行性能的监控与分析中,确保了应用程序运行性能的监控与分析的准确性。并且,采用本公开实施例的技术方案,无需通过调试应用程序的源代码,即可实现对应用程序运行性能的监控和分析,提高了程序运行性能监控和分析的效率。

图5为本公开实施例提供的一种线程快照解析装置的结构示意图,该装置可以采用软件和/或硬件实现,并可集成在具有计算能力的电子设备上,例如终端或者服务器等。

如图5所示,本公开实施例提供的线程快照解析装置500可以包括目标程序计数器地址确定模块501、符号表文件获取模块502、偏移地址区间确定模块503、目标偏移地址确定模块504和线程快照解析模块505,其中:

目标程序计数器地址确定模块501,用于在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址;其中,程序计数器地址用于标识程序运行过程中正在执行的函数指令地址;

符号表文件获取模块502,用于获取应用程序的符号表文件,并确定符号表文件中记录的主函数的初始起始地址、初始结束地址、以及应用程序对应的代码段的虚拟偏移值;

偏移地址区间确定模块503,用于基于至少一个目标程序计数器地址、初始起始地址、初始结束地址、以及虚拟偏移值,确定与预设运行周期中的线程快照对应的至少一个偏移地址区间;

目标偏移地址确定模块504,用于基于预设策略和至少一个偏移地址区间,确定与预设运行周期中的线程快照对应的目标偏移地址;其中,预设策略用于定义确定目标偏移地址的规则;

线程快照解析模块505,用于基于目标偏移地址,对预设运行周期中的线程快照进行符号化解析。

可选地,目标偏移地址确定模块504包括:

第一确定单元,用于基于每个偏移地址区间的最大端点值和最小端点值,确定每个偏移地址区间对应的目标整数;其中,目标整数为10的N次方;

第二确定单元,用于对每个偏移地址区间的最小端点值和目标整数之间的商值向下取整,得到每个偏移地址区间对应的第一倍数值;

第三确定单元,用于将每个偏移地址区间对应的第一倍数值加1,得到第二倍数值,并基于第二倍数值和每个偏移地址区间对应的目标整数的乘积,得到至少一个候选偏移地址;

第四确定单元,用于基于每个候选偏移地址和对应的偏移地址区间的数值关系、以及每个目标程序计数器地址的出现次数占比,从至少一个候选偏移地址中,确定与预设运行周期中的线程快照对应的目标偏移地址;

其中,出现次数占比基于预设运行周期中每个目标程序计数器地址在对应线程中的出现总次数与各个线程中的线程快照总数之和的比值得到。

可选地,第四确定单元具体用于:

如果候选偏移地址处于对应的偏移地址区间,且参与确定该偏移地址区间的目标程序计数器地址的出现次数占比超过第一占比阈值,则将该候选偏移地址确定为目标偏移地址。

可选地,如果满足候选偏移地址处于对应的偏移地址区间,且参与确定该偏移地址区间的目标程序计数器地址的出现次数占比超过第一占比阈值的情况下,候选偏移地址的数量为至少两个,则将至少两个候选偏移地址中的最小值确定为目标偏移地址。

可选地,本公开实施例提供的线程快照解析装置500还包括:

加载地址和空间占用大小确定模块,用于确定符号表文件中记录的代码段的加载地址和代码段的空间占用大小;

位置参数确定模块,用于基于加载地址、代码段的空间占用大小和虚拟偏移值,确定应用程序对应的位置参数;

相应地,线程快照解析模块505包括:

待解析程序计数器地址确定单元,用于将预设运行周期中各个线程快照中大于目标偏移地址、且小于目标偏移地址和位置参数之和的地址,确定为待解析程序计数器地址;

地址解析单元,用于基于目标偏移地址,对待解析程序计数器地址进行符号化解析。

可选地,目标程序计数器地址确定模块501包括:

出现次数确定单元,用于在应用程序的预设运行周期中,确定每个线程的调用栈中第二层栈帧对应的程序计数器地址,在该线程中的出现总次数;

出现次数占比确定单元,用于基于每个线程中的每个程序计数器地址的出现总次数,以及各个线程中的线程快照总数之和,确定每个线程中的每个程序计数器地址的出现次数占比;

目标程序计数器地址确定单元,用于将出现次数占比大于或等于第二占比阈值、且只出现在一个线程中的程序计数器地址确定为至少一个目标程序计数器地址。

可选地,本公开实施例提供的线程快照解析装置500还包括:

第一函数名确定模块,用于确定经过符号化解析后的各个线程的调用栈中第二层栈帧对应的解析函数名;

偏移地址验证模块,用于确定至少一个解析函数名中是否存在主函数的函数名,以及该函数名是否只出现在一个线程中,并根据确定结果对目标偏移地址进行验证。

可选地,如果在应用程序的启动过程中,执行对预设运行周期中的线程快照进行符号化解析的操作,则本公开实施例提供的线程快照解析装置500还包括:

第二函数名确定模块,确定至少一个解析函数名中是否存在程序启动函数DidFinishLaunch的函数名,以使确定结果参与目标偏移地址的验证。

可选地,本公开实施例提供的线程快照解析装置500还包括:

程序监控模块,用于基于预设运行周期中的线程快照的符号化解析结果,监控应用程序的运行性能;其中,符号化解析结果中包括函数名、函数所在文件名、函数在文件中对应的行号中的至少一种。

可选地,本公开实施例提供的线程快照解析装置500还包括:

待监控设备确定模块,用于根据设备标识,确定待监控设备;

待监控应用程序确定模块,用于根据应用程序标识,确定待监控设备中待监控的应用程序;

线程快照与线程ID确定模块,用于与待监控设备建立通信,获取在应用程序的预设运行周期中各个线程的线程快照,以及各个线程的线程ID;

程序计数器地址确定模块,用于基于线程ID对获取的线程快照进行拆分,并从每个线程的线程快照中,确定每个线程的调用栈中第二层栈帧对应的程序计数器地址。

本公开实施例所提供的线程快照解析装置可执行本公开实施例所提供的任意线程快照解析方法,具备执行方法相应的功能模块和有益效果。本公开装置实施例中未详尽描述的内容可以参考本公开任意方法实施例中的描述。

图6为本公开实施例提供的一种电子设备的结构示意图,用于对实现本公开实施例提供的线程快照解析方法的电子设备进行示例性说明。本公开实施例中的电子设备可以包括但不限于诸如移动电话、笔记本电脑、数字广播接收器、PDA(个人数字助理)、PAD(平板电脑)、PMP(便携式多媒体播放器)、车载终端(例如车载导航终端)等等的移动终端以及诸如数字TV、台式计算机、智能家居设备、可穿戴电子设备、服务器等等的固定终端。图6示出的电子设备仅仅是一个示例,不应对本公开实施例的功能和占用范围带来任何限制。

如图6所示,电子设备600包括一个或多个处理器601和存储器602。处理器601可以是中央处理单元(CPU)或者具有数据处理能力和/或指令执行能力的其他形式的处理单元,并且可以控制电子设备600中的其他组件以执行期望的功能。

存储器602可以包括一个或多个计算机程序产品,计算机程序产品可以包括各种形式的计算机可读存储介质,例如易失性存储器和/或非易失性存储器。易失性存储器例如可以包括随机存取存储器(RAM)和/或高速缓冲存储器(cache)等。非易失性存储器例如可以包括只读存储器(ROM)、硬盘、闪存等。在计算机可读存储介质上可以存储一个或多个计算机程序指令,处理器601可以运行程序指令,以实现本公开实施例提供的线程快照解析方法,还可以实现其他期望的功能。在计算机可读存储介质中还可以存储诸如输入信号、信号分量、噪声分量等各种内容。

其中,本公开实施例提供的线程快照解析方法可以包括:在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址;其中,程序计数器地址用于标识程序运行过程中正在执行的函数指令地址;获取应用程序的符号表文件,并确定符号表文件中记录的主函数的初始起始地址、初始结束地址、以及应用程序对应的代码段的虚拟偏移值;基于至少一个目标程序计数器地址、初始起始地址、初始结束地址、以及虚拟偏移值,确定与预设运行周期中的线程快照对应的至少一个偏移地址区间;基于预设策略和至少一个偏移地址区间,确定与预设运行周期中的线程快照对应的目标偏移地址;其中,预设策略用于定义确定目标偏移地址的规则;基于目标偏移地址,对预设运行周期中的线程快照进行符号化解析。应当理解,电子设备600还可以执行本公开方法实施例提供的其他可选实施方案。

在一个示例中,电子设备600还可以包括:输入装置603和输出装置604,这些组件通过总线系统和/或其他形式的连接机构(未示出)互连。

此外,该输入装置603还可以包括例如键盘、鼠标等等。

该输出装置604可以向外部输出各种信息,包括确定出的距离信息、方向信息等。该输出装置604可以包括例如显示器、扬声器、打印机、以及通信网络及其所连接的远程输出设备等等。

当然,为了简化,图6中仅示出了该电子设备600中与本公开有关的组件中的一些,省略了诸如总线、输入/输出接口等等的组件。除此之外,根据具体应用情况,电子设备600还可以包括任何其他适当的组件。

除了上述方法和设备以外,本公开实施例还提供一种计算机程序产品,其包括计算机程序或计算机程序指令,计算机程序或计算机程序指令在被计算设备执行时使得计算设备实现本公开实施例所提供的任意线程快照解析方法。

计算机程序产品可以以一种或多种程序设计语言的任意组合来编写用于执行本公开实施例操作的程序代码,程序设计语言包括面向对象的程序设计语言,诸如Java、C++等,还包括常规的过程式程序设计语言,诸如“C”语言或类似的程序设计语言。程序代码可以完全地在用户电子设备上执行、部分地在用户电子设备上执行、作为一个独立的软件包执行、部分在用户电子设备上且部分在远程电子设备上执行、或者完全在远程电子设备上执行。

此外,本公开实施例还可以提供一种计算机可读存储介质,其上存储有计算机程序指令,计算机程序指令在被计算设备执行时使得计算设备实现本公开实施例所提供的任意线程快照解析方法。

其中,本公开实施例提供的线程快照解析方法可以包括:在应用程序的预设运行周期中,基于各个线程的调用栈中第二层栈帧对应的程序计数器地址,确定至少一个目标程序计数器地址;其中,程序计数器地址用于标识程序运行过程中正在执行的函数指令地址;获取应用程序的符号表文件,并确定符号表文件中记录的主函数的初始起始地址、初始结束地址、以及应用程序对应的代码段的虚拟偏移值;基于至少一个目标程序计数器地址、初始起始地址、初始结束地址、以及虚拟偏移值,确定与预设运行周期中的线程快照对应的至少一个偏移地址区间;基于预设策略和至少一个偏移地址区间,确定与预设运行周期中的线程快照对应的目标偏移地址;其中,预设策略用于定义确定目标偏移地址的规则;基于目标偏移地址,对预设运行周期中的线程快照进行符号化解析。应当理解,计算机程序指令在被计算设备执行时,还可以使得计算设备实现本公开方法实施例提供的其他可选实施方案。

计算机可读存储介质可以采用一个或多个可读介质的任意组合。可读介质可以是可读信号介质或者可读存储介质。可读存储介质例如可以包括但不限于电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。

需要说明的是,在本文中,诸如“第一”和“第二”等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括要素的过程、方法、物品或者设备中还存在另外的相同要素。

以上仅是本公开的具体实施方式,使本领域技术人员能够理解或实现本公开。对这些实施例的多种修改对本领域的技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本公开的精神或范围的情况下,在其它实施例中实现。因此,本公开将不会被限制于本文的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。

相关技术
  • 线程快照解析方法、装置、设备和存储介质
  • 网络块设备快照读写方法、装置、设备及存储介质
技术分类

06120112986514