CN112905381B - 用于获取调用栈中栈帧信息的方法、装置、设备和介质 - Google Patents
用于获取调用栈中栈帧信息的方法、装置、设备和介质 Download PDFInfo
- Publication number
- CN112905381B CN112905381B CN202110303887.1A CN202110303887A CN112905381B CN 112905381 B CN112905381 B CN 112905381B CN 202110303887 A CN202110303887 A CN 202110303887A CN 112905381 B CN112905381 B CN 112905381B
- Authority
- CN
- China
- Prior art keywords
- memory area
- area
- stack
- memory
- address
- 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
Links
- 238000000034 method Methods 0.000 title claims abstract description 171
- 230000008569 process Effects 0.000 claims abstract description 39
- 230000006870 function Effects 0.000 claims description 20
- 238000004590 computer program Methods 0.000 claims description 15
- 230000002159 abnormal effect Effects 0.000 claims description 5
- 230000005856 abnormality Effects 0.000 claims description 2
- 238000010586 diagram Methods 0.000 description 6
- 230000009471 action Effects 0.000 description 3
- 230000009286 beneficial effect Effects 0.000 description 3
- 238000005516 engineering process Methods 0.000 description 3
- 238000003491 array Methods 0.000 description 2
- 230000003287 optical effect Effects 0.000 description 2
- 230000006978 adaptation Effects 0.000 description 1
- 238000004458 analytical method Methods 0.000 description 1
- 238000004891 communication Methods 0.000 description 1
- 230000000694 effects Effects 0.000 description 1
- 230000007246 mechanism Effects 0.000 description 1
- 238000012986 modification Methods 0.000 description 1
- 230000004048 modification Effects 0.000 description 1
- 239000013307 optical fiber Substances 0.000 description 1
- 239000004065 semiconductor Substances 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/006—Identification
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/07—Responding to the occurrence of a fault, e.g. fault tolerance
- G06F11/0703—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation
- G06F11/0706—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation the processing taking place on a specific hardware platform or in a specific software environment
- G06F11/0718—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation the processing taking place on a specific hardware platform or in a specific software environment in an object-oriented system
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/07—Responding to the occurrence of a fault, e.g. fault tolerance
- G06F11/0703—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation
- G06F11/0766—Error or fault reporting or storing
- G06F11/0787—Storage of error reports, e.g. persistent data storage, storage using memory protection
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/07—Responding to the occurrence of a fault, e.g. fault tolerance
- G06F11/0703—Error or fault processing not based on redundancy, i.e. by taking additional measures to deal with the error or fault not making use of redundancy in operation, in hardware, or in data representation
- G06F11/079—Root cause analysis, i.e. error or fault diagnosis
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F2201/00—Indexing scheme relating to error detection, to error correction, and to monitoring
- G06F2201/87—Monitoring of transactions
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Quality & Reliability (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Health & Medical Sciences (AREA)
- Biomedical Technology (AREA)
- Executing Machine-Instructions (AREA)
- Debugging And Monitoring (AREA)
Abstract
本公开实施例涉及一种用于获取调用栈中栈帧信息的方法、装置、设备和介质,该方法包括:获取程序运行过程中存在异常的待处理调用栈;待处理调用栈的每个区域单元中包括方法指针以及与方法指针对应的指令偏移值;申请第一内存区域,用于存储方法指针以及对应的指令偏移值;申请第二内存区域;将第一内存区域的地址存入第二内存区域中的第一个区域单元;申请第三内存区域,并将第二内存区域的地址存入第三内存区域中的目标存储区域;基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息。本公开实施例实现了稳定地获取调用栈中栈帧的详细信息,且兼容性高。
Description
技术领域
本公开涉及计算机技术领域,尤其涉及一种用于获取调用栈中栈帧信息的方法、装置、设备和介质。
背景技术
在应用程序运行过程中,通过栈回溯,可以得到每个栈帧包括的方法指针(例如ArtMethod的指针)和指令偏移值(DexPc),但是不能直接得到描述当前方法的详细信息,例如方法名和源码行号等信息。
为了得到描述方法的详细信息,在现有方案中,一方面,可以将方法(例如ArtMethod)指针作为参数调用PrettyMethod函数得到其相应方法的字符串描述信息;另一方面,可以通过一些底层技术得到方法对应的dex_file信息,然后基于dex_file信息获取方法所在类名、方法名等信息。
然而,前述第一种方法中,只能得到方法的名字信息,无法得到其相应的行号信息,进而不能快速定位源码位置;前述第二种方法中,由于需求采用较多底层技术,实现复杂,稳定性难以保证,并且针对不同***版本的兼容性也存在不确定因素,可能需要涉及较大的适配工作量。
发明内容
为了解决上述技术问题或者至少部分地解决上述技术问题,本公开实施例提供了一种用于获取调用栈中栈帧信息的方法、装置、设备和介质。
第一方面,本公开实施例提供了一种用于获取调用栈中栈帧信息的方法,包括:
获取程序运行过程中存在异常的待处理调用栈;其中,所述待处理调用栈的每个区域单元中包括方法指针以及与所述方法指针对应的指令偏移值,所述待处理调用栈的区域单元总个数为N;
申请第一内存区域;其中,所述第一内存区域的前半部分区域单元用于存储所述方法指针,所述第一内存区域的后半部分区域单元用于存储与所述方法指针对应的指令偏移值,所述第一内存区域的区域单元总个数为2N;
获取所述第一内存区域的地址;
申请第二内存区域,并将所述第一内存区域的地址存入所述第二内存区域中的第一个区域单元;其中,所述第二内存区域的区域单元总个数为N+1;
获取所述第二内存区域的地址;
申请第三内存区域,并获取所述第三内存区域中的目标存储区域,将所述第二内存区域的地址存入所述目标存储区域;
基于所述目标存储区域存储的所述第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取所述待处理调用栈中各栈帧的信息。
第二方面,本公开实施例还提供了一种用于获取调用栈中栈帧信息的装置,包括:
调用栈获取模块,用于获取程序运行过程中存在异常的待处理调用栈;其中,所述待处理调用栈的每个区域单元中包括方法指针以及与所述方法指针对应的指令偏移值,所述待处理调用栈的区域单元总个数为N;
第一内存申请模块,用于申请第一内存区域;其中,所述第一内存区域的前半部分区域单元用于存储所述方法指针,所述第一内存区域的后半部分区域单元用于存储与所述方法指针对应的指令偏移值,所述第一内存区域的区域单元总个数为2N;
第一地址获取模块,用于获取所述第一内存区域的地址;
第二内存申请模块,用于申请第二内存区域,并将所述第一内存区域的地址存入所述第二内存区域中的第一个区域单元;其中,所述第二内存区域的区域单元总个数为N+1;
第二地址获取模块,用于获取所述第二内存区域的地址;
第三内存申请模块,用于申请第三内存区域,并获取所述第三内存区域中的目标存储区域,将所述第二内存区域的地址存入所述目标存储区域;
栈帧信息获取模块,用于基于所述目标存储区域存储的所述第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取所述待处理调用栈中各栈帧的信息。
第三方面,本公开实施例还提供了一种电子设备,包括存储器和处理器,其中,所述存储器中存储有计算机程序,当所述计算机程序被所述处理器执行时,使得所述电子设备实现本公开实施例提供的任一所述的用于获取调用栈中栈帧信息的方法。
第四方面,本公开实施例还提供了一种计算机可读存储介质,所述存储介质中存储有计算机程序,当所述计算机程序被计算设备执行时,使得所述计算设备实现本公开实施例提供的任一所述的用于获取调用栈中栈帧信息的方法。
本公开实施例提供的技术方案与现有技术相比至少具有如下优点:
在本公开实施例中,通过申请第一内存区域,将程序运行过程中存在异常的待处理调用栈中的方法指针存储在第一内存区域的前半部分区域单元,将与方法指针对应的指令偏移值存储在第一内存区域的后半部分区域单元,然后将第一内存区域的地址存储在申请的第二内存区域中的第一个区域单元,其次将第二内存区域的地址存储在申请的第三内存区域中的目标存储区域,从而实现对待处理调用栈中方法指针和对应的指令偏移值的可控式存储,最后基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息,解决了现有方案中无法稳定地获取栈帧的详细信息的问题,实现了稳定地获取栈帧的详细信息,并且降低了栈帧详细信息获取的复杂度,对不同的***版本具有较高的兼容性。通过获取栈帧的详细信息,有助于后续便捷定位程序运行过程中的异常,提高了解决程序异常的效率。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本公开的实施例,并与说明书一起用于解释本公开的原理。
为了更清楚地说明本公开实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1为本公开实施例提供的一种用于获取调用栈中栈帧信息的方法的流程图;
图2为本公开实施例提供的另一种用于获取调用栈中栈帧信息的方法的流程图;
图3为本公开实施例提供的一种栈帧信息获取过程中各个数组之间的关系示意图;
图4为本公开实施例提供的一种用于获取调用栈中栈帧信息的装置的结构示意图;
图5为本公开实施例提供的一种电子设备的结构示意图。
具体实施方式
为了能够更清楚地理解本公开的上述目的、特征和优点,下面将对本公开的方案进行进一步描述。需要说明的是,在不冲突的情况下,本公开的实施例及实施例中的特征可以相互组合。
在下面的描述中阐述了很多具体细节以便于充分理解本公开,但本公开还可以采用其他不同于在此描述的方式来实施;显然,说明书中的实施例只是本公开的一部分实施例,而不是全部的实施例。
图1为本公开实施例提供的一种用于获取调用栈中栈帧信息的方法的流程图,该方法可以由用于获取调用栈中栈帧信息的装置执行,该装置可以采用软件和/或硬件实现,并可集成在具有计算能力的电子设备上,例如移动终端、笔记本、电脑等。
如图1所示,本公开实施例提供的用于获取调用栈中栈帧信息的方法可以包括:
S101、获取程序运行过程中存在异常的待处理调用栈;其中,待处理调用栈的每个区域单元中包括方法指针以及与方法指针对应的指令偏移值,待处理调用栈的区域单元总个数为N。
本公开实施例中提及的程序运行过程可以是电子设备上至少一个应用程序的运行过程,可以利用现有方案中可用的调用栈获取方式获取程序运行过程中存在异常的调用栈,例如程序崩溃、程序卡顿等过程中产生的调用栈,作为后续的处理对象。
具体地,调用栈在代码底层上可以使用数组的形式表示,数组中的元素位置对应调用栈的区域单元,调用栈的区域单元总个数N即数组的长度N,N取整数,数组的每个元素由一个方法指针ArtMethod(或称为ArtMethod指针)和一个指令偏移值DexPc构成,方法指针和指令偏移值存在一一对应关系。
可选地,获取程序运行过程中存在异常的调用栈,包括:
获取程序运行过程中存在异常的多个调用栈;
通过对比各个调用栈中的方法指针和指令偏移值,确定多个调用栈中的重复调用栈;即方法指针和对应的指令偏移值均相同的调用栈,属于重复的调用栈;
基于重复调用栈对多个调用栈进行去重处理,得到待处理调用栈。
通过对获取的多个调用栈进行去重处理,可以减少待处理的调用栈的数量,提高栈帧信息获取的效率,而且不会影响获取的栈帧信息的准确性。
S102、申请第一内存区域;其中,第一内存区域的前半部分区域单元用于存储方法指针,第一内存区域的后半部分区域单元用于存储与方法指针对应的指令偏移值,第一内存区域的区域单元总个数为2N。
通过申请第一内存区域,用于实现对待处理的每个调用栈中方法指针和指令偏移值的二次存储。具体地,方法指针可以用于获取栈帧的方法名、栈帧方法所在类名、栈帧对应的源码文件名中的至少之一;指令偏移值可以用于获取栈帧对应的源码行号。
示例性地,申请第一内存区域,包括:
为属于整型(int型)或者长整型(long型)的第一数组申请第一内存区域。在构建程序代码过程中,构建用于为前述第一数组申请第一内存区域的代码,例如可以使用newint[]命令或者new long[]命令,实现创建属于整型或者长整型的第一数组;其中,第一数组的元素分别存储在第一内存区域的区域单元中。针对32位的***,第一数组的类型采用整型;针对64位的***,第一数组的类型采用长整型。
为了确保后续稳定且准确地获取栈帧信息,方法指针或者指令偏移值在待处理调用栈中的出现顺序与在第一内存区域中的出现顺序相同,也即方法指针或者指令偏移值在待处理调用栈中的出现顺序与在第一数组中的出现顺序相同。
S103、获取第一内存区域的地址。
内存区域的地址获取可以基于任意可用的现有地址获取方式实现。第一内存区域的地址可以用于获取第一内存区域中的存储内容。
S104、申请第二内存区域,并将第一内存区域的地址存入第二内存区域中的第一个区域单元;其中,第二内存区域的区域单元总个数为N+1。
在执行栈帧信息获取功能模块getStackTrace对应的代码段的过程中,只关注第二内存区域中的第一个区域单元中的存储内容,因此,将第一内存区域的地址存入第二内存区域中的第一个区域单元,针对第二内存区域中其他剩余区域单元的存储内容,本公开实施例不作具体限定,例如可以保留默认值null。并且,基于栈帧信息获取函数getStackTrace的本身特性,为了确保函数调用的成功实现,第二内存区域的区域单元总个数需要为N+1。
示例性地,申请第二内存区域,包括:为对象基类Object下的第二数组申请第二内存区域。在构建程序代码过程中,构建用于为对象基类Object下的第二数组(即针对java程序,第二数组属于Object[]类型)申请第二内存区域的代码,例如可以使用newObject[]命令,实现创建对象基类Object下的第二数组;其中,第二数组的元素分别存储在第二内存区域的区域单元中。
需要说明的是,在本公开实施例中,在确保方案逻辑合理的情况下,各个操作步骤之间的执行顺序并无严格限定。例如,针对操作S103和操作S104,可以先获取第一内存区域的地址,然后申请第二内存区域,还可以先申请第二内存区域,然后获取第一内存区域的地址,当然,获取第一内存区域的地址和申请第二内存区域,还可以同时执行,本公开实施例对此不作具体限定。
S105、获取第二内存区域的地址。
第二内存区域的地址可以用于获取第二内存区域中的存储内容。
S106、申请第三内存区域,并获取第三内存区域中的目标存储区域,将第二内存区域的地址存入目标存储区域。
第三内存区域中的目标存储区域可以根据栈帧信息获取函数getStackTrace的执行需求来确定。示例性地,申请第三内存区域,包括:为异常父类Throwable下的目标对象申请第三内存区域。在构建程序代码过程中,构建用于为异常父类Throwable下的目标对象申请第三内存区域的代码,例如可以使用newThrowable()命令,实现创建异常父类Throwable下的目标对象,该目标对象可以示例性地采用thr表示。完成第三内存区域的申请后,可以获取第三内存区域中的目标存储区域,将第二内存区域的地址存入目标存储区域。S107、基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息。
具体地,在getStackTrace函数执行过程中,可以通过第二内存区域的地址,获取到第二内存区域中的第一个区域单元中存储的第一内存区域的地址,进而可以通过第一内存区域的地址,获取到第一内存区域中存储的方法指针以及方法指针对应的指令偏移值,然后可以基于方法指针获取栈帧的方法名、栈帧方法所在类名、栈帧对应的源码文件名中的至少之一,基于方法指针对应的指令偏移值获取栈帧对应的源码行号。本公开实施例中提及的各栈帧的信息可以包括以下至少之一:栈帧的方法名、栈帧方法所在类名、栈帧对应的源码文件名和栈帧对应的源码行号。
示例性地,在创建异常父类Throwable下的目标对象的过程中,会同时创建目标对象的初始成员(backtrace成员),目标存储区域即用于存储backtrace成员。栈帧信息获取功能模块getStackTrace对应的代码段中的getStackTrace函数属于异常父类Throwable下的目标对象的函数。通过将第二内存区域的地址存入目标存储区域,也即实现利用对象基类Object下的第二数组替换目标对象的初始成员,从而实现对getStackTrace函数的输入的有效控制,达到获取所需的栈帧信息的效果。
可选地,基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息,包括:
基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息的存储地址;
基于存储地址,获取各栈帧的信息。
函数getStackTrace属于***函数,在函数执行过程中,其返回值为一个指向特定数组的存储地址,通过该存储地址可以获取到需求的栈帧信息。示例性地,该存储地址指向栈帧信息数组StackTraceElement,栈帧信息数组中的每个元素对应不同栈帧的信息。
例如,获取栈帧信息数组StackTraceElement中的每个元素对应的不同栈帧的信息,可以采用以下程序命令实现:
StackTraceElement[]elements=thr.getStackTrace();//thr用于指代异常父类Throwable下的目标对象;elements作为StackTraceElement[]类型下的一个数组名,此处仅用于示例,可以灵活确定数组名
elements[0].getMethodName();//当前栈帧的方法名
elements[0].getClassName();//当前栈帧方法所在类名
elements[0].getFileName();//当前栈帧对应的源码文件名
elements[0].getLineNumber();//当前栈帧对应的源码行号
以上程序命令作为一种示例,不应理解为对本公开实施例的具体限定。
为便于理解本公开实施例,以下从程序编写的角度,利用示例性地程序代码对本公开实施例进行说明,但不应理解为对本公开实施例的具体限定。具体地,以待处理调用栈的区域单元总个数N等于2为例,进行示例性说明,即待处理调用栈中包括2组元素:方法指针method1和指令偏移值dexpc1、方法指针method2和指令偏移dexpc2。程序代码示例如下:
int method1,method2,dexpc1,dexpc2;//本方案的原始输入,即待处理调用栈中的方法指针和指令偏移值
method1=973;//以下关于method1、method1、dexpc1、dexpc2的具体取值,需要根据实际获取的调用栈而定,此处的各个数值仅作为一种示例
method2=460;
dexpc1=0;
dexpc2=0;
int[]firstIL=new int[4];//创建属于整型且长度为4(即元素个数为4)的第一数组firstIL,firstIL作为数组名只是一种示例,可以根据程序编写情况灵活设置,并且,此处以32位***为例,创建整型数组,如果是64位***,则需创建长整型数组
firstIL[0]=method1;//将调用栈中的第一个方法指针method1作为数组firstIL的第一个元素
firstIL[1]=method2;//将调用栈中的第二个方法指针method2作为数组firstIL的第二个元素
firstIL[2]=dexpc1;//将调用栈中的第一个指令偏移dexpc1作为数组firstIL的第三个元素
firstIL[3]=dexpc2;//将调用栈中的第二个指令偏移dexpc2作为数组firstIL的第四个元素
Object[]backtrace=new Object[3];//创建对象基类Object下的第二数组backtrace,backtrace作为数组名只是一种示例,可以根据程序编写情况灵活设置,第二数组backtrace的长度为3,即元素个数为3
backtrace[0]=firstIL;//将第一数组firstIL的指针作为第二数组backtrace的第一元素,第二数组backtrace的其他元素可以取默认值null Throwable thr=newThrowable();//创建异常父类Throwable下的目标对象thr,thr作为对象名只是一种示例,可以根据程序编写情况灵活设置
try{
Field backtraceFiled=Throwable.class.getDeclaredField(name:“backtrace”);
backtraceFiled.set(thr,backtrace);//利用对象基类Object下的第二数组backtrace替换目标对象thr的初始成员backtrace
StackTraceElement[]elements=thr.getStackTrace();//调用***函数getStackTrace获取调用栈中各个栈帧的信息
}catch(Throwable e){
e.ptintStackTrace();//输出各个栈帧的信息
}
进一步地,本公开实施例提供的方法还可以包括:将各栈帧的信息发送至服务端;其中,服务端用于基于各栈帧的信息分析程序运行过程中的异常,从而提高解决程序异常的效率。示例性地,服务器可以与多个用于执行本公开实施例技术方案的电子设备进行通信,基于针对相同应用程序运行过程中的调用栈中各栈帧的信息,通过信息的统计与分析,准确定位应用程序运行过程中的异常。
在本公开实施例中,通过申请第一内存区域,将待处理调用栈中的方法指针存储在第一内存区域的前半部分区域单元,将与方法指针对应的指令偏移值存储在第一内存区域的后半部分区域单元,然后将第一内存区域的地址存储在申请的第二内存区域中的第一个区域单元,其次将第二内存区域的地址存储在申请的第三内存区域中的目标存储区域,从而实现对待处理调用栈中方法指针和对应的指令偏移值的可控式存储,最后基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息,解决了现有方案中无法稳定地获取栈帧的详细信息的问题,实现了稳定地获取栈帧的详细信息,并且降低了栈帧详细信息获取的复杂度,对不同的***版本具有较高的兼容性。通过获取栈帧的详细信息,有助于后续便捷定位程序运行过程中的异常,提高了解决程序异常的效率。
图2为本公开实施例提供的另一种用于获取调用栈中栈帧信息的方法的流程图,用于对本公开实施例进行示例性说明,不应理解为对本公开实施例的具体限定,具体地,图2从计算机程序执行流程的角度对本公开实施例进行示例性解释。
如图2所示,在程序执行过程中,可以首先获取到程序运行过程中存在异常的调用栈的底层表示:例如一个数组,该数组可以在编程阶段便示例性地定义为采用为rawArr表示,数组的每个元素由一个ArtMethod指针和一个对应的指令偏移值DexPc构成,数组长度记为N;创建一个长度为2N的int或long型数组(32位***情况下是int型,64位***情况下是long型),该数组可以在编程阶段便示例性地定义为采用firstIL表示;
然后,将数组rawArr中的所有ArtMethod指针设置为数组firstIL的前半段元素,将数组rawArr的所有DexPc值设置为数组firstIL的后半段元素,其中由于数组firstIL的长度是数组rawArr长度的两倍,所以ArtMethod指针和DexPc值分别占用数组firstIL的一半,并且,ArtMethod指针或DexPc值在数组firstIL中的出现顺序在数组rawArr中的出现顺序相同;
创建一个Object[]类型(对象基类)的数组,该数组可以在编程阶段便示例性地定义为采用bt表示,其长度为N+1,然后令数组bt的第一个元素为数组firstIL,数组bt剩余的N个元素保留默认值null即可;图3作为示例,示出了各个数组之间的关系示意图;
创建一个Throwable类(异常父类)的对象,该对象可以在编程阶段便示例性地定义为采用thr表示,利用反射将对象thr的backtrace成员替换为上述数组bt,然后调用对象thr的getStackTrace函数,得到StackTraceElement类型的数组,该数组中的每个元素对应一个栈帧,并提供了栈帧的方法名、栈帧方法所在类名、栈帧对应的源码文件名和栈帧对应的源码行号等详细信息。
本公开实施例实现了稳定地获取栈帧的详细信息,并且降低了栈帧详细信息获取的复杂度,对不同的***版本具有较高的兼容性。
图4为本公开实施例提供的一种用于获取调用栈中栈帧信息的装置的结构示意图,该装置可以采用软件和/或硬件实现,并可集成在任意具有计算能力的电子设备上,例如移动终端、笔记本、电脑等。
如图4所示,本公开实施例提供的用于获取调用栈中栈帧信息的装置400可以包括调用栈获取模块401、第一内存申请模块402、第一地址获取模块403、第二内存申请模块404、第二地址获取模块405、第三内存申请模块406和栈帧信息获取模块407,其中:
调用栈获取模块401,用于获取程序运行过程中存在异常的待处理调用栈;其中,待处理调用栈的每个区域单元中包括方法指针以及与方法指针对应的指令偏移值,待处理调用栈的区域单元总个数为N;
第一内存申请模块402,用于申请第一内存区域;其中,第一内存区域的前半部分区域单元用于存储方法指针,第一内存区域的后半部分区域单元用于存储与方法指针对应的指令偏移值,第一内存区域的区域单元总个数为2N;
第一地址获取模块403,用于获取第一内存区域的地址;
第二内存申请模块404,用于申请第二内存区域,并将第一内存区域的地址存入第二内存区域中的第一个区域单元;其中,第二内存区域的区域单元总个数为N+1;
第二地址获取模块405,用于获取第二内存区域的地址;
第三内存申请模块406,用于申请第三内存区域,并获取第三内存区域中的目标存储区域,将第二内存区域的地址存入目标存储区域;
栈帧信息获取模块407,用于基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息。
可选地,第一内存申请模块402具体用于:
为属于整型或者长整型的第一数组申请第一内存区域;其中,第一数组的元素分别存储在第一内存区域的区域单元中;
可选地,第二内存申请模块404具体用于:
为对象基类Object下的第二数组申请第二内存区域;其中,第二数组的元素分别存储在第二内存区域的区域单元中;
可选地,第三内存申请模块406具体用于:
为异常父类Throwable下的目标对象申请第三内存区域。
可选地,方法指针或者指令偏移值在待处理调用栈中的出现顺序与在第一内存区域中的出现顺序相同。
可选地,栈帧信息获取模块407包括:
存储地址返回单元,用于基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息的存储地址;
栈帧信息获取单元,用于基于存储地址,获取各栈帧的信息。
可选地,存储地址指向栈帧信息数组,栈帧信息数组中的每个元素对应不同栈帧的信息。
可选地,各栈帧的信息包括以下至少之一:栈帧的方法名、栈帧方法所在类名、栈帧对应的源码文件名和栈帧对应的源码行号。
可选地,本公开实施例提供的用于获取调用栈中栈帧信息的装置400还包括:
栈帧信息发送模块,用于将各栈帧的信息发送至服务端;其中,服务端用于基于各栈帧的信息分析程序运行过程中的异常。
可选地,调用栈获取模块401包括:
调用栈获取单元,用于获取程序运行过程中存在异常的多个调用栈;
重复调用栈确定单元,用于通过对比各个调用栈中的方法指针和指令偏移值,确定多个调用栈中的重复调用栈;
调用栈去重单元,用于基于重复调用栈对多个调用栈进行去重处理,得到待处理调用栈。
本公开实施例所提供的用于获取调用栈中栈帧信息的装置可执行本公开实施例所提供的任意用于获取调用栈中栈帧信息的方法,具备执行方法相应的功能模块和有益效果。本公开装置实施例中未详尽描述的内容可以参考本公开任意方法实施例中的描述。
图5为本公开实施例提供的一种电子设备的结构示意图,用于对实现本公开实施例提供的用于获取调用栈中栈帧信息的方法的电子设备进行示例性说明。本公开实施例中的电子设备可以包括但不限于诸如移动电话、笔记本电脑、数字广播接收器、PDA(个人数字助理)、PAD(平板电脑)、PMP(便携式多媒体播放器)、车载终端(例如车载导航终端)等等的移动终端以及诸如数字TV、台式计算机、智能家居设备、可穿戴电子设备、服务器等等的固定终端。图5示出的电子设备仅仅是一个示例,不应对本公开实施例的功能和占用范围带来任何限制。
如图5所示,电子设备500包括一个或多个处理器501和存储器502。处理器501可以是中央处理单元(CPU)或者具有数据处理能力和/或指令执行能力的其他形式的处理单元,并且可以控制电子设备500中的其他组件以执行期望的功能。
存储器502可以包括一个或多个计算机程序产品,计算机程序产品可以包括各种形式的计算机可读存储介质,例如易失性存储器和/或非易失性存储器。易失性存储器例如可以包括随机存取存储器(RAM)和/或高速缓冲存储器(cache)等。非易失性存储器例如可以包括只读存储器(ROM)、硬盘、闪存等。在计算机可读存储介质上可以存储一个或多个计算机程序指令,处理器501可以运行程序指令,以实现本公开实施例提供的用于获取调用栈中栈帧信息的方法,还可以实现其他期望的功能。在计算机可读存储介质中还可以存储诸如输入信号、信号分量、噪声分量等各种内容。
其中,本公开实施例提供的用于获取调用栈中栈帧信息的方法可以包括:获取程序运行过程中存在异常的待处理调用栈;其中,待处理调用栈的每个区域单元中包括方法指针以及与方法指针对应的指令偏移值,待处理调用栈的区域单元总个数为N;申请第一内存区域;其中,第一内存区域的前半部分区域单元用于存储方法指针,第一内存区域的后半部分区域单元用于存储与方法指针对应的指令偏移值,第一内存区域的区域单元总个数为2N;获取第一内存区域的地址;申请第二内存区域,并将第一内存区域的地址存入第二内存区域中的第一个区域单元;其中,第二内存区域的区域单元总个数为N+1;获取第二内存区域的地址;申请第三内存区域,并获取第三内存区域中的目标存储区域,将第二内存区域的地址存入目标存储区域;基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息。应当理解,电子设备500还可以执行本公开方法实施例提供的其他可选实施方案。
在一个示例中,电子设备500还可以包括:输入装置503和输出装置504,这些组件通过总线***和/或其他形式的连接机构(未示出)互连。
此外,该输入装置503还可以包括例如键盘、鼠标等等。
该输出装置504可以向外部输出各种信息,包括确定出的距离信息、方向信息等。该输出装置504可以包括例如显示器、扬声器、打印机、以及通信网络及其所连接的远程输出设备等等。
当然,为了简化,图5中仅示出了该电子设备500中与本公开有关的组件中的一些,省略了诸如总线、输入/输出接口等等的组件。除此之外,根据具体应用情况,电子设备500还可以包括任何其他适当的组件。
除了上述方法和设备以外,本公开实施例还提供一种计算机程序产品,其包括计算机程序或计算机程序指令,计算机程序或计算机程序指令在被计算设备执行时使得计算设备实现本公开实施例所提供的任意用于获取调用栈中栈帧信息的方法。
计算机程序产品可以以一种或多种程序设计语言的任意组合来编写用于执行本公开实施例操作的程序代码,程序设计语言包括面向对象的程序设计语言,诸如Java、C++等,还包括常规的过程式程序设计语言,诸如“C”语言或类似的程序设计语言。程序代码可以完全地在用户电子设备上执行、部分地在用户电子设备上执行、作为一个独立的软件包执行、部分在用户电子设备上且部分在远程电子设备上执行、或者完全在远程电子设备上执行。
此外,本公开实施例还可以提供一种计算机可读存储介质,其上存储有计算机程序指令,计算机程序指令在被计算设备执行时使得计算设备实现本公开实施例所提供的任意用于获取调用栈中栈帧信息的方法。
其中,本公开实施例提供的用于获取调用栈中栈帧信息的方法可以包括:获取程序运行过程中存在异常的待处理调用栈;其中,待处理调用栈的每个区域单元中包括方法指针以及与方法指针对应的指令偏移值,待处理调用栈的区域单元总个数为N;申请第一内存区域;其中,第一内存区域的前半部分区域单元用于存储方法指针,第一内存区域的后半部分区域单元用于存储与方法指针对应的指令偏移值,第一内存区域的区域单元总个数为2N;获取第一内存区域的地址;申请第二内存区域,并将第一内存区域的地址存入第二内存区域中的第一个区域单元;其中,第二内存区域的区域单元总个数为N+1;获取第二内存区域的地址;申请第三内存区域,并获取第三内存区域中的目标存储区域,将第二内存区域的地址存入目标存储区域;基于目标存储区域存储的第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取待处理调用栈中各栈帧的信息。应当理解,计算机程序指令在被计算设备执行时,还可以使得计算设备实现本公开方法实施例提供的其他可选实施方案。
计算机可读存储介质可以采用一个或多个可读介质的任意组合。可读介质可以是可读信号介质或者可读存储介质。可读存储介质例如可以包括但不限于电、磁、光、电磁、红外线、或半导体的***、装置或器件,或者任意以上的组合。可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式盘、硬盘、随机存取存储器(RAM)、只读存储器(ROM)、可擦式可编程只读存储器(EPROM或闪存)、光纤、便携式紧凑盘只读存储器(CD-ROM)、光存储器件、磁存储器件、或者上述的任意合适的组合。
需要说明的是,在本文中,诸如“第一”和“第二”等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括要素的过程、方法、物品或者设备中还存在另外的相同要素。
以上仅是本公开的具体实施方式,使本领域技术人员能够理解或实现本公开。对这些实施例的多种修改对本领域的技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本公开的精神或范围的情况下,在其它实施例中实现。因此,本公开将不会被限制于本文的这些实施例,而是要符合与本文所公开的原理和新颖特点相一致的最宽的范围。
Claims (10)
1.一种用于获取调用栈中栈帧信息的方法,其特征在于,包括:
获取程序运行过程中存在异常的待处理调用栈;其中,所述待处理调用栈的每个区域单元中包括方法指针以及与所述方法指针对应的指令偏移值,所述待处理调用栈的区域单元总个数为N;
申请第一内存区域;其中,所述第一内存区域的前半部分区域单元用于存储所述方法指针,所述第一内存区域的后半部分区域单元用于存储与所述方法指针对应的指令偏移值,所述第一内存区域的区域单元总个数为2N;
获取所述第一内存区域的地址;
申请第二内存区域,并将所述第一内存区域的地址存入所述第二内存区域中的第一个区域单元;其中,所述第二内存区域的区域单元总个数为N+1;
获取所述第二内存区域的地址;
申请第三内存区域,并获取所述第三内存区域中的目标存储区域,将所述第二内存区域的地址存入所述目标存储区域;
基于所述目标存储区域存储的所述第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取所述待处理调用栈中各栈帧的信息。
2.根据权利要求1所述的方法,其特征在于:
申请第一内存区域,包括:
为属于整型或者长整型的第一数组申请所述第一内存区域;其中,所述第一数组的元素分别存储在所述第一内存区域的区域单元中;
申请第二内存区域,包括:
为对象基类Object下的第二数组申请所述第二内存区域;其中,所述第二数组的元素分别存储在所述第二内存区域的区域单元中;
申请第三内存区域,包括:
为异常父类Throwable下的目标对象申请所述第三内存区域。
3.根据权利要求1所述的方法,其特征在于,所述方法指针或者所述指令偏移值在所述待处理调用栈中的出现顺序与在所述第一内存区域中的出现顺序相同。
4.根据权利要求1所述的方法,其特征在于,基于所述目标存储区域存储的所述第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取所述待处理调用栈中各栈帧的信息,包括:
基于所述目标存储区域存储的所述第二内存区域的地址,执行所述栈帧信息获取功能模块getStackTrace对应的代码段,获取所述待处理调用栈中各栈帧的信息的存储地址;
基于所述存储地址,获取所述各栈帧的信息。
5.根据权利要求1所述的方法,其特征在于,所述各栈帧的信息包括以下至少之一:栈帧的方法名、栈帧方法所在类名、栈帧对应的源码文件名和栈帧对应的源码行号。
6.根据权利要求1所述的方法,其特征在于,还包括:
将所述各栈帧的信息发送至服务端;其中,所述服务端用于基于所述各栈帧的信息分析程序运行过程中的异常。
7.根据权利要求1所述的方法,其特征在于,获取程序运行过程中存在异常的调用栈,包括:
获取程序运行过程中存在异常的多个调用栈;
通过对比各个调用栈中的所述方法指针和所述指令偏移值,确定所述多个调用栈中的重复调用栈;
基于所述重复调用栈对所述多个调用栈进行去重处理,得到所述待处理调用栈。
8.一种用于获取调用栈中栈帧信息的装置,其特征在于,包括:
调用栈获取模块,用于获取程序运行过程中存在异常的待处理调用栈;其中,所述待处理调用栈的每个区域单元中包括方法指针以及与所述方法指针对应的指令偏移值,所述待处理调用栈的区域单元总个数为N;
第一内存申请模块,用于申请第一内存区域;其中,所述第一内存区域的前半部分区域单元用于存储所述方法指针,所述第一内存区域的后半部分区域单元用于存储与所述方法指针对应的指令偏移值,所述第一内存区域的区域单元总个数为2N;
第一地址获取模块,用于获取所述第一内存区域的地址;
第二内存申请模块,用于申请第二内存区域,并将所述第一内存区域的地址存入所述第二内存区域中的第一个区域单元;其中,所述第二内存区域的区域单元总个数为N+1;
第二地址获取模块,用于获取所述第二内存区域的地址;
第三内存申请模块,用于申请第三内存区域,并获取所述第三内存区域中的目标存储区域,将所述第二内存区域的地址存入所述目标存储区域;
栈帧信息获取模块,用于基于所述目标存储区域存储的所述第二内存区域的地址,执行栈帧信息获取功能模块getStackTrace对应的代码段,获取所述待处理调用栈中各栈帧的信息。
9.一种电子设备,其特征在于,包括存储器和处理器,其中,所述存储器中存储有计算机程序,当所述计算机程序被所述处理器执行时,使得所述电子设备实现权利要求1-7中任一项所述的用于获取调用栈中栈帧信息的方法。
10.一种计算机可读存储介质,其特征在于,所述存储介质中存储有计算机程序,当所述计算机程序被计算设备执行时,使得所述计算设备实现权利要求1-7中任一项所述的用于获取调用栈中栈帧信息的方法。
Priority Applications (3)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110303887.1A CN112905381B (zh) | 2021-03-22 | 2021-03-22 | 用于获取调用栈中栈帧信息的方法、装置、设备和介质 |
PCT/CN2022/078365 WO2022199331A1 (zh) | 2021-03-22 | 2022-02-28 | 用于获取调用栈中栈帧信息的方法、装置、设备和介质 |
US18/277,005 US20240126627A1 (en) | 2021-03-22 | 2022-02-28 | Method and apparatus for obtaining information of stack frame in call stack, device, and medium |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202110303887.1A CN112905381B (zh) | 2021-03-22 | 2021-03-22 | 用于获取调用栈中栈帧信息的方法、装置、设备和介质 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN112905381A CN112905381A (zh) | 2021-06-04 |
CN112905381B true CN112905381B (zh) | 2022-12-06 |
Family
ID=76105898
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202110303887.1A Active CN112905381B (zh) | 2021-03-22 | 2021-03-22 | 用于获取调用栈中栈帧信息的方法、装置、设备和介质 |
Country Status (3)
Country | Link |
---|---|
US (1) | US20240126627A1 (zh) |
CN (1) | CN112905381B (zh) |
WO (1) | WO2022199331A1 (zh) |
Families Citing this family (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN112905381B (zh) * | 2021-03-22 | 2022-12-06 | 北京字节跳动网络技术有限公司 | 用于获取调用栈中栈帧信息的方法、装置、设备和介质 |
Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103019707A (zh) * | 2012-11-30 | 2013-04-03 | 华为技术有限公司 | 调用栈的解析处理方法及装置 |
CN110764941A (zh) * | 2019-09-05 | 2020-02-07 | 北京字节跳动网络技术有限公司 | 获取调用栈栈帧指令偏移的方法、装置、介质和设备 |
CN111813465A (zh) * | 2020-06-19 | 2020-10-23 | 北京字节跳动网络技术有限公司 | 一种信息获取方法、装置、介质和设备 |
Family Cites Families (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103106132B (zh) * | 2013-03-05 | 2016-03-16 | 中标软件有限公司 | Linux***崩溃时内核函数调用栈分析调试方法 |
US11188470B2 (en) * | 2019-05-22 | 2021-11-30 | Vdoo Connected Trust Ltd. | Dynamic identification of stack frames |
US11442739B2 (en) * | 2019-09-16 | 2022-09-13 | International Business Machines Carporation | Exception handling |
CN112084024B (zh) * | 2020-08-31 | 2024-02-02 | 北京字节跳动网络技术有限公司 | 一种内存监控方法、装置、介质和电子设备 |
CN112905381B (zh) * | 2021-03-22 | 2022-12-06 | 北京字节跳动网络技术有限公司 | 用于获取调用栈中栈帧信息的方法、装置、设备和介质 |
-
2021
- 2021-03-22 CN CN202110303887.1A patent/CN112905381B/zh active Active
-
2022
- 2022-02-28 WO PCT/CN2022/078365 patent/WO2022199331A1/zh active Application Filing
- 2022-02-28 US US18/277,005 patent/US20240126627A1/en active Pending
Patent Citations (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103019707A (zh) * | 2012-11-30 | 2013-04-03 | 华为技术有限公司 | 调用栈的解析处理方法及装置 |
CN110764941A (zh) * | 2019-09-05 | 2020-02-07 | 北京字节跳动网络技术有限公司 | 获取调用栈栈帧指令偏移的方法、装置、介质和设备 |
CN111813465A (zh) * | 2020-06-19 | 2020-10-23 | 北京字节跳动网络技术有限公司 | 一种信息获取方法、装置、介质和设备 |
Also Published As
Publication number | Publication date |
---|---|
US20240126627A1 (en) | 2024-04-18 |
CN112905381A (zh) | 2021-06-04 |
WO2022199331A1 (zh) | 2022-09-29 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN109976761B (zh) | 软件开发工具包的生成方法、装置及终端设备 | |
CN109542399B (zh) | 软件开发方法、装置、终端设备及计算机可读存储介质 | |
US7861222B2 (en) | Discoscript: a simplified distributed computing scripting language | |
CN109960678B (zh) | 一种命名处理方法及计算机处理装置 | |
US9183065B1 (en) | Providing access to an application programming interface through a named pipe | |
US8370618B1 (en) | Multiple platform support in computer system firmware | |
CN111209736A (zh) | 文本文件解析方法、装置、计算机设备及存储介质 | |
CN110688096A (zh) | 包含插件的应用程序的构建方法、装置、介质及电子设备 | |
CN112905381B (zh) | 用于获取调用栈中栈帧信息的方法、装置、设备和介质 | |
US8910136B2 (en) | Generating code that calls functions based on types of memory | |
CN110888972A (zh) | 一种基于Spark Streaming的敏感内容识别方法及装置 | |
CN114138363A (zh) | 程序数据调用方法、装置、设备及存储介质 | |
US8539461B2 (en) | Method for identifying memory of virtual machine and computer system thereof | |
CN109324838B (zh) | 单片机程序的执行方法、执行装置及终端 | |
US20140289722A1 (en) | Parallel program installation and configuration | |
US8819494B2 (en) | Automatically changing parts in response to tests | |
US7856344B2 (en) | Method for transforming overlapping paths in a logical model to their physical equivalent based on transformation rules and limited traceability | |
CN107341038B (zh) | 兼容性处理方法、装置及电子设备 | |
US11645616B1 (en) | Verifying the integrity of data transmitted between a firmware and a baseboard management controller (BMC) | |
CN108762637A (zh) | 控制方法、装置及*** | |
CN114253675A (zh) | 事务处理方法、装置、设备及存储介质 | |
CN110018828B (zh) | 源代码检查方法、装置及终端设备 | |
CN112416444A (zh) | 一种板卡切换控制方法、装置、设备及介质 | |
US8135943B1 (en) | Method, apparatus, and computer-readable medium for generating a dispatching function | |
CN112580086A (zh) | 配置文件的访问保护方法、装置、设备以及存储介质 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |