CN116594750A - 一种函数调用收集方法、装置、设备、存储介质及产品 - Google Patents

一种函数调用收集方法、装置、设备、存储介质及产品 Download PDF

Info

Publication number
CN116594750A
CN116594750A CN202310574189.4A CN202310574189A CN116594750A CN 116594750 A CN116594750 A CN 116594750A CN 202310574189 A CN202310574189 A CN 202310574189A CN 116594750 A CN116594750 A CN 116594750A
Authority
CN
China
Prior art keywords
function
stack
information
calling
recorded
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.)
Pending
Application number
CN202310574189.4A
Other languages
English (en)
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.)
Guangzhou Baiguoyuan Network Technology Co Ltd
Original Assignee
Guangzhou Baiguoyuan Network Technology Co Ltd
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 Guangzhou Baiguoyuan Network Technology Co Ltd filed Critical Guangzhou Baiguoyuan Network Technology Co Ltd
Priority to CN202310574189.4A priority Critical patent/CN116594750A/zh
Publication of CN116594750A publication Critical patent/CN116594750A/zh
Pending legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/46Multiprogramming arrangements
    • G06F9/48Program initiating; Program switching, e.g. by interrupt
    • G06F9/4806Task transfer initiation or dispatching
    • G06F9/4843Task transfer initiation or dispatching by program, e.g. task dispatcher, supervisor, operating system
    • G06F9/4881Scheduling strategies for dispatcher, e.g. round robin, multi-level priority queues
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02DCLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
    • Y02D10/00Energy efficient computing, e.g. low power processors, power management or thermal management

Landscapes

  • Engineering & Computer Science (AREA)
  • Software Systems (AREA)
  • Theoretical Computer Science (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Debugging And Monitoring (AREA)

Abstract

本申请实施例提供了一种函数调用收集方法、装置、设备、存储介质及产品。本申请实施例提供的技术方案通过定时对主线程进行堆栈回溯操作获取主线程的堆栈信息,根据堆栈信息中记录的调用函数确定函数进出信息,并将函数进出信息记录到缓冲区中,并且在检测到异常事件时,根据缓冲区中记录的函数进出信息生成函数调用记录信息,函数调用记录信息可反应在发生异常事件前的函数调用轨迹,准确收集反应异常事件的函数调用轨迹,提高对异常事件的定位准确度以及效率。

Description

一种函数调用收集方法、装置、设备、存储介质及产品
技术领域
本申请实施例涉及计算机技术领域,尤其涉及一种函数调用收集方法、装置、设备、存储介质及产品。
背景技术
随着移动互联网的快速发展,用户在智能设备上安装了越来越多的应用程序,用户可使用这些应用程序进行工作、娱乐等活动。在应用程序的使用过程中,应用界面的流畅性是一个非常直观且重要的指标,如果应用界面不流畅,频繁出现卡顿,会严重影响用户的使用体验。
在应用程序中有个用于处理用户输入、界面绘制的主线程(UI线程),如果主线程执行了繁忙的任务导致无法及时进行界面绘制,那么就会出现应用界面的卡顿,如果卡顿时间过长,甚至可能出现应用程序无响应而导致应用程序强制退出。为了提升应用程序的流畅性,给用户带来更好的应用体验,需要对主线程的函数调用轨迹进行收集,以定位和解决卡顿、无响应的问题。目前,对函数调用轨迹的收集一般是在发现卡顿或无响应等异常事件时,收集当前时刻的堆栈信息,但不少问题并非由于该堆栈引起的,函数调用轨迹的收集不准确,导致对异常事件的定位准确度较低。
发明内容
本申请实施例提供一种函数调用收集方法、装置、设备、存储介质及产品,以解决相关技术中函数调用轨迹的收集不准确,导致对异常事件的定位准确度较低的技术问题,以准确收集函数调用轨迹,提高对异常事件的定位准确度。
在第一方面,本申请实施例提供了一种函数调用收集方法,包括:
定时对主线程进行堆栈回溯操作,得到所述主线程的堆栈信息;
根据所述堆栈信息中记录的调用函数确定函数进出信息,将所述函数进出信息记录到缓冲区中;
在检测到异常事件的情况下,基于所述缓冲区中记录的所述函数进出信息生成函数调用记录信息。
在第二方面,本申请实施例提供了一种函数调用收集装置,包括堆栈获取模块、信息记录模块和函数记录模块,其中:
所述堆栈获取模块,配置为定时对主线程进行堆栈回溯操作,得到所述主线程的堆栈信息;
所述信息记录模块,配置为根据所述堆栈信息中记录的调用函数确定函数进出信息,将所述函数进出信息记录到缓冲区中;
所述函数记录模块,配置为在检测到异常事件的情况下,基于所述缓冲区中记录的所述函数进出信息生成函数调用记录信息。
在第三方面,本申请实施例提供了一种函数调用收集设备,包括:存储器以及一个或多个处理器;
所述存储器,用于存储一个或多个程序;
当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现如第一方面所述的函数调用收集方法。
在第四方面,本申请实施例提供了一种存储计算机可执行指令的非易失性存储介质,所述计算机可执行指令在由计算机处理器执行时用于执行如第一方面所述的函数调用收集方法。
在第五方面,本申请实施例提供了一种计算机程序产品,该计算机程序产品包括计算机程序,该计算机程序存储在计算机可读存储介质中,设备的至少一个处理器从计算机可读存储介质读取并执行计算机程序,使得设备执行如第一方面所述的函数调用收集方法。
本申请实施例通过定时对主线程进行堆栈回溯操作获取主线程的堆栈信息,根据堆栈信息中记录的调用函数确定函数进出信息,并将函数进出信息记录到缓冲区中,并且在检测到异常事件时,根据缓冲区中记录的函数进出信息生成函数调用记录信息,函数调用记录信息可反应在发生异常事件前的函数调用轨迹,准确收集反应异常事件的函数调用轨迹,提高对异常事件的定位准确度以及效率。
附图说明
图1是本申请实施例提供的一种函数调用收集方法的流程图;
图2是本申请实施例提供的另一种函数调用收集方法的流程图;
图3是本申请实施例提供的一种堆栈信息获取流程示意图;
图4是本申请实施例提供的一种函数进出信息记录示意图;
图5是本申请实施例提供的一种函数调用收集装置的结构示意图;
图6是本申请实施例提供的一种函数调用收集设备的结构示意图。
具体实施方式
为了使本申请的目的、技术方案和优点更加清楚,下面结合附图对本申请具体实施例作进一步的详细描述。可以理解的是,此处所描述的具体实施例仅仅用于解释本申请,而非对本申请的限定。另外还需要说明的是,为了便于描述,附图中仅示出了与本申请相关的部分而非全部内容。在更加详细地讨论示例性实施例之前应当提到的是,一些示例性实施例被描述成作为流程图描绘的处理或方法。虽然流程图将各项操作(或步骤)描述成顺序的处理,但是其中的许多操作可以被并行地、并发地或者同时实施。此外,各项操作的顺序可以被重新安排。当其操作完成时上述处理可以被终止,但是还可以具有未包括在附图中的附加步骤。上述处理可以对应于方法、函数、规程、子例程、子程序等等。
本申请提供的函数调用收集方法可应用于应用程序运行过程中的函数调用轨迹的收集,旨在根据主线程的堆栈信息中记录的调用函数确定函数进出信息,并将函数进出信息记录到缓冲区中,在检测到异常事件时,根据缓冲区中记录的函数进出信息生成函数调用记录信息,准确收集反应异常事件的函数调用轨迹,提高对异常事件的定位准确度。对于传统的函数调用收集方案,一般是对应用程式的卡顿、无响应等异常情况进行监测,并在监测到异常情况时获取主线程当前的堆栈信息,并根据堆栈信息生成函数调用轨迹并保存,这种函数调用收集方式虽然可定位一部分异常问题,但是这些函数调用轨迹只记录了异常时刻的堆栈,但不少问题并非由于该堆栈引起,函数调用轨迹的收集不准确,导致对异常事件的定位准确度较低。基于此,提供本申请实施例的一种函数调用收集方法,以解决现有函数调用收集方案函数调用轨迹的收集不准确,导致对异常事件的定位准确度较低的技术问题。
图1给出了本申请实施例提供的一种函数调用收集方法的流程图,本申请实施例提供的函数调用收集方法可以由函数调用收集装置来执行,该函数调用收集装置可以通过硬件和/或软件的方式实现,并集成在函数调用收集设备中。
下述以函数调用收集装置执行函数调用收集方法为例进行描述。参考图1,该函数调用收集方法包括:
S110:定时对主线程进行堆栈回溯操作,得到主线程的堆栈信息。
本方案提供的主线程(UI线程)可理解为应用程序中负责处理用户输入、界面绘制的线程,为了减轻主线程的负担,保证用户使用体验,通常会将耗时、繁重的任务交给其他线程处理,主线程主要处理一些简单的任务,减少对处理用户输入、界面绘制的影响,当仍会不可避免地将一些耗时、繁重的任务交给主线程处理,容易导致卡顿、应用程序无响应(ANR,即应用程序无法在特定时间内处理完相应事件,例如屏幕触摸)等异常事件的发生。为了分析定位异常事件发生的原因,通常需要利用主线程的函数调用轨迹进行分析定位。
示例性的,按照设定的采样时间间隔,对主线程进行堆栈回溯操作得到主线程对应的堆栈信息。其中,主线程的堆栈信息中记录有主线程对应的一个或多个调用函数,其中,调用函数可理解为主线程所调用的函数。例如,主线程在需要实现某个功能而调用对应的函数时,函数将作为调用函数进入到主线程的堆栈中,并在完成调用函数的调用后,将调用函数从堆栈中移出。
S120:根据堆栈信息中记录的调用函数确定函数进出信息,将函数进出信息记录到缓冲区中。
示例性的,在每次得到主线程的堆栈信息后,根据堆栈信息中记录的调用函数确定函数进出信息。在得到函数进出信息后,将函数进出信息记录到缓冲区中。
其中,函数进出信息记录有主线程所调用的调用函数进入和退出主线程堆栈的情况,例如可记录主线程所调用的调用函数进入和退出主线程堆栈的时间,根据调用函数进入和退出主线程堆栈的时间可确定每个调用函数的耗时,从而定位异常情况的原因。
例如,应用程序在运行的过程中会不断调用函数,函数之间可以互相调用,例如在一开始,所执行的函数为A、B、C、D(即函数A调用了函数B,函数B调用了函数C,函数C调用了函数D),此时函数A被称为栈底,函数D被称为栈顶,函数ABCD就是当前时刻主线程的堆栈,此时设备正在执行的指令为函数D中的某一行代码,对应的函数进出信息指示当前时刻函数A、B、C、D均为进入堆栈。在下一时刻完成对函数C和D的调用后,函数B又调用了函数E,函数E又调用了函数F,那么此时主线程的堆栈为函数ABEF,此时对应的函数进出信息指示函数C和D为退出堆栈,函数E和F退出堆栈。
可选的,本方案提供的缓冲区可以是设定大小的缓冲区,通过设定大小的缓冲区限定缓存的函数进出信息的信息量,减少时间过久的不必要的函数进出信息在缓冲区中的留存(这部分函数调出信息一般不是引起异常情况的原因),提高异常分析定位效率。在一个实施例中,本方案提供的缓冲区可以是环形缓冲区(ringbuffe,一种固定尺寸、头尾相连的缓冲区,适合缓存数据流),利用环形缓冲区保存函数进出信息可有效减少数据缓存过程中额外的动态内存分配,提高数据缓存效率。
S130:在检测到异常事件的情况下,基于缓冲区中记录的函数进出信息生成函数调用记录信息。
示例性的,在检测到异常事件(例如出现应用程序卡顿、无响应等异常)时,获取缓冲区中记录的函数进出信息,并根据函数进出信息生成函数调用记录信息。其中,函数调用记录信息可反映缓冲区中记录的一次或多次记录的函数进出信息。根据函数进出信息中反映的前后的函数进出信息,可确定一个或多个调用函数的耗时(例如调用函数从进入堆栈到退出堆栈的时间)。
可选的,函数调用记录信息中可记录一个或多个调用函数的耗时,即在基于缓冲区中记录的函数进出信息生成函数调用记录信息时,同时生成一个或多个调用函数的耗时并记录到函数调用记录中,可直接基于函数调用记录确定一个或多个调用函数的耗时。
上述,通过定时对主线程进行堆栈回溯操作获取主线程的堆栈信息,根据堆栈信息中记录的调用函数确定函数进出信息,并将函数进出信息记录到缓冲区中,并且在检测到异常事件时,根据缓冲区中记录的函数进出信息生成函数调用记录信息,函数调用记录信息可反应在发生异常事件前的函数调用轨迹,准确收集反应异常事件的函数调用轨迹,提高对异常事件的定位准确度以及效率。
在上述实施例的基础上,图2给出了本申请实施例提供的另一种函数调用收集方法的流程图,该函数调用收集方法是对上述函数调用收集方法的具体化。参考图2,该函数调用收集方法包括:
S210:定时对主线程进行堆栈回溯操作,得到主线程的堆栈信息。
示例性的,可通过与主线程独立的后台线程(采集线程)定对主线程进行堆栈回溯操作获取堆栈信息。例如在开启主线程后,开启用于采集堆栈信息和/或确定函数进出信息的采集线程(sample_thread),通过采集线程定时对主线程进行堆栈回溯操作获取主线程的堆栈信息。
在一个实施例中,可针对函数调用收集设备的性能设定获取主线程的堆栈信息的采样时间间隔,对性能较好的函数调用收集设备设置较小的采样时间间隔,以提升堆栈信息收集的准确度,对性能较差的函数调用收集设备设置较大的采样时间间隔,以减小堆栈信息收集所造成的性能损耗,有效平衡对堆栈信息收集的准确度和性能损耗。
在一个可能的实施例中,如图3提供的一种堆栈信息获取流程示意图所示,本方案提供的函数调用收集方法在定时对主线程进行堆栈回溯操作,得到主线程的堆栈信息时,包括:
S211:通过线程挂起函数定时将主线程挂起。
S212:通过第一栈回溯函数对主线程进行堆栈回溯操作,得到主线程的堆栈信息,第一栈回溯函数基于虚拟机的第二栈回溯函数进行创建。
示例性的,采集线程按照设定的采样时间间隔对主线程的堆栈信息进行采集,在每次采集主线程的堆栈信息时,调用线程挂起函数(例如线程挂起函数ThreadList::SuspendThreadByPeer)将主线程挂起,然后在主函数挂起期间采集主线程的堆栈信息,并在得到堆栈信息后通过线程恢复函数(例如线程恢复函数ThreadList::Resume)恢复主线程的运行。
其中,在采集主线程的堆栈信息时,可通过第一栈回溯函数(例如栈回溯函数MyStackVisitor)对主线程进行堆栈回溯操作得到主线程的堆栈信息。其中,在每次采集堆栈信息时,创建第一栈回溯函数,通过第一栈回溯函数对主线程进行堆栈回溯操作,可得到主线程的堆栈信息。其中,第一栈回溯函数基于虚拟机的第二栈回溯函数(例如栈回溯函数StackVisitor)进行创建。例如,将第一栈回溯函数的对象大小设置为大于等于函数调用收集设备的虚拟机中的第二栈回溯函数的对象大小,并对第一栈回溯函数定义和第二栈回溯函数的第二虚函数相同的第一虚函数。
需要进行解释的是,应用程序(例如基于安卓系统的应用程序)的运行可在函数调用收集设备的虚拟机中进行,例如在启动应用程序时,在函数调用收集设备的虚拟机中启动主线程,主线程通过第二栈回溯函数调用对应的调用函数。由于第二栈回溯函数StackVisitor是系统代码定义的一个类,第二栈回溯函数没有暴露给开发者,开发者不能直接继承第二栈回溯函数,本方案基于第二栈回溯函数定义一个类:MyStackVisitor,并将其作为第一栈回溯函数。第一栈回溯函数的对象大小大于等于第二栈回溯函数的对象大小,通过第一栈回溯函数调用第二栈回溯函数的构造函数,重写和第二栈回溯函数的第二虚函数StackVisitor::VisitFrame相同的第一虚函数MyStackVisitor::VisitFrame,可实现类似于继承第二栈回溯函数的效果,从而确定主线程的堆栈信息。
本方案通过将主线程挂起后再进行堆栈信息的获取,并在获取到堆栈信息后恢复主线程,减少在获取堆栈信息期间主线程的堆栈发生变动,导致堆栈信息收集错误的情况,保证正确收集堆栈信息,提高对异常分析的准确度。同时,通过基于虚拟机的第二栈回溯函数创建的第一栈回溯函数,实现类似于继承第二栈回溯函数的效果,可准确高效地获取主线程的堆栈信息。
在一个可能的实施例中,本方案提供的第一栈回溯函数在对主线程进行堆栈回溯操作,得到主线程的堆栈信息时,包括:通过函数栈遍历函数遍历主线程的堆栈中的每一个栈帧,并确定每一个栈帧对应的调用函数;基于每一个栈帧对应的调用函数确定主线程的堆栈信息。
示例性的,在新建第一栈回溯函数后,第一栈回溯函数调用函数栈遍历函数(例如函数栈遍历函数StackVisitor::WalkStack),通过函数栈遍历函数遍历主线程的堆栈中的每一个栈帧(主线程的堆栈中的每一个栈帧可表示每一个调用函数对应的指针),并确定每一个栈帧对应的调用函数。在确定每一个栈帧对应的调用函数后,可基于每一个栈帧对应的调用函数确定主线程的堆栈信息。
在一个实施例中,本方案提供的函数栈遍历函数每遍历一个栈帧,会调用第一虚函数MyStackVisitor::VisitFrame,第一虚函数MyStackVisitor::VisitFrame可通过调用函数获取函数StackVisitor::GetMethod获得栈帧对应的调用函数。
可选的,栈帧对应的调用函数可通过设定数据结构进行表示,并将每一个栈帧对应的调用函数形成的堆栈列表作为主线程的堆栈信息,例如以ArtMethod的数据结构表示栈帧对应的调用函数,最终得到的ArtMethod列表即为当前时刻收集到的主线程的堆栈信息。可选的,每一个栈帧对应的调用函数可基于调用函数对应的指针进行表示,例如ArtMethod对应的指针地址。
其中,获取主线程的堆栈信息可使用虚拟机(例如Android虚拟机)内部的接口,这些内部接口没有暴露给开发者使用,可通过dlsym函数(从指定的动态链接库中查找指定的符号,并返回该符号对应的地址)+plt hook函数(一种二进制技术,常用于修改或监视程序执行过程中的某些函数调用)的方式获取这些接口的指针。例如,通过dlsym函数获得线程挂起函数ThreadList::SuspendThreadByPeer和线程恢复函数ThreadList::Resume的指针,线程挂起函数和线程恢复函数是ThreadList函数的成员函数,调用它们还需要获得ThreadList函数的指针。在虚拟机中,ThreadList函数全局唯一,可以先通过dlsym函数获得JVM_SetNativeThreadName函数的函数指针,当调用它设置非当前线程的名字时,会调用线程挂起函数ThreadList::SuspendThreadByPeer和线程恢复函数ThreadList::Resume来挂起和恢复线程,这样可以通过plt hook ThreadList::Resume函数来代理其调用,然后在代理函数中获得ThreadList函数的指针。进一步的,可通过dlsym函数获得StackVisitor构造函数、StackVisitor::GetMethod函数、ArtMethod::PrettyMethod和函数对应的指针,可基于以上获取的函数指针使用虚拟机内部的接口采集主线程的堆栈信息。
本方案通过函数栈遍历函数遍历主线程的堆栈中的每一个栈帧确定多个调用函数,并根据多个调用函数确定主线程的堆栈信息,准确继承第二栈回溯函数的函数调用轨迹,可准确高效地获取主线程的堆栈信息。
S220:根据堆栈信息中记录的调用函数,确定进入堆栈的调用函数和退出堆栈的调用函数,并确定各个调用函数进入堆栈的进入时间和退出堆栈的退出时间。
S230:将各个调用函数的进入时间和退出时间记录到缓冲区中。
在一个实施例中,本方案提供的函数进出信息包括调用函数、调用函数对应的进出状态(进入堆栈或退出堆栈)以及调用函数进入和/或退出堆栈的进入时间和/或退出时间。示例性的,在每次获取主线程的堆栈信息后,确定获取堆栈信息的时间,确定堆栈信息中记录的每个调用函数,并确定进入堆栈的调用函数以及退出堆栈的调用函数,并根据获取堆栈信息的时间分别确定每个进入堆栈的调用函数的进入时间(即进入堆栈的进入时间),和每个退出堆栈的调用函数的退出时间(即退出堆栈的退出时间)。
其中,每次获取的堆栈信息中可以包括进入堆栈的调用函数和/或逗留在堆栈(即在此前进入堆栈,且未退出堆栈的调用函数)的调用函数,其中退出堆栈的调用函数可根据前后相邻的堆栈信息中记录的调用函数进行确定,例如某个调用函数存在于上一个堆栈信息,而未存在于当前的堆栈信息时,可确定该调用函数退出了堆栈。堆栈信息中记录的可以是全部是进入堆栈的调用函数,例如在首次获取堆栈信息,或者上一个堆栈中的函数都退出了堆栈时,堆栈信息中所记录的调用函数均为进入堆栈的调用函数。
进一步的,将每个进入堆栈的调用函数和对应的进入时间,和/或退出堆栈的调用函数和对应的退出时间记录到缓冲区中。
本方案通过在缓冲区中记录进入堆栈和退出堆栈的调用函数,以及分别对应的进入时间和退出时间,准确记录各个调用函数在堆栈中的进入情况以及执行任务的耗时,有效提高对异常事件的定位准确度。
在一个可能的实施例中,本方案提供的函数调用收集方法在根据堆栈信息中记录的调用函数,确定进入堆栈的调用函数和退出堆栈的调用函数,并确定各个调用函数进入堆栈的进入时间和退出堆栈的退出时间时,包括:
S221:确定当前的堆栈信息以及前一个堆栈信息中记录的调用函数。
S222:将未记录在当前的堆栈信息且记录在前一个堆栈信息的调用函数确定为退出堆栈的调用函数,并将当前时间确定为调用函数退出堆栈的退出时间。
S223:将记录在当前的堆栈信息且未记录在前一个堆栈信息的调用函数确定为进入堆栈的调用函数,并将当前时间确定为调用函数进入堆栈的进入时间。
示例性的,在获取当前的堆栈信息后,确定获取当前的堆栈信息对应的时间,并确定当前的堆栈信息中记录的每一个调用函数,以及前一个堆栈信息中记录的每一个调用函数。对比当前的堆栈信息以及前一个堆栈信息中记录的调用函数,确定记录在前一个堆栈信息而未记录在当前的堆栈信息的调用函数,以及记录在当前的堆栈信息而未记录在前一个堆栈信息的调用函数。
对于未记录在当前的堆栈信息且记录在前一个堆栈信息的调用函数,将这些调用函数确定为退出堆栈的调用函数,并将当前时间确定为这些调用函数退出堆栈的退出时间。
对于记录在当前的堆栈信息且未记录在前一个堆栈信息的调用函数,将这些调用函数确定为进入堆栈的调用函数,并将当前时间确定为这些调用函数进入堆栈的进入时间。可以理解的是,对于首次获取的堆栈信息,其内记录的所有调用函数均为进入堆栈的调用函数,对应的进入时间为获取该堆栈信息的时间。
如图4提供的一种函数进出信息记录示意图所示,假设在t1时刻获取的堆栈信息S1中记录有调用函数A、B、C、D、E,其中调用函数A为栈底,调用函数E为栈顶。将调用函数A、B、C、D、E标记为进入堆栈的调用函数,并且进入时间为t1,将进入堆栈的调用函数A、B、C、D、E以及进入时间t1记录到缓冲区(环形缓冲区)中。
假设在t2时刻获取的堆栈信息S2中记录有调用函数A、B、F、G、H,其中调用函数A为栈底,调用函数H为栈顶。通过对比堆栈信息S2和堆栈信息S1可知,其中调用函数E、D、C退出堆栈,调用函数F、G、H进入堆栈,此时的退出时间和进入时间均为t2,将退出堆栈的调用函数E、D、C和退出时间t2,以及进入堆栈的调用函数F、G、H和进入时间t2记录到缓冲区中。
假设在t3时刻获取的堆栈信息S3中记录有调用函数I、J、K、L、M,其中调用函数I为栈底,调用函数M为栈顶。通过对比堆栈信息S3和堆栈信息S2可知,其中调用函数A、B、F、G、H均退出堆栈,调用函数I、J、K、L、M进入堆栈,此时的退出时间和进入时间均为t2,将退出堆栈的调用函数A、B、F、G、H和退出时间t3,以及进入堆栈的调用函数I、J、K、L、M和进入时间t3记录到缓冲区中。此时,缓冲区中记录的函数进出信息如图中缓冲区对应表格所示。需要进行解释的是,基于调用函数的进入时间和退出时间确定调用函数的耗时会有一定的误差,该误差与采样间隔时间相关,假定采样间隔为T,那么调用函数耗时的平均误差为T/2。只要控制好采样间隔时间,即可将误差控制在可接受范围内,在实际应用中,更需要关注的是耗时较长的调用函数,这些调用函数的耗时误差相比实际耗时较小,对于不需要关注的耗时较短的调用函数可过滤掉,不需要保存到缓冲区中,减小了函数进出信息对内存的占用。
本方案通过根据前后获取到的堆栈信息中记录的调用函数准确确定进出堆栈的调用函数,并确定对应的进入时间和退出时间,准确记录各个调用函数在堆栈中的进入情况以及执行任务的耗时,有效提高对异常事件的定位准确度。
S240:在检测到异常事件的情况下,基于缓冲区中记录的函数进出信息生成函数调用记录信息。
在一个实施例中,本方案提供的函数调用收集方法在在检测到异常事件的情况下,基于缓冲区中记录的函数进出信息生成函数调用记录信息之后,还包括:将函数调用记录上传至后台服务器,通过后台服务器对函数调用记录进行可视化处理。
示例性的,在响应异常事件生成函数调用记录信息后,将函数调用记录信息上传到预先设定的后台服务器中,由后台服务器对接收到的函数调用记录信息进行可视化处理。
在一个实施例中,工作人员可基于后台服务器对函数调用记录信息的可视化处理结果对异常事件进行异常分析定位。例如,后台服务器根据接收到的函数调用记录信息确定每个调用函数对应的耗时(可根据调用函数的退出时间与进入时间的差确定耗时),并对每个调用函数的耗时进行可视化处理,工作人员可根据每个调用函数对应的耗时确定引起异常的调用函数,实现对异常事件进行异常分析定位。
本方案通过上传函数调用记录信息并通过后台服务器对函数调用记录信息进行可视化处理,方便工作人员基于可视化的函数调用记录信息对异常事件进行异常分析定位,提高对异常事件进行异常分析定位准确度和效率。
在一个可能的实施例中,本方案提供的函数调用收集方法在基于缓冲区中记录的函数进出信息生成函数调用记录信息时,包括:获取缓冲区中记录的调用函数的函数签名,并基于缓冲区中记录的函数进出信息以及函数签名生成函数调用记录信息。对应的,本方案提供的函数调用收集方法在后台服务器对函数调用记录进行可视化处理时,包括:对函数调用记录信息中记录的调用函数对应的函数签名进行反混淆处理;基于设定可视化工具支持的数据格式,将函数调用记录信息中记录的调用函数对应的函数进出信息转换为可视化数据格式;基于设定可视化工具对函数进出信息以及函数签名进行可视化处理。
示例性的,在检测到异常事件时,获取缓冲区中记录的每个调用函数的函数签名。可选的,调用函数的函数签名可通过对调用函数进行符号化处理获取。例如,通过调用签名获取函数(例如签名获取函数ArtMethod::PrettyMethod)获取缓冲区中各个调用函数的函数签名。
进一步的,根据缓冲区中记录的函数进出信息(包括每个调用函数对应的进入时间以及退出时间)以及每个调用函数的函数签名生成函数调用记录信息。在生成函数调用记录信息后,可将函数调用记录信息打包压缩后上传到后台服务器中。
在一个实施例中,后台服务器接收到上传的函数调用记录信息后,对函数调用记录信息中记录的调用函数对应的函数签名进行反混淆处理,得到各个调用函数对应的函数名。例如,在读取函数调用记录信息后,利用预先配置的匹配文件(mapping文件)对各个调用函数对应的函数签名进行反混淆处理,得到函数签名对应的名称。其中,匹配文件中记录有各个调用函数的函数签名和名称之间的对应关系。其中,在工作人员编写代码阶段,是基于调用函数的名称进行编程的,在变成完成后会将代码进行混淆处理,调用函数的名称将被混淆为函数签名,并且在混淆处理过程中生成对应的匹配文件,并且在应用程序运行过程中,是通过调用函数对应的指针进行调用的,本方案在采集堆栈信息时先确定调用函数对应的指针(记录到缓冲区的为调用函数对应的指针),在检测到异常情况时将指针符号化得到调用函数的函数签名,并在可视化处理时将函数签名反混淆为调用函数的名称,方便工作人员了解具体的调用函数对应的耗时,提高异常分析定位效率。
进一步的,根据设定可视化工具支持的数据格式将函数调用记录信息中记录的调用函数对应的函数进出信息转换为可视化数据格式,并利用设定可视化工具对格式转换后的函数进出信息以及函数签名进行可视化处理。例如,可假设利用设定可视化工具trace_viewer(一种用于分析和可视化跟踪数据的工具)对函数进出信息进行可视化处理,trace_viewer支持的数据格式为trace event格式,则将函数进出信息的数据格式转换为traceevent格式。
本方案通过对函数签名进行反混淆处理以及对函数进出信息进行格式转换处理,满足设定可视化工具对数据进行可视化处理的数据格式要求,并且可根据函数签名对应的名称准确确定各个调用函数的耗时,提高对数据的可视化效果,并且通过设定可视化工具对函数进出信息和函数签名进行可视化处理,方便对各个调用函数的耗时的查看和搜索,提高对异常事件进行异常分析定位准确度和效率。
上述,通过定时对主线程进行堆栈回溯操作获取主线程的堆栈信息,根据堆栈信息中记录的调用函数确定函数进出信息,并将函数进出信息记录到缓冲区中,并且在检测到异常事件时,根据缓冲区中记录的函数进出信息生成函数调用记录信息,函数调用记录信息可反应在发生异常事件前的函数调用轨迹,准确收集反应异常事件的函数调用轨迹,提高对异常事件的定位准确度以及效率。同时,在缓冲区中记录进入堆栈和退出堆栈的调用函数,以及分别对应的进入时间和退出时间,准确记录各个调用函数在堆栈中的进入情况以及执行任务的耗时,有效提高对异常事件的定位准确度。还通过后台服务器对函数调用记录信息进行可视化处理,方便工作人员基于可视化的函数调用记录信息对异常事件进行异常分析定位,提高对异常事件进行异常分析定位准确度和效率。
图5是本申请实施例提供的一种函数调用收集装置的结构示意图。参考图5,该函数调用收集装置包括堆栈获取模块51、信息记录模块52和函数记录模块53。
其中,堆栈获取模块51,配置为定时对主线程进行堆栈回溯操作,得到主线程的堆栈信息;信息记录模块52,配置为根据堆栈信息中记录的调用函数确定函数进出信息,将函数进出信息记录到缓冲区中;函数记录模块53,配置为在检测到异常事件的情况下,基于缓冲区中记录的函数进出信息生成函数调用记录信息。
上述,通过定时对主线程进行堆栈回溯操作获取主线程的堆栈信息,根据堆栈信息中记录的调用函数确定函数进出信息,并将函数进出信息记录到缓冲区中,并且在检测到异常事件时,根据缓冲区中记录的函数进出信息生成函数调用记录信息,函数调用记录信息可反应在发生异常事件前的函数调用轨迹,准确收集反应异常事件的函数调用轨迹,提高对异常事件的定位准确度以及效率。
在一个可能的实施例中,堆栈获取模块51配置为:
通过线程挂起函数定时将主线程挂起;
通过第一栈回溯函数对主线程进行堆栈回溯操作,得到主线程的堆栈信息,第一栈回溯函数基于虚拟机的第二栈回溯函数进行创建;
通过线程恢复函数恢复主线程。
在一个可能的实施例中,堆栈获取模块51在第一栈回溯函数对主线程进行堆栈回溯操作,得到主线程的堆栈信息时,配置为:
通过函数栈遍历函数遍历主线程的堆栈中的每一个栈帧,并确定每一个栈帧对应的调用函数;
基于每一个栈帧对应的调用函数确定主线程的堆栈信息。
在一个可能的实施例中,信息记录模块52配置为:
根据堆栈信息中记录的调用函数,确定进入堆栈的调用函数和退出堆栈的调用函数,并确定各个调用函数进入堆栈的进入时间和退出堆栈的退出时间;
将各个调用函数的进入时间和退出时间记录到缓冲区中。
在一个可能的实施例中,信息记录模块52在根据堆栈信息中记录的调用函数,确定进入堆栈的调用函数和退出堆栈的调用函数,并确定各个调用函数进入堆栈的进入时间和退出堆栈的退出时间时,配置为:
确定当前的堆栈信息以及前一个堆栈信息中记录的调用函数;
将未记录在当前的堆栈信息且记录在前一个堆栈信息的调用函数确定为退出堆栈的调用函数,并将当前时间确定为调用函数退出堆栈的退出时间;
将记录在当前的堆栈信息且未记录在前一个堆栈信息的调用函数确定为进入堆栈的调用函数,并将当前时间确定为调用函数进入堆栈的进入时间。
在一个可能的实施例中,函数调用收集装置还包括数据上传模块,数据上传模块配置为将函数调用记录上传至后台服务器,通过后台服务器对函数调用记录进行可视化处理。
在一个可能的实施例中,函数记录模块53在基于缓冲区中记录的函数进出信息生成函数调用记录信息时,配置为:获取缓冲区中记录的调用函数的函数签名,并基于缓冲区中记录的函数进出信息以及函数签名生成函数调用记录信息;
后台服务器对函数调用记录进行可视化处理时,配置为:对函数调用记录信息中记录的调用函数对应的函数签名进行反混淆处理;基于设定可视化工具支持的数据格式,将函数调用记录信息中记录的调用函数对应的函数进出信息转换为可视化数据格式;基于设定可视化工具对函数进出信息以及函数签名进行可视化处理。
值得注意的是,上述函数调用收集装置的实施例中,所包括的各个单元和模块只是按照功能逻辑进行划分的,但并不局限于上述的划分,只要能够实现相应的功能即可;另外,各功能单元的具体名称也只是为了便于相互区分,并不用于限制本发明实施例的保护范围。
本申请实施例还提供了一种函数调用收集设备,该函数调用收集设备可集成本申请实施例提供的函数调用收集装置。图6是本申请实施例提供的一种函数调用收集设备的结构示意图。参考图6,该函数调用收集设备包括:输入装置63、输出装置64、存储器62以及一个或多个处理器61;存储器62,用于存储一个或多个程序;当一个或多个程序被一个或多个处理器61执行,使得一个或多个处理器61实现如上述实施例提供的函数调用收集方法。上述提供的函数调用收集装置、设备和计算机可用于执行上述任意实施例提供的函数调用收集方法,具备相应的功能和有益效果。
本申请实施例还提供一种存储计算机可执行指令的非易失性存储介质,计算机可执行指令在由计算机处理器执行时用于执行如上述实施例提供的函数调用收集方法。当然,本申请实施例所提供的一种存储计算机可执行指令的非易失性存储介质,其计算机可执行指令不限于如上提供的函数调用收集方法,还可以执行本申请任意实施例所提供的函数调用收集方法中的相关操作。上述实施例中提供的函数调用收集装置、设备及存储介质可执行本申请任意实施例所提供的函数调用收集方法,未在上述实施例中详尽描述的技术细节,可参见本申请任意实施例所提供的函数调用收集方法。
在上述实施例的基础上,本申请实施例还提供一种计算机程序产品,本申请的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的全部或部分可以以软件产品的形式体现出来,该计算机程序产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备、移动终端或其中的处理器执行本申请各个实施例所提供的函数调用收集方法的全部或部分步骤。

Claims (11)

1.一种函数调用收集方法,其特征在于,包括:
定时对主线程进行堆栈回溯操作,得到所述主线程的堆栈信息;
根据所述堆栈信息中记录的调用函数确定函数进出信息,将所述函数进出信息记录到缓冲区中;
在检测到异常事件的情况下,基于所述缓冲区中记录的所述函数进出信息生成函数调用记录信息。
2.根据权利要求1所述的函数调用收集方法,其特征在于,所述定时对主线程进行堆栈回溯操作,得到所述主线程的堆栈信息,包括:
通过线程挂起函数定时将主线程挂起;
通过第一栈回溯函数对所述主线程进行堆栈回溯操作,得到所述主线程的堆栈信息,所述第一栈回溯函数基于虚拟机的第二栈回溯函数进行创建;
通过线程恢复函数恢复所述主线程。
3.根据权利要求2所述的函数调用收集方法,其特征在于,所述第一栈回溯函数对所述主线程进行堆栈回溯操作,得到所述主线程的堆栈信息,包括:
通过函数栈遍历函数遍历所述主线程的堆栈中的每一个栈帧,并确定每一个所述栈帧对应的调用函数;
基于每一个所述栈帧对应的所述调用函数确定所述主线程的堆栈信息。
4.根据权利要求1所述的函数调用收集方法,其特征在于,所述根据所述堆栈信息中记录的调用函数确定函数进出信息,将所述函数进出信息记录到缓冲区中,包括:
根据所述堆栈信息中记录的调用函数,确定进入堆栈的调用函数和退出堆栈的调用函数,并确定各个所述调用函数进入堆栈的进入时间和退出堆栈的退出时间;
将各个所述调用函数的进入时间和退出时间记录到缓冲区中。
5.根据权利要求4所述的函数调用收集方法,其特征在于,所述根据所述堆栈信息中记录的调用函数,确定进入堆栈的调用函数和退出堆栈的调用函数,并确定各个所述调用函数进入堆栈的进入时间和退出堆栈的退出时间,包括:
确定当前的堆栈信息以及前一个堆栈信息中记录的调用函数;
将未记录在当前的堆栈信息且记录在前一个堆栈信息的调用函数确定为退出堆栈的调用函数,并将当前时间确定为所述调用函数退出堆栈的退出时间;
将记录在当前的堆栈信息且未记录在前一个堆栈信息的调用函数确定为进入堆栈的调用函数,并将当前时间确定为所述调用函数进入堆栈的进入时间。
6.根据权利要求1所述的函数调用收集方法,其特征在于,所述在检测到异常事件的情况下,基于所述缓冲区中记录的所述函数进出信息生成函数调用记录信息之后,还包括:
将所述函数调用记录上传至后台服务器,通过所述后台服务器对所述函数调用记录进行可视化处理。
7.根据权利要求6所述的函数调用收集方法,其特征在于,所述基于所述缓冲区中记录的所述函数进出信息生成函数调用记录信息,包括:
获取所述缓冲区中记录的调用函数的函数签名,并基于所述缓冲区中记录的所述函数进出信息以及所述函数签名生成函数调用记录信息;
所述后台服务器对所述函数调用记录进行可视化处理,包括:
对所述函数调用记录信息中记录的调用函数对应的函数签名进行反混淆处理;
基于设定可视化工具支持的数据格式,将所述函数调用记录信息中记录的调用函数对应的函数进出信息转换为可视化数据格式;
基于所述设定可视化工具对所述函数进出信息以及所述函数签名进行可视化处理。
8.一种函数调用收集装置,其特征在于,包括堆栈获取模块、信息记录模块和函数记录模块,其中:
所述堆栈获取模块,配置为定时对主线程进行堆栈回溯操作,得到所述主线程的堆栈信息;
所述信息记录模块,配置为根据所述堆栈信息中记录的调用函数确定函数进出信息,将所述函数进出信息记录到缓冲区中;
所述函数记录模块,配置为在检测到异常事件的情况下,基于所述缓冲区中记录的所述函数进出信息生成函数调用记录信息。
9.一种函数调用收集设备,其特征在于,包括:存储器以及一个或多个处理器;
所述存储器,用于存储一个或多个程序;
当所述一个或多个程序被所述一个或多个处理器执行,使得所述一个或多个处理器实现如权利要求1-7任一项所述的函数调用收集方法。
10.一种存储计算机可执行指令的非易失性存储介质,其特征在于,所述计算机可执行指令在由计算机处理器执行时用于执行如权利要求1-7任一项所述的函数调用收集方法。
11.一种计算机程序产品,包括计算机程序,其特征在于,所述计算机程序被处理器执行时实现权利要求1-7任一项所述的函数调用收集方法。
CN202310574189.4A 2023-05-19 2023-05-19 一种函数调用收集方法、装置、设备、存储介质及产品 Pending CN116594750A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202310574189.4A CN116594750A (zh) 2023-05-19 2023-05-19 一种函数调用收集方法、装置、设备、存储介质及产品

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202310574189.4A CN116594750A (zh) 2023-05-19 2023-05-19 一种函数调用收集方法、装置、设备、存储介质及产品

Publications (1)

Publication Number Publication Date
CN116594750A true CN116594750A (zh) 2023-08-15

Family

ID=87589436

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202310574189.4A Pending CN116594750A (zh) 2023-05-19 2023-05-19 一种函数调用收集方法、装置、设备、存储介质及产品

Country Status (1)

Country Link
CN (1) CN116594750A (zh)

Similar Documents

Publication Publication Date Title
CN107111544B (zh) 生产诊断中的历史控制流可视化
US5748878A (en) Method and apparatus for analyzing software executed in embedded systems
JP5705084B2 (ja) 2パス自動アプリケーション計測
US7770155B2 (en) Debugger apparatus and method for indicating time-correlated position of threads in a multi-threaded computer program
US8141053B2 (en) Call stack sampling using a virtual machine
US9111038B2 (en) Integrated debugger and code coverage tool
US8418149B2 (en) Differential comparison system and method
US10761963B2 (en) Object monitoring in code debugging
US9146831B2 (en) Sampling based runtime optimizer for efficient debugging of applications
US20150006961A1 (en) Capturing trace information using annotated trace output
KR19990077479A (ko) 데이터처리시스템및애플리케이션의구조화된프로파일링방법및장치
US20080276129A1 (en) Software tracing
US9361205B2 (en) Code coverage framework
CN109542341B (zh) 一种读写io监测方法、装置、终端及计算机可读存储介质
US8762783B2 (en) Error identification
EP3921734A1 (en) Using historic execution data to visualize tracepoints
CN116594750A (zh) 一种函数调用收集方法、装置、设备、存储介质及产品
CN115481025A (zh) 自动化测试的脚本录制方法、装置、计算机设备及介质
CN115705250A (zh) 监测堆栈使用量以优化程序
US9244814B1 (en) Enriched log viewer
JP3459898B2 (ja) 組み込みシステムの障害情報トレーサ装置
US11816092B2 (en) System and method for automatic application log messages grouping using logging framework code instrumentation
Shimari et al. Evaluating the effectiveness of size-limited execution trace with near-omniscient debugging
CN113961449A (zh) 一种计算机软件技术开发调试系统
CN113704088A (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