发明内容
为进一步压缩应用程序的apk,提出一种能够从apk中去除行号的情况下,可实现应用程序故障定位的文件处理方法、应用程序运行故障定位方法和计算机设备。
第一方面,本申请实施例提供一种文件处理方法,该文件包括应用程序的第一目标文件和应用程序对应的第二目标文件,第一目标文件的数据区域至少包括调试信息数据区域,该第一目标文件的数据内容至少包括目标映射关系数据,该调试信息数据区域被划分为多个数据子区域,该方法包括:
至少根据应用程序的各个方法各自的指令总长度,为各个方法分别指定数据子区域,并将各个方法的指令偏移数据写入方法对应的数据子区域的目标位置,其中,指令偏移数据包括指令偏移地址,每个数据子区域对应应用程序的一个或多个方法,且每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度,目标位置为指令偏移数据中包括的指令偏移地址指向的位置;
从第一目标文件中读取目标映射关系数据,目标映射关系数据包括各个方法的指令偏移地址与应用程序的源代码行号的映射关系数据;
将目标映射关系数据保存到应用程序对应的第二目标文件中,并从第一目标文件中删除目标映射关系数据。
本发明实施例提供的文件处理方法,一方面将第一目标文件中保存的目标映射关系数据删除,即从应用程序的apk包中删除了行号,达到了压缩应用程序的apk的目的;另一方面,将目标映射关系数据保存到第二目标应用文件,并在调试信息数据区域保存应用程序的指令的指令偏移地址,从而使得应用程序崩溃后,从调式信息数据区域读取指令偏移地址而非行号进行上报,使得故障定位阶段,可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位;再一方面,通过修改调试信息数据区域的数据保存格式,实现了该数据区域的分区共享,相较于现有的每个方法均对应一个调试信息数据区域,本发明实施例提供的新的数据保存格式使得调试信息数据区域所占存储空间更小,进一步实现了压缩apk的目的。
本发明实施例中,为上述各个方法指定数据子区域时,不仅可以依据各个方法各自的指令总长度,还可以依据各个方法各自的方法名和/或各个方法各自的方法参数数量。
也就是说,上述至少根据应用程序的各个方法各自的指令总长度,为上述各个方法分别指定数据子区域,其一种实现方式是:至少根据应用程序的各个方法各自的指令总长度和各自的方法名,为上述各个方法分别指定数据子区域,方法名相同的方法对应不同的数据子区域;另一种实现方式是:至少根据应用程序的各个方法各自的指令总长度和各自的方法参数数量,为上述各个方法分别指定数据子区域,方法参数数量不同的方法对应不同的数据子区域;又一种实现方式是:至少根据应用程序的各个方法各自的指令总长度、各自的方法名和各自的方法参数数量,为上述各个方法分别指定数据子区域。
发明人在实现本发明的过程中发现,部分版本的移动终端,若某方法的方法参数数量与为其指定的数据子区域对应的其他方法的方法参数数量不同,则该方法的指令引起应用程序崩溃时,上报的崩溃报告中不携带行号信息(若已将行号信息替换为指令偏移数据,也不会携带指令偏移数据),对崩溃定位造成干扰。为避免这种情况发生,本发明实施例提供的方法,在为方法指定数据子区域时,将相同方法参数数量的方法指定到同一个数据子区域(应当指出的是,这并不意味着所有方法参数数量相同的方法均会被指定到同一个数据子区域,这是因为为方法指定数据子区域还与其他参考因素有关)。
发明人在实现本发明的过程中还发现,若将相同方法名的方法指定到同一个数据子区域,那么在应用程序运行故障定位过程中,解析源代码行号时会存在歧义,导致无法成功解析。为避免这种情况发生,本发明实施例中,将相同方法名的方法指定到不同的数据子区域。
在上述任意方法实施例的基础上,指令偏移数据还可以包括指令偏移数据所在数据子区域的标识信息。
通过在指令偏移数据中携带数据子区域的标识信息,是为了在后续的应用程序运行故障定位阶段,根据崩溃报告中携带的偏移数据中的数据子区域的标识信息,对第二目标文件中的目标映射关系数据进行过滤,仅对过滤后的部分目标映射关系数据中查找行号,从而缩短查找时间,提高查找效率。
在此基础上,一种实现方式中,将目标映射关系数据保存到应用程序对应的第二目标文件中,具体可以根据对应的数据子区域将目标映射关系数据分组保存到应用程序对应的第二目标文件中,每组目标映射关系数据对应一个数据子区域。另一种实现方式中,目标映射关系数据中还包括各个方法对应的数据子区域的标识信息。
本发明实施例中,数据子区域的标识信息可以但不仅限于包括:数据子区域对应的方法的方法参数数量,和/或,数据子区域的索引。
其中,数据子区域的索引即为该数据子区域的偏移地址。
在上述任意方法实施例的基础上,调试信息数据区域的数据子区域划分方式可以为:
将应用程序的各个方法按照各自的指令总长度进行排序;
对所述各个方法构成的排序序列进行至少一次分组,直至每组方法的指令总长度最大值的求和结果不大于所述调制信息数据区域的长度,同一次得到的每组方法数量相同,每次分组的分组数量递减;
针对每次分组,查找每组方法的指令总长度最大值并求和,将求和结果与所述调试信息数据区域的长度比较,若求和结果不大于所述调试信息数据区域的长度,则按照各组方法的指令总长度最大值将所述调试信息数据区域分为与本次分组数量相同的数据子区域。
通过上述分区方式,可以使得分区更为均衡,避免出现某个或某些数据子区域对应的方法过多,而某个或某些数据子区域对应的方法过少。
第二方面,本发明实施例提供一种文件处理装置,该文件包括应用程序的第一目标文件和应用程序对应的第二目标文件,第一目标文件的数据区域至少包括调试信息数据区域,第一目标文件的数据内容至少包括目标映射关系数据,调试信息数据区域被划分为多个数据子区域,该装置包括:
指令偏移数据写入模块,用于至少根据上述应用程序的各个方法各自的指令总长度,为上述各个方法分别指定数据子区域,并将各个方法的指令偏移数据写入方法对应的数据子区域的目标位置,指令偏移数据包括指令偏移地址,每个数据子区域对应上述应用程序的一个或多个方法,且每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度,目标位置为指令偏移数据中包括的指令偏移地址指向的位置;
映射关系数据读取模块,用于从第一目标文件中读取目标映射关系数据,该目标映射关系数据包括上述各个方法的指令偏移地址与所述应用程序的源代码行号的映射关系数据;
映射关系数据转移模块,用于将上述目标映射关系数据保存到上述应用程序对应的第二目标文件中,并从上述第一目标文件中删除该目标映射关系数据。
本发明实施例提供的文件处理装置,一方面将第一目标文件中保存的目标映射关系数据删除,即从应用程序的apk包中删除了行号,达到了压缩应用程序的apk的目的;另一方面,将目标映射关系数据保存到第二目标应用文件,并在调试信息数据区域保存应用程序的指令的指令偏移地址,从而使得应用程序崩溃后,从调式信息数据区域读取指令偏移地址而非行号进行上报,使得故障定位阶段,可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位;再一方面,通过修改调试信息数据区域的数据保存格式,实现了该数据区域的分区共享,相较于现有的每个方法均对应一个调试信息数据区域,本发明实施例提供的新的数据保存格式使得调试信息数据区域所占存储空间更小,进一步实现了压缩apk的目的。
本发明实施例中,指令偏移数据写入模块为上述各个方法指定数据子区域时,不仅可以依据各个方法各自的指令总长度,还可以依据各个方法各自的方法名和/或各个方法各自的方法参数数量。
也就是说,上述指令偏移数据写入模块至少根据应用程序的各个方法各自的指令总长度,为上述各个方法分别指定数据子区域,其一种实现方式是:至少根据应用程序的各个方法各自的指令总长度和各自的方法名,为上述各个方法分别指定数据子区域,方法名相同的方法对应不同的数据子区域;另一种实现方式是:至少根据应用程序的各个方法各自的指令总长度和各自的方法参数数量,为上述各个方法分别指定数据子区域,方法参数数量不同的方法对应不同的数据子区域;又一种实现方式是:至少根据应用程序的各个方法各自的指令总长度、各自的方法名和各自的方法参数数量,为上述各个方法分别指定数据子区域。
发明人在实现本发明的过程中发现,部分版本的移动终端,若某方法的方法参数数量与为其指定的数据子区域对应的其他方法的方法参数数量不同,则该方法的指令引起应用程序崩溃时,上报的崩溃报告中不携带行号信息(若已将行号信息替换为指令偏移数据,也不会携带指令偏移数据),对崩溃定位造成干扰。为避免这种情况发生,本发明实施例提供的装置,在为方法指定数据子区域时,将相同方法参数数量的方法指定到同一个数据子区域(应当指出的是,这并不意味着所有方法参数数量相同的方法均会被指定到同一个数据子区域,这是因为为方法指定数据子区域还与其他参考因素有关)。
发明人在实现本发明的过程中还发现,若将相同方法名的方法指定到同一个数据子区域,那么在应用程序运行故障定位过程中,解析源代码行号时会存在歧义,导致无法成功解析。为避免这种情况发生,本发明实施例中,指令偏移数据写入模块将相同方法名的方法指定到不同的数据子区域。
在上述任意装置实施例的基础上,指令偏移数据还可以包括指令偏移数据所在数据子区域的标识信息。
通过在指令偏移数据中携带数据子区域的标识信息,是为了在后续的应用程序运行故障定位阶段,根据崩溃报告中携带的偏移数据中的数据子区域的标识信息,对第二目标文件中的目标映射关系数据进行过滤,仅对过滤后的部分目标映射关系数据中查找行号,从而缩短查找时间,提高查找效率。
在此基础上,一种实现方式中,映射关系数据转移模块将目标映射关系数据保存到应用程序对应的第二目标文件中,具体可以根据对应的数据子区域将目标映射关系数据分组保存到应用程序对应的第二目标文件中,每组目标映射关系数据对应一个数据子区域。另一种实现方式中,目标映射关系数据中还包括各个方法对应的数据子区域的标识信息。
本发明实施例中,数据子区域的标识信息可以但不仅限于包括:数据子区域对应的方法的方法参数数量,和/或,数据子区域的索引。
其中,数据子区域的索引即为该数据子区域的偏移地址。
在上述任意装置实施例的基础上,还可以包括数据子区域划分模块,用于:
将应用程序的各个方法按照各自的指令总长度进行排序;
对上述各个方法构成的排序序列进行至少一次分组,直至每组方法的指令总长度最大值的求和结果不大于调制信息数据区域的长度,同一次得到的每组方法数量相同,每次分组的分组数量递减;
针对每次分组,查找每组方法的指令总长度最大值并求和,将求和结果与调试信息数据区域的长度比较,若求和结果不大于调试信息数据区域的长度,则按照各组方法的指令总长度最大值将调试信息数据区域分为与本次分组数量相同的数据子区域。
通过上述分区方式,可以使得分区更为均衡,避免出现某个或某些数据子区域对应的方法过多,而某个或某些数据子区域对应的方法过少。
第三方面,本发明实施例提供一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,处理器执行所述计算机程序时实现上述方法实施例的步骤。
本发明实施例提供的计算机设备,一方面将第一目标文件中保存的目标映射关系数据删除,即从应用程序的apk包中删除了行号,达到了压缩应用程序的apk的目的;另一方面,将目标映射关系数据保存到第二目标应用文件,并在调试信息数据区域保存应用程序的指令的指令偏移地址,从而使得应用程序崩溃后,从调式信息数据区域读取指令偏移地址而非行号进行上报,使得故障定位阶段,可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位;再一方面,通过修改调试信息数据区域的数据保存格式,实现了该数据区域的分区共享,相较于现有的每个方法均对应一个调试信息数据区域,本发明实施例提供的新的数据保存格式使得调试信息数据区域所占存储空间更小,进一步实现了压缩apk的目的。
第四方面,本发明实施例提供一种计算机可读存储介质,包括存储有执行上述任意方法实施例提供的方法的程序。
本发明实施例提供的计算机可读存储介质,一方面将第一目标文件中保存的目标映射关系数据删除,即从应用程序的apk包中删除了行号,达到了压缩应用程序的apk的目的;另一方面,将目标映射关系数据保存到第二目标应用文件,并在调试信息数据区域保存应用程序的指令的指令偏移地址,从而使得应用程序崩溃后,从调式信息数据区域读取指令偏移地址而非行号进行上报,使得故障定位阶段,可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位;再一方面,通过修改调试信息数据区域的数据保存格式,实现了该数据区域的分区共享,相较于现有的每个方法均对应一个调试信息数据区域,本发明实施例提供的新的数据保存格式使得调试信息数据区域所占存储空间更小,进一步实现了压缩apk的目的。
第五方面,本发明实施例提供一种应用程序运行故障定位方法,包括:
从终端上报的应用程序崩溃报告中获取所述应用程序的目标指令的指令偏移数据,所述目标指令为所述应用程序崩溃时运行的指令,所述指令偏移数据包括指令偏移地址,所述指令偏移地址是所述应用程序崩溃报告的上报终端从所述应用程序的第一目标文件的调试信息数据区域查找得到的,所述调试信息数据区域被划分为多个数据子区域,每个数据子区域对应所述应用程序的一个或多个方法,每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度,且每个数据子区域中的目标位置保存有对应的各个方法的指令偏移数据,所述目标位置为指令偏移数据中包括的指令偏移地址指向的位置,第一目标文件的数据区域至少包括调试信息数据区域,该第一目标文件的数据内容至少包括目标映射关系数据;
从所述指令偏移数据中读取指令偏移地址;
在所述应用程序对应的第二目标文件中查找所述指令偏移地址对应的所述应用程序的源代码行号,所述第二目标文件中保存有目标映射关系数据,所述目标映射关系数据包括所述各个方法的指令偏移地址与所述应用程序的源代码行号的映射关系数据;
根据查找到的所述源代码行号确定导致所述应用程序崩溃的源代码。
本发明实施例提供的应用程序运行故障定位方法,由于能够获取第二目标文件,因此,即使崩溃报告中未携带源代码行号,而是携带指令偏移数据,仍然可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位。
在此基础上,上述指令偏移数据还可以包括所述指令偏移数据所在数据子区域的标识信息,相应的,在所述应用程序对应的第二目标文件中查找所述指令偏移地址对应的所述应用程序的源代码行号,其实现方式可以是:
从所述指令偏移数据中读取所述数据子区域的标识信息;
根据所述数据子区域的标识信息从所述第二目标文件中查找候选目标映射关系数据集合,并在所述候选目标映射关系数据集合中查找所述指令偏移地址对应的所述应用程序的源代码行号,所述候选目标映射关系数据集合为所述数据子区域的标识信息对应的目标映射关系数据构成的集合。
更进一步地,所述数据子区域的标识信息可以包括:所述数据子区域对应的方法的方法参数数量,和/或,所述数据子区域的索引。
第六方面,本发明实施例提供一种应用程序运行故障定位装置,包括:
指令偏移数据读取模块,用于从终端上报的应用程序崩溃报告中获取应用程序的目标指令的指令偏移数据,该目标指令为应用程序崩溃时运行的指令,该指令偏移数据包括指令偏移地址,该指令偏移地址是应用程序崩溃报告的上报终端从应用程序的第一目标文件的调试信息数据区域查找得到的,该调试信息数据区域被划分为多个数据子区域,每个数据子区域对应应用程序的一个或多个方法,每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度,且每个数据子区域中的目标位置保存有对应的各个方法的指令偏移数据,目标位置为指令偏移数据中包括的指令偏移地址指向的位置,第一目标文件的数据区域至少包括调试信息数据区域,第一目标文件的数据内容至少包括目标映射关系数据;
指令偏移地址读取模块,用于从指令偏移数据中读取指令偏移地址;
源代码行号查找模块,用于在应用程序对应的第二目标文件中查找指令偏移地址对应的应用程序的源代码行号,第二目标文件中保存有目标映射关系数据,目标映射关系数据包括各个方法的指令偏移地址与应用程序的源代码行号的映射关系数据;
故障源代码查找模块,用于根据查找到的源代码行号确定导致应用程序崩溃的源代码。
本发明实施例提供的应用程序运行故障定位装置,由于能够获取第二目标文件,因此,即使崩溃报告中未携带源代码行号,而是携带指令偏移数据,仍然可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位。
在此基础上,上述指令偏移数据还可以包括所述指令偏移数据所在数据子区域的标识信息,相应的,源代码行号查找模块在上述应用程序对应的第二目标文件中查找所述指令偏移地址对应的所述应用程序的源代码行号,其实现方式可以是:
从所述指令偏移数据中读取所述数据子区域的标识信息;
根据所述数据子区域的标识信息从所述第二目标文件中查找候选目标映射关系数据集合,并在所述候选目标映射关系数据集合中查找所述指令偏移地址对应的所述应用程序的源代码行号,所述候选目标映射关系数据集合为所述数据子区域的标识信息对应的目标映射关系数据构成的集合。
更进一步地,所述数据子区域的标识信息可以包括:数据子区域对应的方法的方法参数数量,和/或,数据子区域的索引。
第七方面,本发明实施例提供一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,处理器执行所述计算机程序时实现上述任意方法实施例的步骤。
本发明实施例提供的计算机设备,由于能够获取第二目标文件,因此,即使崩溃报告中未携带源代码行号,而是携带指令偏移数据,仍然可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位。
第八方面,本发明实施例提供一种计算机可读存储介质,包括存储有执行上述方法实施例提供的方法的程序。
本发明实施例提供的计算机可读存储介质,由于能够获取第二目标文件,因此,即使崩溃报告中未携带源代码行号,而是携带指令偏移数据,仍然可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位。
具体实施方式
为了使本申请的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本申请进行进一步详细说明。应当理解,此处描述的具体实施例仅仅用以解释本申请,并不用于限定本申请。
在本申请的说明书和权利要求书及上述附图中的描述的一些流程中,包含了按照特定顺序出现的多个操作,但是应该清楚了解,这些流程可以包括更多或更少的操作,并且这些操作可以按顺序执行或并行执行。
本发明实施例提供的文件处理方法在应用程序的开发阶段执行,具体是在应用程序编译期间,生成第一目标文件之后执行。通过将应用程序的每个第一目标文件中的调试信息数据区域共享,将调试信息数据区域划分为多个数据子区域,并使用特定的数据子区域指定方式,使应用程序的各个方法分组共享相同的存储区域(数据子区域)和内容(指令偏移数据),并保存记录有共享的内容的目标映射关系数据。在应用程序运行过程中,若发生崩溃,移动终端会向服务器上报崩溃日志,在解析上报的崩溃日志中的信息时,根据保存的目标映射关系数据可以定位导致崩溃的指令对应的行号,进而可以得到对应的原始堆栈。以运行在安卓***中的应用程序为例,在编译阶段以及崩溃日志解析阶段可实现无侵入式地接入以实现本发明实施例提供的方法。可有效实现对应用程序的apk的压缩,压缩量可以达到1M至2.5M,甚至更多。.
以运行在安卓***中的应用程序为例,第一目标文件是DEX文件。对于其他操作***,第一目标文件可以是其他原本用于保存行号信息的文件。
对于DEX文件,调试信息数据区域是debugeinfoItem所在的数据区域。对于其他形式的第一目标文件,调试信息数据区域是能够在应用程序崩溃后,原本能够从中读取行号信息的数据区域。
本发明实施例对第一目标文件进行了改进。具体的,以DEX文件为例,现有技术中,应用程序的每个方法分别对应一个debugeinfoItem,debugeinfoItem中保存对应方法的指令的偏移地址与源代码行号的映射关系数据。另外,现有技术中,在DEX文件的debug items中保存源代码行号。而在本发明实施例中,将完整的debugeinfoItem数据区域进行分区,划分为多个数据子区域,各个数据子区域的长度不完全相同,在数据子区域中保存对应方法的指令偏移数据,且删除了debug items中保存的源代码行号。
本发明实施例中,debugeinfoItem数据区域的划分可以是预先进行的,也可以是在本发明实施例提供的文件处理方法执行过程中进行的。
分区方式有多种,本发明实施例不做限定,例如,按照等长度差将debugeinfoItem划分为多个数据子区域。又例如,将应用程序的各个方法按照各自的指令总长度进行排序;对所述各个方法构成的排序序列进行至少一次分组,直至每组方法的指令总长度最大值的求和结果不大于所述调制信息数据区域的长度,同一次得到的每组方法数量相同,每次分组的分组数量递减;针对每次分组,查找每组方法的指令总长度最大值并求和,将求和结果与所述调试信息数据区域的长度比较,若求和结果不大于所述调试信息数据区域的长度,则按照各组方法的指令总长度最大值将所述调试信息数据区域分为与本次分组数量相同的数据子区域。通过这种分区方式,可以使得分区更为均衡,避免出现某个或某些数据子区域对应的方法过多,而某个或某些数据子区域对应的方法过少。
本发明实施例中,可以通过编译器的业务逻辑,使得生成的第一目标文件的调试信息数据区域中不再保存目标映射关系数据。也可以通过分区的方式格式化该数据区域。
本申请实施例提供一种文件处理方法,该文件包括应用程序的第一目标文件和应用程序对应的第二目标文件,第一目标文件的数据区域至少包括调试信息数据区域,该第一目标文件的数据内容至少包括目标映射关系数据,该调试信息数据区域被划分为多个数据子区域,如图1所示,该方法包括:
步骤101、至少根据应用程序的各个方法各自的指令总长度,为各个方法分别指定数据子区域,并将各个方法的指令偏移数据写入方法对应的数据子区域的目标位置。
其中,指令偏移数据包括指令偏移地址。
每个数据子区域对应应用程序的一个或多个方法,且每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度。例如,数据子区域A对应N个方法,其中,方法i的指令总长度在N个方法中最长,那么,数据子区域A的长度不小于方法i的指令总长度。
目标位置为指令偏移数据中包括的指令偏移地址指向的位置。本发明实施例中,位置是指存储空间中的存储位置。
步骤102、从第一目标文件中读取目标映射关系数据。
其中,目标映射关系数据包括各个方法的指令偏移地址与应用程序的源代码行号的映射关系数据。
步骤103、将目标映射关系数据保存到应用程序对应的第二目标文件中,并从第一目标文件中删除目标映射关系数据。
本发明实施例提供的文件处理方法,一方面将第一目标文件中保存的目标映射关系数据删除,即从应用程序的apk包中删除了行号,达到了压缩应用程序的apk的目的;另一方面,将目标映射关系数据保存到第二目标应用文件,并在调试信息数据区域保存应用程序的指令的指令偏移地址,从而使得应用程序崩溃后,从调式信息数据区域读取指令偏移地址而非行号进行上报,使得故障定位阶段,可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位;再一方面,通过修改调试信息数据区域的数据保存格式,实现了该数据区域的分区共享,相较于现有的每个方法均对应一个调试信息数据区域,本发明实施例提供的新的数据保存格式使得调试信息数据区域所占存储空间更小,进一步实现了压缩apk的目的。
本发明实施例中,为上述各个方法指定数据子区域时,不仅可以依据各个方法各自的指令总长度,还可以依据各个方法各自的方法名和/或各个方法各自的方法参数数量。
也就是说,上述至少根据应用程序的各个方法各自的指令总长度,为上述各个方法分别指定数据子区域,其一种实现方式是:至少根据应用程序的各个方法各自的指令总长度和各自的方法名,为上述各个方法分别指定数据子区域,方法名相同的方法对应不同的数据子区域;另一种实现方式是:至少根据应用程序的各个方法各自的指令总长度和各自的方法参数数量,为上述各个方法分别指定数据子区域,方法参数数量不同的方法对应不同的数据子区域;又一种实现方式是:至少根据应用程序的各个方法各自的指令总长度、各自的方法名和各自的方法参数数量,为上述各个方法分别指定数据子区域。
发明人在实现本发明的过程中发现,部分版本的移动终端,若某方法的方法参数数量与为其指定的数据子区域对应的其他方法的方法参数数量不同,则该方法的指令引起应用程序崩溃时,上报的崩溃报告中不携带行号信息(若已将行号信息替换为指令偏移数据,也不会携带指令偏移数据),对崩溃定位造成干扰。为避免这种情况发生,本发明实施例提供的方法,在为方法指定数据子区域时,将相同方法参数数量的方法指定到同一个数据子区域(应当指出的是,这并不意味着所有方法参数数量相同的方法均会被指定到同一个数据子区域,这是因为为方法指定数据子区域还与其他参考因素有关)。
发明人在实现本发明的过程中还发现,若将相同方法名的方法指定到同一个数据子区域,那么在应用程序运行故障定位过程中,解析源代码行号时会存在歧义,导致无法成功解析。为避免这种情况发生,本发明实施例中,将相同方法名的方法指定到不同的数据子区域。
下面举例说明为方法指定数据子区域。
若仅基于指令总长度和方法参数数量为方法指定数据子区域,那么,查找长度不小于方法的指令总长度的数据子区域;从查找到的数据子区域中选择长度最小的数据子区域;判断该长度最小的数据子区域对应的方法与本方法的参数数量是否相同;若相同,为该方法指定该长度最小的数据子区域;若不同,选择长度次小的数据子区域,并进行上述判断,直至成功为该方法指定数据子区域。
若仅基于指令总长度和方法名为方法指定数据子区域,那么,查找长度不小于方法的指令总长度的数据子区域;从查找到的数据子区域中选择长度最小的数据子区域;判断该长度最小的数据子区域对应的方法与本方法的方法名是否相同;若均不相同,为该方法指定该长度最小的数据子区域;若存在相同的方法名,选择长度次小的数据子区域,并进行上述判断,直至成功为该方法指定数据子区域。
若基于指令总长度、方法参数数量和方法名为方法指定数据子区域,可以参照上述实现方式实现,此处不再赘述。
在上述任意方法实施例的基础上,指令偏移数据还可以包括指令偏移数据所在数据子区域的标识信息。
通过在指令偏移数据中携带数据子区域的标识信息,是为了在后续的应用程序运行故障定位阶段,根据崩溃报告中携带的偏移数据中的数据子区域的标识信息,对第二目标文件中的目标映射关系数据进行过滤,仅对过滤后的部分目标映射关系数据中查找行号,从而缩短查找时间,提高查找效率。
在此基础上,一种实现方式中,将目标映射关系数据保存到应用程序对应的第二目标文件中,具体可以根据对应的数据子区域将目标映射关系数据分组保存到应用程序对应的第二目标文件中,每组目标映射关系数据对应一个数据子区域。另一种实现方式中,目标映射关系数据中还包括各个方法对应的数据子区域的标识信息。
本发明实施例中,数据子区域的标识信息可以但不仅限于包括:数据子区域对应的方法的方法参数数量,和/或,数据子区域的索引。
其中,数据子区域的索引即为该数据子区域的偏移地址。
下面结合具体应用场景,对本发明实施例提供的文件处理方法进行说明。
针对运行在安卓***上的某应用程序的编译阶段,经过aapt、javac、lancent、bytex等过程后,进行DEX文件合并(DexMerge),然后打包生成apk。
通过预先***的钩子函数(Hook),在打包生成apk后,读取apk中的各个Dex文件。
判断Dex文件中是否存在Debug Item,如果不存在,则返回Debug_Info的偏移为NO_OFFSET(0),不对Dex文件进行改动,如果存在,则按照以下处理方式实现Dex文件中的DebugInfo区域的共享:
将Dex文件中的原始Debug_Item中的行号信息写入第二目标文件LineNumberMapping.txt中;
针对每个方法,为其寻找合适大小的DebugInfo偏移(即DebugInfo子区域),并判断该方法的指令偏移数据是否已经写入该DebugInfo子区域,若已经写入,则直接返回该方法的指令偏移地址,将返回的指令偏移地址写入第二目标文件,并建立与行号信息的对应关系;否则,将该方法的指令偏移数据写入该DebugInfo子区域,返回该方法的指令偏移地址,并将返回的指令偏移地址写入第二目标文件,并建立与行号信息的对应关系。
其中,寻找合适大小的DebugInfo偏移的实现方式可以是:
计算该方法的指令总长度,如果方法的指令总长度超过65536,则不适合采用本发明实施例提供的方法,reng然按照现有方式写入方法的原始DebugInfo,并返回DebugInfo的偏移地址(实际为行号偏移),如果方法的指令总长度未超过65536,确定该方法的方法参数数量,查找已写入的方法的方法参数数量相同、且长度不小于该方法的指令总长度的DebugInfo子区域,可能查找到多个DebugInfo子区域,从最小的DebugInfo子区域开始判断,判断该DebugInfo子区域的是否存在与该方法同名的方法,如果没有,则将该方法的指令偏移数据写入该DebugInfo子区域,否则按照大小升序依次查找判断,直至找到合适的分区,或者确定未查找到合适的分区,则不再进行共享,仍然按照现有方式进行数据存储。
在此基础上,本发明实施例提出一种具体的指令偏移数据的数据格式,一条指令偏移数据占用一个整形量(32位),其中:
低16位用来存储指令偏移地址,方法的第一个指令偏移为0,每增加一个指令,则偏移量增加一个改指令暂用的内存大小。若一个方法指令总长度大于65536,则跳过优化。
17-24位用来保存分区(即子区域)索引,如果分区数已满(超过256个),则跳过优化。
25-30位用来保存该方法的方法参数的个数。如果方法参数个数超过64个,则跳过优化。
31-32位保留,恒定为0。
这样写入后的dex中指令数相近的Code_Item中的Debug_Info相同,同时因为原本是行号的数据改写成了指令偏移,所以上报的堆栈信息将会是指令偏移。
共享dex中的DebugInfo方案嵌入到打包流程:
Hook android标准打包的dexMerge或者package任务(两种任务自适应,找到其中任何一个执行dex行号优化过程)。
通过上述处理过程,将DebugInfo区域原本保存的行号偏移改成了保存指令偏移,且实现了对DebugInfo区域的共享。
基于与文件处理方法同样的发明构思,本发明实施例还提供一种文件处理装置,该文件包括应用程序的第一目标文件和应用程序对应的第二目标文件,第一目标文件的数据区域至少包括调试信息数据区域,第一目标文件的数据内容至少包括目标映射关系数据,调试信息数据区域被划分为多个数据子区域,如图2所示,该装置包括:
指令偏移数据写入模块201,用于至少根据上述应用程序的各个方法各自的指令总长度,为上述各个方法分别指定数据子区域,并将各个方法的指令偏移数据写入方法对应的数据子区域的目标位置,指令偏移数据包括指令偏移地址,每个数据子区域对应上述应用程序的一个或多个方法,且每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度,目标位置为指令偏移数据中包括的指令偏移地址指向的位置;
映射关系数据读取模块202,用于从第一目标文件中读取目标映射关系数据,该目标映射关系数据包括上述各个方法的指令偏移地址与所述应用程序的源代码行号的映射关系数据;
映射关系数据转移模块203,用于将上述目标映射关系数据保存到上述应用程序对应的第二目标文件中,并从上述第一目标文件中删除该目标映射关系数据。
其中,上述各个模块的具体实现方式可以参照上述方法实施例的描述,此处不再赘述。
本发明实施例提供的文件处理装置,一方面将第一目标文件中保存的目标映射关系数据删除,即从应用程序的apk包中删除了行号,达到了压缩应用程序的apk的目的;另一方面,将目标映射关系数据保存到第二目标应用文件,并在调试信息数据区域保存应用程序的指令的指令偏移地址,从而使得应用程序崩溃后,从调式信息数据区域读取指令偏移地址而非行号进行上报,使得故障定位阶段,可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位;再一方面,通过修改调试信息数据区域的数据保存格式,实现了该数据区域的分区共享,相较于现有的每个方法均对应一个调试信息数据区域,本发明实施例提供的新的数据保存格式使得调试信息数据区域所占存储空间更小,进一步实现了压缩apk的目的。
基于与文件处理方法同样的发明构思,本发明实施例提供一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,处理器执行所述计算机程序时实现上述方法实施例的步骤。
本发明实施例提供的计算机设备,一方面将第一目标文件中保存的目标映射关系数据删除,即从应用程序的apk包中删除了行号,达到了压缩应用程序的apk的目的;另一方面,将目标映射关系数据保存到第二目标应用文件,并在调试信息数据区域保存应用程序的指令的指令偏移地址,从而使得应用程序崩溃后,从调式信息数据区域读取指令偏移地址而非行号进行上报,使得故障定位阶段,可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位;再一方面,通过修改调试信息数据区域的数据保存格式,实现了该数据区域的分区共享,相较于现有的每个方法均对应一个调试信息数据区域,本发明实施例提供的新的数据保存格式使得调试信息数据区域所占存储空间更小,进一步实现了压缩apk的目的。
如上所述,本发明实施例提供的文件处理方法是在应用程序的编译期间实现的,那么,本发明实施例提供的计算机设备即为运行编译器的设备,可以是个人电脑(PC)、笔记本电脑、工作站、服务器等等。其一种实现结构如图3所示,至少包括:处理器301(如中央处理器),其可以根据存储在只读存储器(ROM)302中的程序或者从存储装置306加载到随机访问存储器(RAM)303中的程序而执行各种适当的动作和处理。在RAM 303中,还存储有计算机设备作所需的各种程序和数据。ROM 302、RAM 303以及存储装置306统称为存储器,处理器301、ROM 302、RAM 303以及存储装置306通过总线304彼此相连。输入/输出(I/O)接口305也连接至总线304。通常,以下装置可以连接至I/O接口305:包括例如触摸屏、触摸板、键盘、鼠标、摄像头、麦克风等的输入装置;包括例如液晶显示器(LCD)、扬声器等的输出装置;包括例如磁带、硬盘等的存储装置;以及通信装置。通信装置可以允许计算机设备与其他设备进行无线或有线通信以交换数据。虽然图3示出了具有各种装置的计算机设备,但是应理解的是,并不要求实施或具备所有示出的装置。可以替代地实施或具备更多或更少的装置。
如图4所示,本发明实施例提供一种应用程序运行故障定位方法,包括:
步骤401、从终端上报的应用程序崩溃报告中获取所述应用程序的目标指令的指令偏移数据。
其中,目标指令为上述应用程序崩溃时运行的指令,指令偏移数据包括指令偏移地址,指令偏移地址是上述应用程序崩溃报告的上报终端从该应用程序的第一目标文件的调试信息数据区域查找得到的,所述调试信息数据区域被划分为多个数据子区域,每个数据子区域对应所述应用程序的一个或多个方法,每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度,且每个数据子区域中的目标位置保存有对应的各个方法的指令偏移数据,所述目标位置为指令偏移数据中包括的指令偏移地址指向的位置,第一目标文件的数据区域至少包括调试信息数据区域,该第一目标文件的数据内容至少包括目标映射关系数据。
步骤402、从上述指令偏移数据中读取指令偏移地址。
步骤403、在上述应用程序对应的第二目标文件中查找指令偏移地址对应的应用程序的源代码行号。
其中,第二目标文件中保存有目标映射关系数据,目标映射关系数据包括上述各个方法的指令偏移地址与应用程序的源代码行号的映射关系数据。
步骤404、根据查找到的上述源代码行号确定导致上述应用程序崩溃的源代码。
本发明实施例提供的应用程序运行故障定位方法可以在网络侧设备(例如服务器)上实现,也可以在应用程序的提供方的终端设备(个人计算机、移动终端等)上实现。
本发明实施例提供的应用程序运行故障定位方法,由于能够获取第二目标文件,因此,即使崩溃报告中未携带源代码行号,而是携带指令偏移数据,仍然可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位。
在此基础上,上述指令偏移数据还可以包括所述指令偏移数据所在数据子区域的标识信息,相应的,在所述应用程序对应的第二目标文件中查找所述指令偏移地址对应的所述应用程序的源代码行号,其实现方式可以是:
从所述指令偏移数据中读取所述数据子区域的标识信息;
根据所述数据子区域的标识信息从所述第二目标文件中查找候选目标映射关系数据集合,并在所述候选目标映射关系数据集合中查找所述指令偏移地址对应的所述应用程序的源代码行号,所述候选目标映射关系数据集合为所述数据子区域的标识信息对应的目标映射关系数据构成的集合。
更进一步地,所述数据子区域的标识信息可以包括:所述数据子区域对应的方法的方法参数数量,和/或,所述数据子区域的索引。
下面结合上述具体应用场景对本发明实施例提供的运行故障定位方法进行详细说明。
在接收到应用程序的崩溃日志后,判断是否存在应用程序对应的Mapping文件,如果不存在,按照现有解析流程进行处理;
如果存在,判断是否存在-dslnmapping参数,如果存在,则调用自定义的Retrace解析崩溃堆栈,在仍然无法解析时,按照现有的解析流程进行处理,如果不存在,判断Mapping文件是否为MappingWithLineNumber.txt;
如果不是,按照现有解析流程进行处理,如果是MappingWithLineNumber.txt,进一步判断是否存在cachemappingsize参数;
如果不存在,则调用自定义的Retrace解析崩溃堆栈,在仍然无法解析时,按照现有的解析流程进行处理;如果存在,将MappingWithLineNumber.txt按照标识拆分成Proguard官方的Mapping文件和只包含指令偏移数据与行号信息映射关系的第二目标文件,利用第二目标文件,按照自定义的Retrace解析崩溃堆栈。
其中,自定义的Retrace即本发明实施例提供的运行故障定位方法。
基于与应用程序运行故障定位方法同样的发明构思,本发明实施例还提供一种应用程序运行故障定位装置,如图5所示,包括:
指令偏移数据读取模块501,用于从终端上报的应用程序崩溃报告中获取应用程序的目标指令的指令偏移数据,该目标指令为应用程序崩溃时运行的指令,该指令偏移数据包括指令偏移地址,该指令偏移地址是应用程序崩溃报告的上报终端从应用程序的第一目标文件的调试信息数据区域查找得到的,该调试信息数据区域被划分为多个数据子区域,每个数据子区域对应应用程序的一个或多个方法,每个数据子区域的长度不小于本数据子区域对应的各个方法各自的指令总长度,且每个数据子区域中的目标位置保存有对应的各个方法的指令偏移数据,目标位置为指令偏移数据中包括的指令偏移地址指向的位置,第一目标文件的数据区域至少包括调试信息数据区域,第一目标文件的数据内容至少包括目标映射关系数据;
指令偏移地址读取模块502,用于从指令偏移数据中读取指令偏移地址;
源代码行号查找模块503,用于在应用程序对应的第二目标文件中查找指令偏移地址对应的应用程序的源代码行号,第二目标文件中保存有目标映射关系数据,目标映射关系数据包括各个方法的指令偏移地址与应用程序的源代码行号的映射关系数据;
故障源代码查找模块504,用于根据查找到的源代码行号确定导致应用程序崩溃的源代码。
上述各模块的具体实现方式可以参照上述方法实施例的描述,此处不再赘述。
本发明实施例提供的应用程序运行故障定位装置,由于能够获取第二目标文件,因此,即使崩溃报告中未携带源代码行号,而是携带指令偏移数据,仍然可以根据上报的指令偏移地址在第二目标应用文件中找到对应的行号,进而实现故障定位。
基于与应用程序运行故障定位方法同样的发明构思,本发明实施例提供一种计算机设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,处理器执行所述计算机程序时实现上述任意方法实施例的步骤。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的装置和单元的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
本领域普通技术人员可以理解上述实施例的各种方法中的全部或部分步骤是可以通过程序来指令相关的硬件来完成,该程序可以存储于一计算机可读存储介质中,存储介质可以包括:只读存储器(ROM,Read Only Memory)、随机存取存储器(RAM,RandomAccess Memory)、磁盘或光盘等。
以上对本发明实施例所提供的一种移动终端进行了详细介绍,对于本领域的一般技术人员,依据本发明实施例的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。
上述所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。