CN111045658B - 访问类的静态成员的方法和装置 - Google Patents

访问类的静态成员的方法和装置 Download PDF

Info

Publication number
CN111045658B
CN111045658B CN201811194933.3A CN201811194933A CN111045658B CN 111045658 B CN111045658 B CN 111045658B CN 201811194933 A CN201811194933 A CN 201811194933A CN 111045658 B CN111045658 B CN 111045658B
Authority
CN
China
Prior art keywords
class
address
variable
metadata
static
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
Application number
CN201811194933.3A
Other languages
English (en)
Other versions
CN111045658A (zh
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.)
Huawei Technologies Co Ltd
Original Assignee
Huawei Technologies 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 Huawei Technologies Co Ltd filed Critical Huawei Technologies Co Ltd
Priority to CN201811194933.3A priority Critical patent/CN111045658B/zh
Publication of CN111045658A publication Critical patent/CN111045658A/zh
Application granted granted Critical
Publication of CN111045658B publication Critical patent/CN111045658B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/30Creation or generation of source code
    • G06F8/31Programming languages or programming paradigms
    • G06F8/315Object-oriented languages
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation

Abstract

本申请提供访问类的静态成员的方法和装置。该方法和装置中,获取类的元数据,元数据中包括第一变量,在类初始化之前,第一变量中记录不可访问的第一地址,在类初始化之后,第一变量中记录类的静态域的第二地址;根据第一变量中记录的第一地址或第二地址,确定该类的静态域中的待访问成员的目标地址;最后访问该目标地址,以访问该待访问成员。其中,若该类已经初始化过,则可以成功访问其静态成员,而不需要进行初始化状态检测或判断等流程;若该类还未初始化,因为第一变量中的第一地址不可访问,所以可以保证不会访问错的静态成员值。本申请的技术方案可以使得运行时系统使用较少的时间开销和空间开销来访问类的静态成员和提高访问的正确性。

Description

访问类的静态成员的方法和装置
技术领域
本申请涉及程序设计语言领域,并且更具体地,涉及访问类的静态成员的方法和装置。
背景技术
类在访问前必须初始化。类的初始化就是执行类构造器。类的初始化可以实现对类中的静态变量的赋值,并执行类中的静态代码块中的语句。
在访问类时,如果类没有被初始化,则需要执行类的初始化操作;如果类已经被初始化,则可以直接访问类的静态成员,例如类的静态方法或静态变量。访问类也可以理解为访问类的静态成员。
目前,一种访问类的方法包括:给类设置一个标识类的初始化状态的标记,在访问类之前,获取该标记的值,将该标记的值与未初始化状态标记的值进行比较,然后根据比较结果判断类是否已经初始化。其中,若该标记的值与未初始化状态标记的值不相同,说明该类可能已经初始化,可以访问该类的静态成员。
这种访问类的方法使得类的运行时系统的时间开销和空间开间都比较大。那如何使用运行时系统中较少的时间开销和空间开销来访问类是一种亟待解决的技术问题。
发明内容
本申请提供一种访问类的静态成员的方法和装置,可以使用运行时系统中较少的时间开销和空间开销来访问类的静态成员,以及提高类的访问正确性。
第一方面,本申请提供了一种访问类的静态成员的方法,该包括:获取类的元数据,所述元数据中包括第一变量,在所述类初始化之前,所述第一变量中记录不可访问的第一地址,在所述类初始化之后,所述第一变量中记录所述类的静态域的第二地址;根据第一变量中记录的第一地址或第二地址,确定该类的静态域中的待访问成员的目标地址;访问该目标地址,以访问该待访问成员。
该方法中,直接根据类的元数据中的第一变量中记录的地址来确定类的静态域中的待访问成员的目标地址,然后访问该目标地址以访问该待访问成员。
本申请的方法中,在类已初始化的情况下,不需要比较指令和进行比较操作,就可以直接访问已经初始化过的类的静态成员,从而可以减少类的运行时系统中访问类的静态成员所需的时间开销和空间开销。
此外,该类还未初始化时,因为第一变量中的第一地址不可访问,所以可以保证不会访问错的静态成员值,从而可以提高访问的正确性。
结合第一方面,在第一种可能的实现方式中,该方法还包括:在SIGSEGV异常信号的触发下执行异常处理,其中,该异常处理包括:调用该类的构造方法对该类进行初始化,并将该类的静态域的第二地址记录到该类的元数据的第一变量中。
该实现方式中,通过内存访问异常产生SIGSEGV异常信号,并在SIGSEGV异常信号的触发下进行类的初始化,以便于可以访问该类的静态成员。其中,不需要进行比较操作就可以触发类的初始化,即不需要比较指令就可以在类处于非初始化状态时对类进行初始化。
由于产生内存访问异常,内存访问异常触发生成SIGSEGV异常信号和通过SIGSEGV异常信号触发类的初始化是由为类的运行时系统提供支持的操作系统执行的,以及SIGSEGV异常信号触发类的初始化后,将类的静态域的第二地址直接写入第一变量中而不需要额外的存储空间来完成类的初始化,因此,该实现方式可以使用类的运行时系统中的较少的空间开销和时间开销来访问类的静态成员。
结合第一种可能的实现方式,在第二种可能的实现方式中,在调用类的构造方法对类进行初始化之前,所述异常处理还包括:确定发生内存访问异常的PC属于访问类的运行时系统。
该实现方式中,在确定发生内存访问异常的PC属于访问该类的运行时系统的情况下,才对该类进行初始化,可以避免内存访问异常为其他运行时系统引发时执行类的初始化,从而避免出现运行错误。
结合第一种可能的实现方式或第二种可能的实现方式,在第三种可能的实现方式中,在调用类的构造方法对类进行初始化之前,第一变量中记录的第一地址为保护页中的地址;其中,在调用类的构造方法对类进行初始化之前,所述异常处理还包括:确定发生内存访问异常的内存地址位于第一变量中记录的第一地址所属的保护页的范围内。
该实现方式中,在确定发生内存访问异常的内存地址属于所属保护页的范围内的情况下,才对该类进行初始化,有助于保证该内存访问异常是由访问待访问成员的目标地址所引起的,即在进一步确定该类没有进行过初始化的情况下才对该类进行初始化,从而可以节省时间开销。
结合第一方面或第一方面中任意一种可能的实现方式,在第四种可能的实现方式中,在获取类的元数据之前,所述方法还包括:生成类的元数据,该元数据中包括第一变量,第一变量中记录的第一地址为保护页中的地址。
也就是说,在生成类的元数据时,在元数据中定义一个变量,该变量称为第一变量,并在该第一变量中记录属于保护页中的第一地址。这样,第一次访问该类时,访问根据第一变量中的第一地址生成的待访问成员的目标地址时,就会发生内存访问异常,而不会将错误的值当做静态成员的值。
此外,这种实现方式为类的初始化提供了触发条件。与判断类初始化状态以触发类的初始化相比,可以节省时间开销和空间开销。
第二方面,提供了一种访问类的静态成员的装置,该装置包括用于执行第一方面或第一方面的任意一种可能的实现方式中的方法的模块。
第三方面,提供了一种访问类的静态成员的装置,该装置包括处理器,处理器用于执行程序,当处理器执行程序时,实现第一方面或第一方面的任意一种可能的实现方式中的方法。
可选地,该装置还可以包括存储器。存储器用于存储处理器执行的程序。该装置的一种示例为计算设备,例如计算机。
第四方面,提供一种计算机可读存储介质,该计算机可读存储介质存储用于计算装置执行的程序代码,该程序代码包括用于实现第一方面或第一方面的任意一种可能的实现方式中的方法的指令。
第五方面,提供一种芯片,该芯片包括处理器和通信接口,该通信接口用于与外部器件进行通信,该处理器用于实现第一方面或第一方面的任意一种可能的实现方式中的方法。
可选地,该芯片还可以包括存储器,该存储器中存储有指令,处理器用于执行存储器中存储的指令,当该指令被执行时,处理器用于实现第一方面或第一方面的任意一种可能的实现方式中的方法。
可选地,该芯片可以集成在计算装置或计算设备上。
第六方面,本申请实施例提供了一种包含指令的计算机程序产品,当其在计算装置或计算设备上运行时,使得计算装置或计算设备执行第一方面所述的方法。
附图说明
图1是本申请一个实施例的源代码的示意性处理图;
图2是本申请一个实施例的访问类的静态成员的方法的示意性流程图;
图3是本申请另一个实施例的访问类的静态成员的方法的示意性流程图;
图4是本申请一个实施例的访问类的静态成员的装置的示意性流程图;
图5是本申请一个实施例的访问类的静态成员的装置的示意性流程图。
具体实施方式
下面将结合附图,对本申请中的技术方案进行描述。
为了更好地理解本申请的技术方案,下面先对本申请中出现的一些术语进行解释。
运行时系统:又称运行环境,是一种把编译的运行码在目标机器上运行的环境。运行时系统是多核计算机系统软件栈的基础部分,是确保计算机应用安全高效运转的关键环节。运行时系统向下封装操作系统的资源接口,向上提供编程框架的运行时支持,包括优化调度、内存管理、进程管理、错误处理等。
例如,Java代码运行时,需要调用本地的资源。但是Java代码不能直接调用本地资源,而是需要借助Java虚拟机等来实现调用。调用其他资源使Java系统能够正常运行所借用的所有软硬件,都叫运行时系统。
Java系统的运行时系统也可以称为Java运行环境(java runtime environment,JRE)。
汇编指令:是汇编语言中使用的一些操作符和助记符,还包括一些伪指令,用于告诉汇编程序如何进行汇编的指令,它既不控制机器的操作也不被汇编成机器代码,只能为汇编程序所识别并指导汇编如何进行。汇编指令在存储器和寄存器、寄存器和输入输出端口之间传送数据。
类的元数据(metadata):又称中介数据、中继数据,为描述数据的数据(dataabout data),主要是描述数据属性(property)的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。
类的静态域:属于类,而不属于任何独立的对象。类的静态域可以直接用类名来调用,而不用创建对象并用对象来调用。通常情况下,一个类中仅有一个静态域。例如,Java中被static修饰的域被称作静态域。类的静态域用于存储类的静态成员。
类的初始化:简称类初始化(class initialization),是指执行类的构造器的过程。类的初始化实现对类中静态变量的赋值,以及执行类中的静态代码块中的语句。
SIGSEGV异常信号:当一个进程执行了一个无效的内存引用,或发生段错误时操作系统发送给该进程的信号。操作系统可以使用信号栈向一个处于自然状态的应用程序通告错误,由此,开发者可以使用该异常信号来调试程序或处理错误。
保护页:为操作系统中被设为读写保护的物理页。物理页设置为读写保护后,该页将没有访问权限。如果程序尝试在没有访问权限的内存上操作,将触发SIGSEGV信号。
源代码:可以简称为源码或源文件。计算机里面运行的所有东西都是用程序编出来的,而编写程序要用到计算机语言,用计算机语言直接编出来的程序就叫源码。例如,用C++语言编写的源码一种为.cpp文件,用Java语言编写的源码为.java。
源代码不能直接运行,必须编译后才能运行。源码经过编译和链接处理后就可以直接在操作系统下运行了。
图1是本申请一个实施例的源代码的示意性处理图。如图1所示,Java源代码经过Figo编译器编译后,可以得到可执行文件。该可执行文件被加载在Java运行时系统中。
应理解,图1中所示的Java源代码、Figo编译器、Java运行时系统、windows操作系统和windows程序均为示例。
图2是本申请实施例的访问类的静态成员的方法的示意性流程图。例如,该方法可以由图1中所示的Java运行时系统来执行。
应理解,图2示出了该方法的步骤或操作,但这些步骤或操作仅是示例,本申请实施例还可以执行其他操作或者图2中的各个操作的变形。
S220,获取类的元数据,该元数据中包括第一变量,在该类初始化之前,该第一变量中记录不可访问的第一地址,在该类初始化之后,该第一变量中记录该类的静态域的第二地址。
应理解,本申请实施例中的“第一”和“第二”只是为了更好地区分不可访问的地址和类的静态域的地址,不应对本申请实施例中的地址构成限制。
获取类的元数据可以理解为获取类的元数据的地址,或者说起始地址。
获取的类的元数据中可以包括用于记录该类的静态域的地址的变量。该变量可以称为第一变量。
如果是第一次获取该类的元数据,则该类的元数据中的第一变量中记录的第一地址是不可访问的地址。例如,第一变量中记录的可以是保护页中的第一地址,或者可以是任意不可访问或不可读写的内存的第一地址。
如果是非首次获取该类的元数据,例如,是在该类进行过初始化之后才获取的元数据,则该第一变量中记录的可以是该类的静态域的第二地址。
获取第一元数据后,可以获取该类的元数据中的第一变量。
例如,在获取到该类的元数据的地址后,可以根据该类的元数据的地址和第一变量的地址相对于该元数据的地址的位置偏移量,确定第一变量的地址。
例如,将类的元数据的地址与第一变量的位置偏移量相加,从而得到第一变量的地址。
然后根据第一变量的地址获取第一变量,即从所确定的第一变量的地址处读取或者访问第一变量。
S230,根据所第一变量中记录的第一地址或第二地址,确定该类的静态域中的待访问成员的目标地址。
在S220中获取到第一变量之后,可以根据第一变量中记录的第一地址或第二地址,以及该类的静态域中的待访问成员的地址相对于该静态域的地址的位置偏移量,即可得到该待访问成员的目标地址。
例如,将第一变量中记录的地址与待访问成员的位置偏移量相加,从而可以得到待访问成员的目标地址。
S240,访问该待访问成员的目标地址,以访问该待访问成员。
访问该待访问成员的目标地址,即从目标地址中读取该待访问成员。
其中,若S220中是非首次获取类的元数据,例如,是在对该类进行初始化后才获取类的元数据,则该元数据中的第一变量中记录的应该是该类的静态域的第二地址。
这种情况下,访问该目标地址就可以直接访问到该类的待访问成员。也就是说,不需要进行初始化状态的判断就可以直接访问到类的静态成员,从而可以节省时间开销和空间开销。
若S220中是第一次获取类的元数据,例如,是在类初始化前获取类的元数据,则该元数据中的第一变量中记录的第一地址是受保护的。这种情况下,根据第一变量中记录的第一地址所确定的访问待访问成员的目标地址也应当是属于保护页中,也是受保护的,或者说也是不可以访问的,因此,访问该目标地址会导致内存访问异常。
运行时系统所依赖的操作系统在内存访问异常时,可以生成SIGSEGV异常信号。该操作系统可以根据预先配置的该SIGSEGV异常信号与异常处理的绑定关系,触发该运行时系统进行异常处理。其中,SIGSEGV异常信号与异常处理的绑定关系可以是运行时系统进行环境配置时通知操作系统的。
也就是说,本申请实施例的访问类的静态成员的方法还可以包括:在SIGSEGV异常信号的触发下执行异常处理,其中,该异常处理可以包括:调用该类的构造方法对该类进行初始化,将该类的静态域的第二地址记录到该类的第一变量中;再次根据该第一变量中记录的第二地址,确定该类的静态域中的待访问成员的目标地址;重新访问该待访问成员目标地址,以访问该待访问成员。
例如,可以自定义一个名为信号处理(singal handler)的函数,该函数中可以调用类的构造方法对类进行初始化,并将该类的静态域的第二地址记录到该类的第一变量中,然后,该函数改变控制流,从S220开始重新执行访问类的静态成员的方法。
在SIGSEGV异常信号的触发下执行异常处理的情况下,可选地,在调用该类的构造方法对该类进行初始化之前,该异常处理还可以包括:确定发生内存访问异常的地址属于访问类的运行时系统。
例如,确定发生内存访问异常的程序计数器(program counter,PC)属于访问类的运行时系统。PC用来存放当前执行的指令的地址。
也就是说,在SIGSEGV异常信号的触发下执行异常处理的情况下,可以先检测触发内存访问异常的运行时系统是否是当前执行异常处理的运行时系统,若是,则调用引发内存访问异常的类的构造方法来初始化该类,并将该类的静态域的第二地址记录到该类的第一变量中;以及再次根据该第一变量中记录的第二地址,确定该类的静态域中的待访问成员的目标地址,和重新访问该待访问成员目标地址,以访问该待访问成员。
若触发内存访问异常的运行时系统不是当前执行异常处理的运行时系统,则不对该SIGSIGV异常信号进行处理。
这样,可以使得即使该操作系统中配置了多个运行时系统时,也可以准确的针对当前的运行时系统进行类的初始化。
在SIGSEGV异常信号的触发下执行异常处理的情况下,可选地,若该类的元数据中的第一变量中记录的第一地址为保护页中的地址,则在调用该类的构造方法对该类进行初始化之前,该异常处理还可以包括:确定产生内存访问异常的内存地址位于第一变量中记录的保护页的范围内。
也就是说,在SIGSEGV异常信号的触发下执行异常处理的情况下,可以先判断触发内存访问异常所访问的地址是否位于第一变量中记录的第一地址所属的页的范围内;若是,则说明该类还没有初始化,则调用引发内存访问异常的类的构造方法来初始化该类,并将该类的静态域的第二地址记录到该类的第一变量中,以及再次根据该第一变量中记录的第二地址,确定该类的静态域中的待访问成员的目标地址,和重新访问该待访问成员目标地址,以访问该待访问成员;若不是,则不对该SIGSEGV异常信号进行处理。
这样,可以进一步确保该内存访问异常是由于类还没有进行初始化所引发的,从而可以提高初始化的准确性。
可选地,在SIGSEGV异常信号的触发下执行异常处理的情况下,该异常处理既可以包括确定发生内存访问异常的PC属于访问类的运行时系统,也可以包括确定产生内存访问异常的内存地址位于第一变量中记录的保护页的范围内。当然并不限定这两个步骤的先后顺序。
本申请实施例的访问类的静态成员的方法中,可选地,在获取类的所述元数据之前,该方法还可以包括:生成该类的元数据,该元数据中包括该第一变量,该第一变量中记录的地址为不可访问的第一地址。例如,第一变量中记录的可以是保护页中的第一地址。
其中,可以由编译器来生成类的元数据。也就是说,在编译器编译包含该类的源文件或源代码时,即为类生成包括第一变量的元数据,并在第一变量中记录保护页中的第一地址。这样,运行时系统第一次获取类的元数据并根据该元数据中的第一变量中记录的第一地址访问待访问成员时,必然会导致内存访问异常,从而可以在SIGSEGV异常信号的触发下初始化该类。
下面Java类为例,详细介绍本申请实施例中的访问类的静态成员的方法。
首先,使用编译器(例如Figo编译器)编译Java类时,生成类的元数据。在这个元数据中设置一个变量,即前面所述的第一变量,这个变量中记录保护页中的一个地址(第一地址)。
例如,可以在Java类的元数据中设置一个变量class_init_state。变量class_init_state被设置为class_init_protect_page,class_init_protect_page指向的内存页在运行时系统开始运行时被设为读写受保护。
其次,编译器编译Java源代码时,可以将访问Java类的静态成员的语句编译成如下三条汇编指令:
1:mov scratch0,_classinfo_classname
2:ldr scratch1,[scratch0+offset of class_init_state]
3:ldr r0,[scratch1,offset]
其中,变量_classinfo_classname表示类的元数据的地址,第一条汇编指令用于将类的元数据的地址移动到寄存器scratch0中;offset of class_init_state表示变量class_init_state相对于元数据的地址_classinfo_classname的位置偏移量,offset ofclass_init_state的大小由变量class_init_state的类型决定,第二条汇编指令用于将变量class_init_state中记录的地址中的值存放到寄存器scratch1中;第三条汇编中的offset表示待访问成员相对于class_init_state中记录的地址的位置偏移量,第三条汇编指令用于加载类的静态域中位置偏移量为offset的静态成员,offset的值由待访问成员的类型决定。
应注意的是,Java源代码中每个访问Java类的静态成员的语句都可以编译成上述三条汇编指令,不同的语句编译得到的三条汇编指令中的_classinfo_classname、offsetof class_init_state和offset的值可能不同。
应理解,上述汇编指令中的各个变量的名称仅是示例,不应对本申请实施例构成限制。
在Java的运行时系统中设置SIGSEGV异常信号与自定义signal handler函数的对应关系,并向操作系统通知该对应关系。
signal handler函数用于调用引发该SIGSEGV异常信号的类的构造器对该类进行初始化,以及将该类的静态域的起始地址(第二地址)写到类的元数据的第一变量中。
编译器编译Java源代码后,在Java的运行环境中运行该Java源代码编译得到的汇编指令时,访问Java类的静态成员的步骤如图3所示。其中,访问Java类的源代码被编译成上述三条汇编指令。
S301,执行第1条指令,获取Java类的元数据。
S302,执行第2条指令,获取class_init_state(即第一变量)中的值,并将class_init_state中的值存储于scratch1寄存器中。
S303,执行第3条指令,以读取偏移量为offset的静态成员(即待访问成员)。
S304,class_init_state中的值是否受保护。若是,则执行S305,否则执行S308。
S305,操作系统抛出SIGSEGV异常信号。
通常情况下,如果是第一次获取该Java类的元数据,或者说,该Java类还没初始化,则class_init_state中的值为class_init_protect_page指向的地址,这种情况下,会执行S305。
S306,该SIGSEGV信号触发signal handler函数。
S307,signal handler函数根据第1条指令,获取Java类的元数据;然后根据Java类的元数据获取该Java类的构造器<clinit>方法,执行该构造器<clinit>方法,对该Java类进行初始化,以将类的静态域的有效起始地址(第二地址)填写到该Java类的元数据的class_init_state中;接下来重新从S301开始执行。
S308,访问该Java类的偏移量为offset的静态成员。
在S307中,signal handler函数再次执行第1条指令,获取Java类的元数据是为了保证scratch1寄存器中最新记录的是该Java类的元数据的地址,即避免在执行S302至S306的过程中,scratch1寄存器中的值被改变。
在S307中,对该Java类进行初始化,并将该类的静态域的有效起始地址填写到该Java类的元数据的class_init_state中后,重新从S301开始执行,即重新获取元数据,并根据元数据获取第一变量,也可以保证scratch1寄存器中最新记录的是该Java类的元数据的地址,即避免在执行初始化的过程中,scratch1寄存器中的值被改变而导致所第一变量不是当前要访问的Java类的元数据中的第一变量,从而避免访问类成员错误。
下面结合具体的Java类来进一步介绍本申请的访问类的静态成员的方法。
例如,Java源代码中包括类foo和类bar。类foo和类bar的定义如下:
Figure BDA0001828499920000081
其中,在类bar的getlong()方法中访问类foo的静态域中的静态成员l。
首先,Figo编译器编译生成的可执行与可链接格式(Executable and LinkableFormat,ELF)文件中包括如下内容:
Figure BDA0001828499920000082
类foo的静态域的内存布局如下:
Figure BDA0001828499920000083
Figure BDA0001828499920000091
访问类foo的静态域中的静态成员l时,执行的汇编指令如下所示:
1:mov scratch0,__classinfo_foo
2:ldr scratch1,[scratch0+offset of class_init_state]
3:ldr r0,[scratch1,20]
其中,若类foo未被初始化时,访问foo类的静态域中的静态成员l的流程如下:
1)分析第1条汇编指令可以获取__classinfo__foo的值。
2)当foo类的类构造器<clinit>方法没有执行过时,执行第2条汇编指令后,scratch1寄存器中的内容为class_init_protect_page,执行第3条汇编指令时,因为class_init_protect_page指向的地址所在的页被保护,所以抛出SIGSEGV异常信号,触发自定义signal handler函数。此时,PC停留在第3条汇编指令上。
3)自定义signal handler函数检查发生内存访问异常的PC是否属于Java栈帧(frame),且发生内存访问异常的内存地址是否在[class_init_protect_page,class_init_protect_page+Page_Size)范围内,如果是,说明foo类没有初始化。
4)分析第1条汇编指令重新获取__classinfo__foo的值,进而获取foo类的类构造器<clinit>方法的入口地址,调用该方法执行初始化。
5)在自定义的signal handler里将foo类的静态域的有效起始地址class_foo_static_fields值填写到class_init_state,然后从第1条汇编指令恢复控制流,执行到第2条汇编指令时获取到类的静态域起始地址,执行到第3条汇编指令时能够获取类成员。
6)若类foo已被初始化,访问foo类的静态域中的静态成员l时,第3条汇编指令执行不会发生异常,控制流正常执行,无额外开销。
图4是本申请实施例的访问类的静态成员的装置400的示意性框图。应理解,装置400仅是一种示例。本申请实施例的装置还可包括其他模块或单元,或者包括与图4中的各个模块的功能相似的模块,或者并非要包括图4中的所有模块。
获取模块410,用于获取类的元数据,所述元数据中包括第一变量,在所述类初始化之前,所述第一变量中记录不可访问的第一地址,在所述类初始化之后,所述第一变量中记录所述类的静态域的第二地址。
确定模块420,用于根据所述第一变量中记录的第一地址或第二地址,确定所述类的静态域中的待访问成员的目标地址。
访问模块430,用于访问所述目标地址,以访问所述待访问成员。
可选地,所述装置400还包括处理模块440,用于:在SIGSEGV异常信号的触发下执行异常处理,其中,所述异常处理包括:调用所述类的构造方法对所述类进行初始化,将所述类的静态域的第二地址记录到所述第一变量中;调用所述确定模块420和所述访问模块430。
可选地,在调用所述类的构造方法对所述类进行初始化之前,所述异常处理还包括:确定发生所述内存访问异常的地址属于访问所述类的运行时系统。
可选地,在所述处理模块440调用所述类的构造方法对所述类进行初始化之前,所述第一变量中记录的第一地址为保护页中的地址。
其中,在调用所述类的构造方法对所述类进行初始化之前,所述异常处理还包括:确定所述内存地址位于所述保护页的范围内。
可选地,所述装置400还包括生成模块450,用于:在所述获取模块410获取所述类的所述元数据之前,生成所述元数据,所述元数据中包括所述第一变量,所述第一变量中记录的第一地址为保护页中的地址。
装置400可以用于执行图2或图3描述的方法的步骤,为了简洁,此处不再赘述。
图5是本申请另一个实施例的访问类的静态成员的装置的示意性结构图。应理解,图5示出的装置500仅是示例,本申请实施例的装置还可包括其他模块或单元,或者包括与图5中的各个模块的功能相似的模块。
装置500可以包括一个或多个处理器510,一个或多个存储器520。存储器520用于存储处理器510执行的程序代码。处理器510用于调取存储器520中的指令。
其中,处理器510中可以集成有存储器520,或者处理器510耦合到一个或多个存储器520。
处理器510可以用于实现图4中的获取模块410、确定模块420、访问模块430、处理模块440和生成模块450能够实现的操作或步骤。
本领域普通技术人员可以意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、或者计算机软件和电子硬件的结合来实现。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的系统、装置和单元的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
在本申请所提供的几个实施例中,应该理解到,所揭露的系统、装置和方法,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
另外,在本申请各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。
应理解,本申请实施例中的处理器可以为中央处理单元(central processingunit,CPU),该处理器还可以是其他通用处理器、数字信号处理器(digital signalprocessor,DSP)、专用集成电路(application specific integrated circuit,ASIC)、现场可编程门阵列(field programmable gate array,FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。
所述功能如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分或者该技术方案的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本申请各个实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(read-only memory,ROM)、随机存取存储器(random access memory,RAM)、磁碟或者光盘等各种可以存储程序代码的介质。
以上所述,仅为本申请的具体实施方式,但本申请的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本申请揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本申请的保护范围之内。因此,本申请的保护范围应以所述权利要求的保护范围为准。

Claims (12)

1.一种访问类的静态成员的方法,其特征在于,包括:
获取类的元数据,所述元数据中包括第一变量,在所述类初始化之前,所述第一变量中记录不可访问的第一地址,在所述类初始化之后,所述第一变量中记录所述类的静态域的第二地址;
根据所述第一变量中记录的所述第一地址或所述第二地址,确定所述类的静态域中的待访问成员的目标地址;
访问所述目标地址,以访问所述待访问成员。
2.根据权利要求1所述的方法,其特征在于,所述方法还包括:
在SIGSEGV异常信号的触发下执行异常处理,其中,所述异常处理包括:调用所述类的构造方法对所述类进行初始化,将所述类的静态域的所述第二地址记录到所述第一变量中。
3.根据权利要求2所述的方法,其特征在于,在调用所述类的构造方法对所述类进行初始化之前,所述异常处理还包括:
确定发生内存访问异常的地址属于访问所述类的运行时系统。
4.根据权利要求2或3所述的方法,其特征在于,在调用所述类的构造方法对所述类进行初始化之前,所述第一变量中记录的所述第一地址为保护页中的地址;
其中,在调用所述类的构造方法对所述类进行初始化之前,所述异常处理还包括:
确定发生内存访问异常的地址位于所述保护页的范围内。
5.根据权利要求1至4中任一项所述的方法,其特征在于,在获取所述类的所述元数据之前,所述方法还包括:
生成所述元数据,所述元数据中包括所述第一变量,所述第一变量中记录的所述第一地址为保护页中的地址。
6.一种访问类的静态成员的装置,其特征在于,包括:
获取模块,用于获取类的元数据,所述元数据中包括第一变量,在所述类初始化之前,所述第一变量中记录不可访问的第一地址,在所述类初始化之后,所述第一变量中记录所述类的静态域的第二地址;
确定模块,用于根据所述第一变量中记录的所述第一地址或所述第二地址,确定所述类的静态域中的待访问成员的目标地址;
访问模块,用于访问所述目标地址,以访问所述待访问成员。
7.根据权利要求6所述的装置,其特征在于,所述装置还包括处理模块,用于:
在SIGSEGV异常信号的触发下执行异常处理,其中,所述异常处理包括:调用所述类的构造方法对所述类进行初始化,将所述类的静态域的所述第二地址记录到所述第一变量中;
调用所述确定模块和所述访问模块。
8.根据权利要求7所述的装置,其特征在于,在调用所述类的构造方法对所述类进行初始化之前,所述异常处理还包括:
确定发生内存访问异常的地址属于访问所述类的运行时系统。
9.根据权利要求7或8所述的装置,其特征在于,在所述处理模块调用所述类的构造方法对所述类进行初始化之前,所述第一变量中记录的所述第一地址为保护页中的地址;
其中,在调用所述类的构造方法对所述类进行初始化之前,所述异常处理还包括:
确定发生内存访问异常的地址位于所述保护页的范围内。
10.根据权利要求6至9中任一项所述的装置,其特征在于,所述装置还包括生成模块,用于:在所述获取模块获取所述类的所述元数据之前,生成所述元数据,所述元数据中包括所述第一变量,所述第一变量中记录的所述第一地址为保护页中的地址。
11.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质上存储有程序,当所述程序运行时,实现如权利要求1至5中任一项所述的方法。
12.一种访问类的静态成员的装置,其特征在于,包括:与程序指令相关的硬件,所述硬件用于执行权利要求 1至5中任一项所述的方法。
CN201811194933.3A 2018-10-15 2018-10-15 访问类的静态成员的方法和装置 Active CN111045658B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201811194933.3A CN111045658B (zh) 2018-10-15 2018-10-15 访问类的静态成员的方法和装置

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201811194933.3A CN111045658B (zh) 2018-10-15 2018-10-15 访问类的静态成员的方法和装置

Publications (2)

Publication Number Publication Date
CN111045658A CN111045658A (zh) 2020-04-21
CN111045658B true CN111045658B (zh) 2021-10-01

Family

ID=70230572

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201811194933.3A Active CN111045658B (zh) 2018-10-15 2018-10-15 访问类的静态成员的方法和装置

Country Status (1)

Country Link
CN (1) CN111045658B (zh)

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN1234553A (zh) * 1998-03-23 1999-11-10 太阳微系统有限公司 减少编译代码中动态类初始化检查的代价的技术
CN102103489A (zh) * 2011-01-28 2011-06-22 武汉天喻信息产业股份有限公司 一种提高静态域访问指令执行效率的方法
CN103246611A (zh) * 2012-02-07 2013-08-14 腾讯科技(深圳)有限公司 一种文件处理方法及系统
WO2016094258A1 (en) * 2014-12-10 2016-06-16 Microsoft Technology Licensing, Llc Inter-procedural type propagation for devirtualization

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN1234553A (zh) * 1998-03-23 1999-11-10 太阳微系统有限公司 减少编译代码中动态类初始化检查的代价的技术
CN102103489A (zh) * 2011-01-28 2011-06-22 武汉天喻信息产业股份有限公司 一种提高静态域访问指令执行效率的方法
CN103246611A (zh) * 2012-02-07 2013-08-14 腾讯科技(深圳)有限公司 一种文件处理方法及系统
WO2016094258A1 (en) * 2014-12-10 2016-06-16 Microsoft Technology Licensing, Llc Inter-procedural type propagation for devirtualization

Also Published As

Publication number Publication date
CN111045658A (zh) 2020-04-21

Similar Documents

Publication Publication Date Title
US8266608B2 (en) Post-compile instrumentation of object code for generating execution trace data
CN109271789B (zh) 恶意进程检测方法、装置、电子设备及存储介质
JP2015516601A (ja) 被管理ランタイムのためのハードウェア・ベース・ランタイム計装機構
US20170220795A1 (en) Information-processing device, information-processing monitoring method, and recording medium
Salehi et al. {μSBS}: Static Binary Sanitization of Bare-metal Embedded Devices for Fault Observability
US20020073359A1 (en) System and method for high priority machine check analysis
CN113778838B (zh) 二进制程序动态污点分析方法及装置
US9069900B2 (en) Method for determining whether a machine code instruction of a machine code program is executed in the machine code program
CN111045658B (zh) 访问类的静态成员的方法和装置
CN111931191A (zh) Linux平台二进制软件堆溢漏洞动态检测方法及系统
Chen et al. CARE: Compiler-assisted recovery from soft failures
Hermann et al. Getting to know you: Towards a capability model for java
CN111309444B (zh) 利用进程虚拟机反调试的方法、装置、系统及存储介质
JP4725240B2 (ja) データトレース方法およびトレースモジュール
KR101225577B1 (ko) 어셈블리 언어 코드의 분석 장치 및 방법
CN114238153B (zh) 一种Linux系统中二进制文件检测方法
Fan et al. Advanced memory checking frameworks for MPI parallel applications in Open MPI
Brown Control-flow Integrity for Real-time Embedded Systems
CN115470151B (zh) 一种应用运行分析方法、计算设备及存储介质
CN111625784B (zh) 一种应用的反调试方法、相关装置及存储介质
CN112527660B (zh) 代码的静态检测方法和装置
JP5822848B2 (ja) 例外の制御方法、システムおよびプログラム
Vostokov Memory Dump Analysis Anthology
CN114489657A (zh) 用于编译源代码的系统和过程
CN117873646A (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