CN114327776A - 用于智能合约的调试方法、调试设备和调试系统 - Google Patents

用于智能合约的调试方法、调试设备和调试系统 Download PDF

Info

Publication number
CN114327776A
CN114327776A CN202111655712.3A CN202111655712A CN114327776A CN 114327776 A CN114327776 A CN 114327776A CN 202111655712 A CN202111655712 A CN 202111655712A CN 114327776 A CN114327776 A CN 114327776A
Authority
CN
China
Prior art keywords
debugging
function
program
instruction
virtual machine
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
CN202111655712.3A
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.)
Alipay Hangzhou Information Technology Co Ltd
Ant Blockchain Technology Shanghai Co Ltd
Original Assignee
Alipay Hangzhou Information Technology Co Ltd
Ant Blockchain Technology Shanghai 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 Alipay Hangzhou Information Technology Co Ltd, Ant Blockchain Technology Shanghai Co Ltd filed Critical Alipay Hangzhou Information Technology Co Ltd
Priority to CN202111655712.3A priority Critical patent/CN114327776A/zh
Publication of CN114327776A publication Critical patent/CN114327776A/zh
Pending legal-status Critical Current

Links

Images

Landscapes

  • Debugging And Monitoring (AREA)

Abstract

本说明书实施例提供一种用于智能合约的调试方法、调试设备和调试系统。调试方法包括:获取智能合约的包括调试信息的第一字节码程序文件,或者智能合约的第一字节码程序文件以及包括调试信息的调试信息文件;对第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件;对第二字节码程序文件进行编译,以产生机器码程序文件;以及根据断点信息和调试命令,以调试状态来执行机器码程序文件,并结合函数列表信息和映射信息对智能合约进行调试。

Description

用于智能合约的调试方法、调试设备和调试系统
技术领域
本说明书实施例属于区块链技术领域,尤其涉及一种用于智能合约的调试方法、调试设备和调试系统。
背景技术
区块链技术构建在传输网络(例如点对点网络)之上。传输网络中的网络节点利用链式数据结构来验证与存储数据,并采用分布式节点共识算法来生成和更新数据。区块链2.0时代中出现了智能合约,将区块链的应用范围提升到了一个新高度。有了智能合约,区块链能实现的不再是单一的转账交易,而是还可以实现用户自定义的其他功能。在用户开发智能合约的过程中,通常需要对智能合约进行调试,因此存在对可靠且高效的用于智能合约的调试方法的需求。
发明内容
本发明的目的在于提供一种用于智能合约的调试方法、调试设备和调试系统,以便可靠且高效地调试智能合约。
根据本说明书一个或多个实施例的第一方面,提供了一种用于智能合约的调试方法,包括:
虚拟机获取所述智能合约的包括调试信息的第一字节码程序文件,或者所述虚拟机获取所述智能合约的第一字节码程序文件以及包括调试信息的调试信息文件,其中,所述调试信息包括所述智能合约的源码与字节码之间的映射信息以及函数列表信息;
在所述虚拟机中对所述第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件,并相应地修改所述映射信息,其中,所述中断处理函数用于确定是否在其所在的当前运行位置处中断运行,所述堆栈维护函数用于记录在其所在的当前运行位置处的函数调用状态;
在所述虚拟机中对所述第二字节码程序文件进行编译,以产生机器码程序文件;以及
根据所述虚拟机获取的断点信息和调试命令,在所述虚拟机中以调试状态来执行所述机器码程序文件,并结合所述函数列表信息和所述映射信息对所述智能合约进行调试。
根据本说明书一个或多个实施例的第二方面,提供了一种用于智能合约的调试设备,包括处理器和存储器,所述存储器上存储有指令,当所述指令被所述处理器执行时,实现如上所述的调试方法的步骤。
根据本说明书一个或多个实施例的第三方面,提供了一种用于智能合约的调试系统,包括虚拟机,所述虚拟机包括:
获取模块,所述获取模块被配置为获取所述智能合约的包括调试信息的第一字节码程序文件,或者获取所述智能合约的第一字节码程序文件以及包括调试信息的调试信息文件,其中,所述调试信息包括所述智能合约的源码与字节码之间的映射信息以及函数列表信息;
修改模块,所述修改模块被配置为对所述第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件,并相应地修改所述映射信息,其中,所述中断处理函数用于确定是否在其所在的当前运行位置处中断运行,所述堆栈维护函数用于记录在其所在的当前运行位置处的函数调用状态;
编译模块,所述编译模块被配置为在所述虚拟机中对所述第二字节码程序文件进行编译,以产生机器码程序文件;以及
执行模块,所述执行模块被配置为根据所述获取模块获取的断点信息和调试命令,以调试状态来执行所述机器码程序文件,并结合所述函数列表信息和所述映射信息对所述智能合约进行调试。
附图说明
为了更清楚地说明本说明书实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本说明书中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1是本说明书一实施例中用于智能合约的调试方法的流程图;
图2是本说明书一实施例中用于智能合约的调试方法的步骤S300的流程图;
图3是本说明书一实施例中用于智能合约的调试方法的步骤S700的流程图;
图4是本说明书一实施例中用于智能合约的调试方法的步骤S770的流程图;
图5是本说明书另一实施例中用于智能合约的调试方法的步骤S770的流程图;
图6是本说明书一实施例中用于智能合约的调试设备的框图;
图7是本说明书一实施例中用于智能合约的调试系统的框图。
具体实施方式
为了使本技术领域的人员更好地理解本说明书中的技术方案,下面将结合本说明书实施例中的附图,对本说明书实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本说明书一部分实施例,而不是全部的实施例。基于本说明书中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本说明书保护的范围。
区块链一般可以被划分为三种类型:公有链(Public Blockchain),私有链(PrivateBlockchain)和联盟链(Consortium Blockchain)。此外,还有多种类型的结合,比如私有链+联盟链、联盟链+公有链等不同组合形式。其中去中心化程度最高的是公有链。加入公有链的参与者可以读取链上的数据记录、参与交易以及竞争新区块的记账权等。而且,各参与者(即节点)可自由加入以及退出网络,并进行相关操作。私有链则相反,该网络的写入权限由某个组织或者机构控制,数据读取权限受组织规定。简单来说,私有链可以为一个弱中心化系统,参与节点具有严格限制且少。这种类型的区块链更适合于特定机构内部使用。联盟链则是介于公有链以及私有链之间的区块链,可实现“部分去中心化”。联盟链中各个节点通常有与之相对应的实体机构或者组织;参与者通过授权加入网络并组成利益相关联盟,共同维护区块链运行。
不论是公有链、私有链还是联盟链,都可能提供智能合约的功能。区块链上的智能合约是在区块链系统上可以被交易触发执行的合约。智能合约可以通过代码的形式定义。智能合约可以以规定的方式在区块链网络中每个节点独立的执行,所有执行记录和数据都保存在区块链上,所以当这样的交易完成后后,区块链上就保存了无法篡改、不会丢失的交易凭证。
在支持智能合约的区块链(例如,蚂蚁链)中,支持用户在区块链网络中创建并调用一些复杂的逻辑。一个可编程区块链的核心是虚拟机,每个区块链节点都可以运行这个虚拟机。虚拟机可以是图灵完备的,这意味着可以通过它实现各种复杂的逻辑。用户在区块链中发布和调用智能合约就是在虚拟机上运行的。实际上,虚拟机直接运行的是虚拟机代码(虚拟机字节码,下简称“字节码”)。部署在区块链上的智能合约可以是字节码的形式。在本说明书一个或多个实施例中,虚拟机可以是WASM虚拟机,相应地,本说明书一个或多个实施例中涉及的字节码程序文件(例如,下文所述的第一字节码程序文件和第二字节码程序文件)可以是WASM文件。其中,WASM是WebAssembly的简称,是一种贴近计算机底层的低层级编程语言,是一种可移植、具有大小与加载高效率的二进制格式,可以被编译至常见的平台。
字节码由一连串的字节组成,每一字节可以标识一个操作。基于开发效率、可读性等多方面考虑,开发者可以不直接书写字节码,而是选择一门高级语言编写智能合约代码。高级语言编写的智能合约代码,经过高级语言编译器编译,生成字节码,进而该字节码可以部署到区块链上。
在运行部署在区块链上的字节码之前,还需要由不同于高级语言编译器的字节码编译器将字节码编译为更底层的机器码。对应于不同的编译方式,存在多种运行方式,包括解释运行、即时编译(JIT)运行和静态编译(AOT)运行等。在解释运行中,可以依次对字节码程序文件中的一条条指令进行解释运行,其效率通常很差。在JIT运行中,可以在运行时将字节码程序文件编译成机器码形式的可执行程序,即机器码程序文件,然后执行编译生成的机器码程序文件。即时编译可以包括源代码或字节码到机器码的转换,实现即时编译的系统可以不断地分析正在执行的代码,并确定代码的某些部分,在这些部分中,编译或重新编译所获得的性能的提高将大于编译该代码的开销。相比解释运行的运行效率而言,JIT运行的运行效率可以有数量级上的提高,并且可能做到接近系统原生的可执行程序的运行效率的水平。在AOT运行中,可以在运行前将字节码程序文件提前编译成机器码程序文件,然后执行编译所生成的机器码程序文件,从而避免了在运行时进行JIT编译的操作。AOT运行的运行效率也可以比解释运行的运行效率有数量级上的提高,且可以接近系统原生的可执行程序的水平。
在开发智能合约的过程中,可以通过调试器来实现调试。调试器是指一种用于调试其他程序的计算机程序及工具,其能够在运行环境中检查代码的运行状况以及使代码被选择性地运行,从而方便进行排错和调整。相应地,在虚拟机中,除了运行智能合约本身的程序运行线程之外,还可以包括调试器线程,在调试器线程中可以执行与对智能合约的调试相关联的操作,如后文中将详细描述的。
一种用于智能合约的调试方法可以是基于解释器来实现的。具体而言,可以在解释运行字节码程序文件的过程中,在字节码程序文件中的每条指令被执行时,检查相应的位置是否存在断点,并查看断点处的相关信息。然而,这种调试方法需要额外地提供解释器,且基于解释器的调试通常具有非常低的效率。此外,用于调试智能合约的解释器和用于执行智能合约的虚拟机的行为可能存在不一致之处,这将导致调试的可靠性降低。
在另一种用于智能合约的调试方法中,可以直接基于对字节码程序文件编译后所产生的机器码程序文件来进行调试,例如相应地修改机器码程序文件以添加断点,并查看断点处的相关信息等。这种调试方法可以具有较高的效率,但是在调试过程中需要维护智能合约的源码与机器码之间的映射关系,其实现难度往往较大。
为了解决上述问题,本说明书一个或多个实施例提供了一种用于智能合约的调试方法。
如图1所示,该调试方法可以包括:
步骤S100,虚拟机获取智能合约的包括调试信息的第一字节码程序文件,或者虚拟机获取智能合约的第一字节码程序文件以及包括调试信息的调试信息文件。
其中,调试信息可以包括智能合约的源码与字节码之间的映射信息以及函数列表信息。在调试过程中,调试信息可以用于定位当前运行位置在智能合约的源码中的对应位置,并且帮助查看源码形式的相关变量的值等。调试信息或者调试信息文件可以是在将智能合约的源码编译为字节码的过程中由高级语言编译器生成的。常用的调试信息文件的格式包括dwarf等。其中,映射信息可以包括智能合约的源码的行号与相应的字节码的行号之间的映射关系,而函数列表信息可以包括智能合约中的函数的名称、函数的词法作用域、变量的名称、变量的数据类型、变量的词法作用域、变量的索引、参数的名称和参数的索引中的至少一者。需要注意的是,在其他实施例中,调试信息或调试信息文件中也可以包括其他信息或数据,在此不作限制。
如图1所示,调试方法还可以包括:
步骤S300,在虚拟机中对第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件,并相应地修改映射信息。
其中,当中断处理函数被调用时,可以确定是否在当前运行位置处中断运行。可以根据调试的需要来在第二字节码程序文件中的相应位置处添加用于调用中断处理函数的第一指令。当堆栈维护函数被调用时,可以在函数调用栈中记录在当前运行位置处的函数调用状态,以便在调试过程中进行定位、查看等操作。由于修改是针对第一字节码程序文件进行的,在智能合约的源码中并未包含如本文所述的针对调试所做的修改,因此无需对智能合约的高级语言编译器或字节码编译器本身的执行逻辑等进行修改。
如图2所示,在本说明书一个或多个实施例中,在虚拟机中对第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件可以包括在虚拟机的调试器线程中执行以下操作:
步骤S310,将第一字节码程序文件划分成一个或多个函数。
其中,第一字节码程序文件至少可以包括一个主函数。在大多数情况下,第一字节码程序文件还可以包括在上述主函数中的多个内部函数。对第一字节码程序文件的划分可以使其中的每条指令都被包括在至少一个函数中。此外,根据函数之间的引用关系,可以形成对应于第一字节码程序文件的函数树。在函数树中,引用某函数的其他函数可以被称为该函数的父函数,而被某函数引用的其他函数可以被称为该函数的子函数。
如图2所示,在虚拟机中对第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件还可以包括在虚拟机的调试器线程中针对一个或多个函数中的每个函数分别执行以下操作:
步骤S330,将函数划分成一个或多个基本块,使得该函数中的每条指令被包括且仅被包括在一个或多个基本块中的相应的一个基本块中;以及
步骤S350,在函数中的每个基本块的头部加入第一指令。
其中,每个基本块可以包括一条或多条指令,且一旦基本块被运行,包含在该基本块中的所有的指令被全部运行。也就是说,基本块可以被视为程序文件的运行单元,一旦基本块中的第一条指令被运行,那么将从该基本块中的第一条指令运行到该基本块中的最后一条指令,即运行了该基本块中的所有指令后才有可能中止运行,而不会出现基本块中的仅部分指令被运行的情况。
在本说明书一个或多个实施例中,将函数划分成一个或多个基本块,使得该函数中的每条指令被包括且仅被包括在一个或多个基本块中的相应的一个基本块中可以包括:
查找函数中的所有非线性运行指令;以及
根据查找到的非线性运行指令,将函数划分成一个或多个基本块,其中,每个非线性运行指令为其所在的基本块中的最后一条指令。
具体而言,非线性运行指令可以包括跳转指令、函数调用指令和修改变量值的存储类指令中的至少一者。在非线性运行指令处,程序文件不是顺序运行的,因此这些位置往往也是容易发生错误的位置,可能需要在调试的过程中重点予以关注。
在对所有函数完成上述操作后,也就实现了在第一字节码程序文件中的每个基本块的头部加入了用于调用中断处理函数的第一指令。这样,在程序运行到每个基本块的头部时,都可以判断是否要在当前运行位置处中断运行以待调试,用户可以根据调试的需要选择其中的一些或全部位置来中断,后文中还将详细阐述。
如图2所示,在虚拟机中对第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件还可以包括在虚拟机的调试器线程中执行以下操作:
步骤S370,在一个或多个函数中的每个函数的所有入口和出口之前加入第二指令。
如上文所述的,第二指令用于调用堆栈维护函数,堆栈维护函数可以通过维护一个函数调用栈来记录当前的函数调用状态,以便用户对智能合约进行调试,后文中还将详细阐述。每个函数可以包括一个或多个入口以及一个或多个出口,为了保障准确地记录函数调用状态,在所有的入口和所有的出口处都可以加入用于调用堆栈维护函数的第二指令。
在本说明书一个或多个实施例中,相应地修改映射信息可以包括在虚拟机的调试器线程中执行以下操作:
将映射信息中的智能合约的源码与第一字节码程序文件的字节码之间的第一映射关系修改为智能合约的源码与第二字节码程序文件的字节码之间的第二映射关系。
具体而言,可以将映射信息修改为源码的行号与第二字节码程序文件中的相应的字节码的行号之间的映射关系,以便在后续的调试过程中方便地根据映射信息和字节码来定位在源码中的相应的位置。
返回图1,调试方法还可以包括:
步骤S500,在虚拟机中对第二字节码程序文件进行编译,以产生机器码程序文件。
具体而言,可以通过虚拟机中的字节码编译器对第二字节码程序文件进行如上文所述的即时编译(JIT编译),以产生机器码程序文件。相应地,字节码编译器可以是JIT编译器。
如图1所示,调试方法还可以包括:
步骤S700,根据虚拟机获取的断点信息和调试命令,在虚拟机中以调试状态来执行机器码程序文件,并结合函数列表信息和映射信息对智能合约进行调试。
断点信息和调试命令可以是在调试过程中由用户输入到虚拟机中的,用户可以根据调试需求给出相应的断点信息和调试命令。当以调试状态来执行机器码程序文件时,在中断处理函数的作用下,机器码程序文件的运行可以在相应的位置处中断,用户可以通过给出调试命令并结合函数列表信息和映射信息来对智能合约进行调试。
具体而言,如图3所示,根据虚拟机获取的断点信息和调试命令,在虚拟机中以调试状态来执行机器码程序文件,并结合函数列表信息和映射信息对智能合约进行调试可以包括:
步骤S710,在虚拟机的调试器线程中获取来自用户的断点信息;
步骤S730,在虚拟机中运行机器码程序文件,直至中断处理函数基于断点信息使虚拟机的程序运行线程中断并处于调试器线程中。
其中,可以在编译获得机器码程序文件后、且运行机器码程序文件之前,获取来自用户的初始的断点信息。也可以在以调试状态执行机器码程序文件的过程中,在机器码程序文件被中断时,获取来自用户的修改的断点信息,以方便用户根据调试需要及时地调整需要中断的断点位置。
在本说明书一个或多个实施例中,可以基于断点信息位图(数组)来维护断点信息。第二字节码程序文件中的与每个用于调用中断处理函数的第一指令相关联的程序块可以分别具有唯一地表示该程序块的程序块标识以及用于确定在该程序块处是否要中断的中断指示标识,且所有程序块的程序块标识及其相应的中断指示标识可以被记录在断点信息位图中。其中,程序块标识可以是常量数值参数,某个程序块的程序块标识可以相比其相邻的前一个程序块的程序块标识递增1(可以理解的是,也可以以其他方式来设置程序块标识,在此不作限制),中断指示标识可以有true和false两种取值,其中true表示要中断,而false表示不要中断。通常情况下,每个程序块可以仅包括一个基本块,也就是说,第二字节码程序文件中的每个基本块可以分别具有唯一地表示该基本块的基本块标识以及用于确定在该基本块的头部是否要中断的中断指示标识,且所有基本块的基本块标识及其相应的中断指示标识可以被记录在断点信息位图中。然而,在一些实施例中,也可能根据需要使一个程序块包括多于一个基本块,在此不作限制。在获取到来自用户的初始的断点信息时,可以初始地建立断点信息位图并在其中相应地记录初始的断点信息。当机器码程序文件被中断运行且获取到来自用户的修改的断点信息时,可以根据修改的断点信息来更新标记断点信息位图,使得更新后的断点信息位图与修改的断点信息保持一致。具体而言,用户可以在智能合约的源码中修改断点行号以标记修改的断点位置,在虚拟机中,可以根据映射信息将断点位置的源码行号转换为断点位置的字节码行号,并将断点信息位图中的与该断点位置对应的中断指示标识修改为true。
进一步地,中断处理函数可以被配置为在虚拟机的调试器线程中执行以下操作:
读取断点信息位图中的当前程序块的相应的中断指示标识;
当根据中断指示标识确定在当前程序块处要中断时,使虚拟机处于调试器线程中;以及
当根据中断指示标识确定在当前程序块处不要中断时,使虚拟机处于程序运行线程中,直至运行到与下一个第一指令相关联的程序块,并返回读取断点信息位图中的当前程序块的相应的中断指示标识的步骤。
在如上文所述的在第二字节码程序文件的每个基本块的头部都加入有第一指令的情况下,在运行机器码程序文件的过程中,在每个基本块的头部,都将调用中断处理函数以确定在这个基本块的头部是否需要中断程序运行线程并进入调试器线程。中断处理函数读取断点信息位图中的与当前基本块相应的中断指示标识。如果所读取到的中断指示标识为true,则中断程序运行线程并进入调试器线程,而如果所读取到的中断指示标识为false,则继续程序运行线程以运行相应的基本块,直至到达下一个基本块时重复上述判断过程。中断处理函数还可以包括其相应的基本块的开始指令行号和结尾指令行号两个参数,以便中断处理函数控制程序运行的中断。
返回图3,根据虚拟机获取的断点信息和调试命令,在虚拟机中以调试状态来执行机器码程序文件,并结合函数列表信息和映射信息对智能合约进行调试还可以包括:
步骤S750,在调试器线程中获取来自用户的调试命令;以及
步骤S770,根据调试命令,结合函数列表信息和映射信息对智能合约进行调试。
如上文所述的,为了便于对智能合约进行调试,可以通过堆栈维护函数来维护一个函数调用栈,以记录当前运行位置处的函数调用状态。具体而言,堆栈维护函数可以被配置为在虚拟机的调试器线程中执行以下操作:在当前运行位置为函数的入口时,向函数调用栈压栈与当前运行位置相关联的记录;以及在当前运行位置为函数的出口时,从函数调用栈出栈与当前运行位置相关联的记录。其中,与当前运行位置相关联的记录可以包括当前运行位置处的指令的行号。在修改函数调用栈的过程中,可以先填入占位符,最终替换成正确的指令的行号。
在本说明书一个或多个实施例中,调试命令可以包括行进命令,用户可以通过行进命令来指示将要运行的下一条指令,以使虚拟机在合适的条件下在调试器状态与程序运行状态之间切换,从而方便对智能合约的继续调试。
在调试命令包括行进命令的情况下,如图4所示,根据调试命令,结合函数列表信息和映射信息对智能合约进行调试可以包括:
步骤S771,在调试器线程中记录在获取到行进命令时的函数调用栈的栈桢深度;
步骤S773,在调试器线程中根据所记录的栈桢深度和行进命令来修改最大调试栈桢深度和最小调试栈桢深度;以及
步骤S775,中断调试器线程并进入程序运行线程以运行机器码程序文件,直至程序运行线程基于所修改的最小调试栈桢深度和最大调试栈桢深度再次中断并重新进入调试器线程。
其中,虚拟机的程序运行线程仅在当前栈桢深度大于或等于最小调试栈桢深度、且小于或等于最大调试栈桢深度的情况下运行,最小调试栈桢深度和最大调试栈桢深度可以是调试器的两个全局变量。栈帧深度反映了当前运行的函数的调用级别。例如,如果当前运行的函数为C,且函数C被函数B调用,函数B被主函数A调用,那么,当前的栈桢深度则为3。由于程序运行线程仅在当前栈桢深度大于或等于最小调试栈桢深度、且小于或等于最大调试栈桢深度的情况下运行,因此通过修改最大调试栈桢深度和最小调试栈桢深度,可以控制程序运行线程与调试器线程之间的切换。
在一具体示例中,当所记录的栈桢深度(即当前栈桢深度)为n、行进命令为用于使程序运行线程在进行到对应于第二字节码程序文件中的下一个要中断的位置处中断,或使程序运行线程在进行到对应于智能合约的源码中的不是调用当前函数的子函数的下一条指令时中断(也就是说,如果当前运行位置的下一条指令是调用子函数的指令,则正常地进入并运行子函数,直至栈桢深度重新返回到对应于当前函数时再中断;如果当前运行位置的下一条指令不是调用子函数的指令,则直接中断),或使程序运行线程进行到引用当前函数的上一级父函数时中断的step over命令时,为了实现step over命令,可以将最小调试栈桢深度修改为(n+1),最大调试栈桢深度修改为对应于无穷大。这样,在机器码程序文件运行至使当前栈桢深度小于或等于n时,再次进入调试器线程。
在另一具体示例中,当所记录的栈桢深度为n、行进命令为用于使程序运行线程在进行到对应于第二字节码程序文件中的下一个要中断的位置处中断,或使程序运行线程进行到引用当前函数的上一级父函数时中断的step out命令时,为了实现step out命令,可以将最小调试栈桢深度修改为n,最大调试栈桢深度修改为对应于无穷大。这样,在机器码程序文件运行至使当前栈桢深度小于n时,再次进入调试器线程。
在又一具体示例中,当行进命令为用于使程序运行线程单步进行到对应于智能合约的源码中的当前函数的下一条指令时中断,或使程序运行线程进行到被当前函数引用的下一级子函数时中断的step in命令时,可以将最小调试栈桢深度修改为大于最大调试栈桢深度,例如将最小调试栈桢深度修改为2,最大调试栈桢深度修改为1,即始终无法满足栈桢深度的要求,从而中断程序运行线程并进入调试器线程。
类似地,还可以通过修改最大调试栈桢深度和最小调试栈桢深度的方式来实现continue等其他行进命令,在此不作限制。
在本说明书一个或多个实施例中,调试命令还可以包括查看命令,以在调试过程中查看相应的变量等信息。如图5所示,根据调试命令,结合函数列表信息和映射信息对智能合约进行调试可以包括在调试器线程中执行以下操作:
步骤S772,确定在获取到查看指令时的当前运行位置所对应的当前函数在字节码形式的函数调用栈中的桢地址;
步骤S774,根据当前函数的桢地址筛选出包含当前运行位置的指令的变量,并确定与查看命令相应的待查看变量的索引;以及
步骤S776,根据当前函数的桢地址和待查看变量的索引,结合函数列表信息和映射信息获取源码形式的待查看变量。
在查看变量的过程中,关键在于根据调试信息将字节码形式的函数信息、变量信息等转换为用户能够查看的源码形式的函数信息、变量信息等。
在调试器线程中,维护了字节码(例如,WASM)形式的函数调用栈,结合调试信息中的函数列表信息和映射信息,可以查看源码(高级语言)形式的函数调用栈,从而找到字节码形式的函数调用栈中的每一项字节码形式的函数所对应的源码形式的函数。
函数调用栈中的每一帧除了包含本桢的字节码形式的函数信息,还包含了本桢当前执行的指令位置,可以根据调试信息文件中的当前桢函数的地址信息,筛选出函数或变量的词法作用域包含这个指令位置的变量,即为本桢当前可见的局部变量列表。在获取变量值时,可以从函数调用栈中获取到此桢函数的桢地址以及这个变量在字节码形式的函数中的局部变量的索引i,然后由虚拟机提供获取函数栈桢第i个变量的值的方式。在调试信息文件中包含变量的类型,可以根据变量类型判断要读取的内存中的数据范围以及解析和显示方式。
在本说明书一个或多个实施例的调试方法中,在即时编译之前修改字节码程序文件,以注入与调试处理相关联的程序指令(例如,包括用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令等),从而避免了对原有的即时编译和运行字节码程序文件的编译器或运行逻辑的影响。在本说明书一个或多个实施例的调试方法中,也无需额外提供解释器,从而避免了解释器与编译器实现代码不一样所导致的运行逻辑不一致的风险。此外,对修改所得的第二字节码程序文件进行即时编译,最终执行的还是从字节码编译所得到的机器码,从理论上,运行效率也远高于以解释运行的方式来进行调试。本说明书一个或多个实施例的调试方法中,不需要维护源码到机器码的映射信息,而仅需要维护源码到字节码的映射信息,从而简化了维护难度。本说明书一个或多个实施例的调试方法中,通过先对字节码程序文件进行修改,然后再以即时编译的方式来运行修改的字节码程序文件,以实现断点调试,并在运行时根据调试信息以及函数调用栈反推出源码(高级语言)形式的函数调用栈,这种方式不会影响智能合约的源码本身的运行时逻辑,有助于改善调试的可靠性和效率。
在本公开的一个或多个实施例中,还提出了一种用于智能合约的调试设备910。如图6所示,该调试设备可以包括处理器911和存储器913,存储器913上存储有指令,当指令被处理器911执行时,实现如上所述的调试方法的步骤。
具体地,处理器911可以是一种集成电路芯片,具有信号的处理能力。上述处理器可以是通用处理器、数字信号处理器(DSP)、专用集成电路(ASIC)、现成可编程门阵列(FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。可以实现或者执行本公开实施例中公开的各种方法、步骤及逻辑框图。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等,可以是X86架构或者是ARM架构等。
存储器913可以是易失性存储器或非易失性存储器,或可包括易失性和非易失性存储器两者。非易失性存储器可以是只读存储器(ROM)、可编程只读存储器(PROM)、可擦除可编程只读存储器(EPROM)、电可擦除可编程只读存储器(EEPROM)或闪存。易失性存储器可以是随机存取存储器(RAM),其用作外部高速缓存。通过示例性但不是限制性说明,许多形式的RAM可用,例如静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、同步动态随机存取存储器(SDRAM)、双倍数据速率同步动态随机存取存储器(DDRSDRAM)、增强型同步动态随机存取存储器(ESDRAM)、同步连接动态随机存取存储器(SLDRAM)和直接内存总线随机存取存储器(DR RAM)。应注意,本文描述的方法的存储器旨在包括但不限于这些和任意其它适合类型的存储器。
在本公开的一个或多个实施例中,还提出了一种用于智能合约的调试系统。如图7所示,该调试系统可以包括虚拟机930,该虚拟机930可以包括:
获取模块931,获取模块931可以被配置为获取智能合约的包括调试信息的第一字节码程序文件,或者获取智能合约的第一字节码程序文件以及包括调试信息的调试信息文件,其中,调试信息包括智能合约的源码与字节码之间的映射信息以及函数列表信息;
修改模块932,修改模块932可以被配置为对第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件,并相应地修改映射信息,其中,中断处理函数用于确定是否在其所在的当前运行位置处中断运行,堆栈维护函数用于记录在其所在的当前运行位置处的函数调用状态;
编译模块933,编译模块933可以被配置为在虚拟机中对第二字节码程序文件进行编译,以产生机器码程序文件;以及
执行模块934,执行模块934可以被配置为根据获取模块931获取的断点信息和调试命令,以调试状态来执行机器码程序文件,并结合函数列表信息和映射信息对智能合约进行调试。
在一些实施例中,虚拟机930可以为WASM虚拟机,且第一字节码程序文件和第二字节码程序文件均为WASM文件。
在一些实施例中,修改模块932可以包括:
第一划分单元,第一划分单元被配置为将第一字节码程序文件划分成一个或多个函数;
第二划分单元,第二划分单元被配置为将一个或多个函数中的每个函数分别划分成一个或多个基本块,使得该函数中的每条指令被包括且仅被包括在一个或多个基本块中的相应的一个基本块中,其中,每个基本块包括一条或多条指令,且一旦基本块被运行,包含在该基本块中的所有的指令被全部运行;以及
指令写入单元,指令写入单元被配置为在函数中的每个基本块的头部加入第一指令。
在一些实施例中,第二划分单元可以被配置为执行以下操作:
查找函数中的所有非线性运行指令;以及
根据查找到的非线性运行指令,将函数划分成一个或多个基本块,其中,每个非线性运行指令为其所在的基本块中的最后一条指令。
在一些实施例中,指令写入单元还可以被配置为在一个或多个函数中的每个函数的所有入口和出口之前加入第二指令。
在一些实施例中,修改模块932还可以被配置为执行以下操作:
将映射信息中的智能合约的源码与第一字节码程序文件的字节码之间的第一映射关系修改为智能合约的源码与第二字节码程序文件的字节码之间的第二映射关系。
在一些实施例中,编译模块933可以为即时编译模块。
在一些实施例中,获取模块931还可以被配置为获取来自用户的断点信息;
执行模块934可以被配置为执行以下操作:
在虚拟机中运行机器码程序文件,直至中断处理函数基于断点信息使虚拟机的程序运行线程中断并处于调试器线程中;
在调试器线程中获取来自用户的调试命令;以及
根据调试命令,结合函数列表信息和映射信息对智能合约进行调试。
在一些实施例中,第二字节码程序文件中的与每个第一指令相关联的程序块分别具有唯一地表示该程序块的程序块标识以及用于确定在该程序块处是否要中断的中断指示标识,且所有程序块的程序块标识及其相应的中断指示标识被记录在断点信息位图中。
在一些实施例中,中断处理函数可以被配置为在虚拟机930的调试器线程中执行以下操作:
读取断点信息位图中的当前程序块的相应的中断指示标识;
当根据中断指示标识确定在当前程序块处要中断时,使虚拟机处于调试器线程中;以及
当根据中断指示标识确定在当前程序块处不要中断时,使虚拟机处于程序运行线程中,直至运行到与下一个第一指令相关联的程序块,并返回读取断点信息位图中的当前程序块的相应的中断指示标识的步骤。
在一些实施例中,当虚拟机930获取到来自用户的修改的断点信息时,相应地修改断点信息位图。
在一些实施例中,堆栈维护函数可以被配置为在虚拟机的调试器线程中执行以下操作:
在当前运行位置为函数的入口时,向函数调用栈压栈与当前运行位置相关联的记录;以及
在当前运行位置为函数的出口时,从函数调用栈出栈与当前运行位置相关联的记录。
在一些实施例中,调试命令可以包括行进命令,执行模块934可以被配置为执行以下操作:
在调试器线程中记录在获取到行进命令时的函数调用栈的栈桢深度;
在调试器线程中根据所记录的栈桢深度和行进命令来修改最大调试栈桢深度和最小调试栈桢深度,其中,虚拟机的程序运行线程仅在当前栈桢深度大于或等于最小调试栈桢深度、且小于或等于最大调试栈桢深度的情况下运行;以及
中断调试器线程并进入程序运行线程以运行机器码程序文件,直至程序运行线程基于所修改的最小调试栈桢深度和最大调试栈桢深度再次中断并重新进入调试器线程。
在一些实施例中,当所记录的栈桢深度为n、行进命令为step over命令时,最小调试栈桢深度被修改为(n+1),最大调试栈桢深度被修改为对应于无穷大,其中,step over命令用于使程序运行线程在进行到对应于第二字节码程序文件中的下一个要中断的位置处中断,或使程序运行线程在进行到对应于智能合约的源码中的不是调用当前函数的子函数的下一条指令时中断,或使程序运行线程进行到引用当前函数的上一级父函数时中断。
在一些实施例中,当所记录的栈桢深度为n、行进命令为step out命令时,最小调试栈桢深度被修改为n,最大调试栈桢深度被修改为对应于无穷大,其中,step out命令用于使程序运行线程在进行到对应于第二字节码程序文件中的下一个要中断的位置处中断,或使程序运行线程进行到引用当前函数的上一级父函数时中断。
在一些实施例中,当行进命令为step in命令时,最小调试栈桢深度被修改为大于最大调试栈桢深度,其中,step in命令用于使程序运行线程单步进行到对应于智能合约的源码中的当前函数的下一条指令时中断,或使程序运行线程进行到被当前函数引用的下一级子函数时中断。
在一些实施例中,调试命令可以包括查看命令,执行模块934可以被配置为执行以下操作:
确定在获取到查看指令时的当前运行位置所对应的当前函数在字节码形式的函数调用栈中的桢地址;
根据当前函数的桢地址筛选出包含当前运行位置的指令的变量,并确定与查看命令相应的待查看变量的索引;以及
根据当前函数的桢地址和待查看变量的索引,结合函数列表信息和映射信息获取源码形式的待查看变量。
在20世纪90年代,对于一个技术的改进可以很明显地区分是硬件上的改进(例如,对二极管、晶体管、开关等电路结构的改进)还是软件上的改进(对于方法流程的改进)。然而,随着技术的发展,当今的很多方法流程的改进已经可以视为硬件电路结构的直接改进。设计人员几乎都通过将改进的方法流程编程到硬件电路中来得到相应的硬件电路结构。因此,不能说一个方法流程的改进就不能用硬件实体模块来实现。例如,可编程逻辑器件(Programmable Logic Device,PLD)(例如现场可编程门阵列(Field Programmable GateArray,FPGA))就是这样一种集成电路,其逻辑功能由使用者对器件编程来确定。由设计人员自行编程来把一个数字系统“集成”在一片PLD上,而不需要请芯片制造厂商来设计和制作专用的集成电路芯片。而且,如今,取代手工地制作集成电路芯片,这种编程也多半改用“逻辑编译器(logic compiler)”软件来实现,它与程序开发撰写时所用的软件编译器相类似,而要编译之前的原始代码也得用特定的编程语言来撰写,此称之为硬件描述语言(Hardware Description Language,HDL),而HDL也并非仅有一种,而是有许多种,如ABEL(Advanced Boolean Expression Language)、AHDL(Altera Hardware DescriptionLanguage)、Confluence、CUPL(Cornell University Programming Language)、HDCal、JHDL(Java Hardware Description Language)、Lava、Lola、MyHDL、PALASM、RHDL(RubyHardware Description Language)等,目前最普遍使用的是VHDL(Very-High-SpeedIntegrated Circuit Hardware Description Language)与Verilog。本领域技术人员也应该清楚,只需要将方法流程用上述几种硬件描述语言稍作逻辑编程并编程到集成电路中,就可以很容易得到实现该逻辑方法流程的硬件电路。
控制器可以按任何适当的方式实现,例如,控制器可以采取例如微处理器或处理器以及存储可由该(微)处理器执行的计算机可读程序代码(例如软件或固件)的计算机可读介质、逻辑门、开关、专用集成电路(Application Specific Integrated Circuit,ASIC)、可编程逻辑控制器和嵌入微控制器的形式,控制器的例子包括但不限于以下微控制器:ARC 625D、Atmel AT91SAM、Microchip PIC18F26K20以及Silicone Labs C8051F320,存储器控制器还可以被实现为存储器的控制逻辑的一部分。本领域技术人员也知道,除了以纯计算机可读程序代码方式实现控制器以外,完全可以通过将方法步骤进行逻辑编程来使得控制器以逻辑门、开关、专用集成电路、可编程逻辑控制器和嵌入微控制器等的形式来实现相同功能。因此这种控制器可以被认为是一种硬件部件,而对其内包括的用于实现各种功能的装置也可以视为硬件部件内的结构。或者甚至,可以将用于实现各种功能的装置视为既可以是实现方法的软件模块又可以是硬件部件内的结构。
上述实施例阐明的系统、装置、模块或单元,具体可以由计算机芯片或实体实现,或者由具有某种功能的产品来实现。一种典型的实现设备为服务器系统。当然,本申请不排除随着未来计算机技术的发展,实现上述实施例功能的计算机例如可以为个人计算机、膝上型计算机、车载人机交互设备、蜂窝电话、相机电话、智能电话、个人数字助理、媒体播放器、导航设备、电子邮件设备、游戏控制台、平板计算机、可穿戴设备或者这些设备中的任何设备的组合。
虽然本说明书一个或多个实施例提供了如实施例或流程图所述的方法操作步骤,但基于常规或者无创造性的手段可以包括更多或者更少的操作步骤。实施例中列举的步骤顺序仅仅为众多步骤执行顺序中的一种方式,不代表唯一的执行顺序。在实际中的装置或终端产品执行时,可以按照实施例或者附图所示的方法顺序执行或者并行执行(例如并行处理器或者多线程处理的环境,甚至为分布式数据处理环境)。术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、产品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、产品或者设备所固有的要素。在没有更多限制的情况下,并不排除在包括所述要素的过程、方法、产品或者设备中还存在另外的相同或等同要素。例如若使用到第一,第二等词语用来表示名称,而并不表示任何特定的顺序。
为了描述的方便,描述以上装置时以功能分为各种模块分别描述。当然,在实施本说明书一个或多个时可以把各模块的功能在同一个或多个软件和/或硬件中实现,也可以将实现同一功能的模块由多个子模块或子单元的组合实现等。以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其他的形式。
本发明是参照根据本发明实施例的方法、装置(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
在一个典型的配置中,计算设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储、石墨烯存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitory media),如调制的数据信号和载波。
本领域技术人员应明白,本说明书一个或多个实施例可提供为方法、系统或计算机程序产品。因此,本说明书一个或多个实施例可采用完全硬件实施例、完全软件实施例或结合软件和硬件方面的实施例的形式。而且,本说明书一个或多个实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本说明书一个或多个实施例可以在由计算机执行的计算机可执行指令的一般上下文中描述,例如程序模块。一般地,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、对象、组件、数据结构等等。也可以在分布式计算环境中实践本本说明书一个或多个实施例,在这些分布式计算环境中,由通过通信网络而被连接的远程处理设备来执行任务。在分布式计算环境中,程序模块可以位于包括存储设备在内的本地和远程计算机存储介质中。
本说明书中的各个实施例均采用递进的方式描述,各个实施例之间相同相似的部分互相参见即可,每个实施例重点说明的都是与其他实施例的不同之处。尤其,对于系统实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。在本说明书的描述中,参考术语“一个实施例”、“一些实施例”、“示例”、“具体示例”、或“一些示例”等的描述意指结合该实施例或示例描述的具体特征、结构、材料或者特点包含于本说明书的至少一个实施例或示例中。在本说明书中,对上述术语的示意性表述不必须针对的是相同的实施例或示例。而且,描述的具体特征、结构、材料或者特点可以在任一个或多个实施例或示例中以合适的方式结合。此外,在不相互矛盾的情况下,本领域的技术人员可以将本说明书中描述的不同实施例或示例以及不同实施例或示例的特征进行结合和组合。
以上所述仅为本说明书一个或多个实施例的实施例而已,并不用于限制本本说明书一个或多个实施例。对于本领域技术人员来说,本说明书一个或多个实施例可以有各种更改和变化。凡在本说明书的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在权利要求范围之内。

Claims (40)

1.一种用于智能合约的调试方法,包括:
虚拟机获取所述智能合约的包括调试信息的第一字节码程序文件,或者所述虚拟机获取所述智能合约的第一字节码程序文件以及包括调试信息的调试信息文件,其中,所述调试信息包括所述智能合约的源码与字节码之间的映射信息以及函数列表信息;
在所述虚拟机中对所述第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件,并相应地修改所述映射信息,其中,所述中断处理函数用于确定是否在其所在的当前运行位置处中断运行,所述堆栈维护函数用于记录在其所在的当前运行位置处的函数调用状态;
在所述虚拟机中对所述第二字节码程序文件进行编译,以产生机器码程序文件;以及
根据所述虚拟机获取的断点信息和调试命令,在所述虚拟机中以调试状态来执行所述机器码程序文件,并结合所述函数列表信息和所述映射信息对所述智能合约进行调试。
2.根据权利要求1所述的调试方法,其中,所述虚拟机为WASM虚拟机,且所述第一字节码程序文件和所述第二字节码程序文件均为WASM文件。
3.根据权利要求1所述的调试方法,其中,所述映射信息包括所述智能合约的源码的行号与相应的字节码的行号之间的映射关系。
4.根据权利要求1所述的调试方法,其中,所述函数列表信息包括所述智能合约中的函数的名称、函数的词法作用域、变量的名称、变量的数据类型、变量的词法作用域、变量的索引、参数的名称和参数的索引中的至少一者。
5.根据权利要求1所述的调试方法,其中,在所述虚拟机中对所述第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件包括在所述虚拟机的调试器线程中执行以下操作:
将所述第一字节码程序文件划分成一个或多个函数;
针对所述一个或多个函数中的每个函数,分别执行以下操作:
将函数划分成一个或多个基本块,使得该函数中的每条指令被包括且仅被包括在所述一个或多个基本块中的相应的一个基本块中,其中,每个基本块包括一条或多条指令,且一旦基本块被运行,包含在该基本块中的所有的指令被全部运行;以及
在函数中的每个基本块的头部加入所述第一指令。
6.根据权利要求5所述的调试方法,其中,将函数划分成一个或多个基本块,使得该函数中的每条指令被包括且仅被包括在所述一个或多个基本块中的相应的一个基本块中包括:
查找函数中的所有非线性运行指令;以及
根据查找到的非线性运行指令,将函数划分成一个或多个基本块,其中,每个非线性运行指令为其所在的基本块中的最后一条指令。
7.根据权利要求6所述的调试方法,其中,所述非线性运行指令包括跳转指令、函数调用指令和修改变量值的存储类指令中的至少一者。
8.根据权利要求5所述的调试方法,其中,在所述虚拟机中对所述第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件还包括在所述虚拟机的调试器线程中执行以下操作:
在所述一个或多个函数中的每个函数的所有入口和出口之前加入所述第二指令。
9.根据权利要求1所述的调试方法,其中,相应地修改所述映射信息包括在所述虚拟机的调试器线程中执行以下操作:
将所述映射信息中的所述智能合约的源码与所述第一字节码程序文件的字节码之间的第一映射关系修改为所述智能合约的源码与所述第二字节码程序文件的字节码之间的第二映射关系。
10.根据权利要求1所述的调试方法,其中,在所述虚拟机中对所述第二字节码程序文件进行编译,以产生机器码程序文件包括:
所述虚拟机中的字节码编译器对所述第二字节码程序文件进行即时编译,以产生所述机器码程序文件。
11.根据权利要求1所述的调试方法,其中,根据所述虚拟机获取的断点信息和调试命令,在所述虚拟机中以调试状态来执行所述机器码程序文件,并结合所述函数列表信息和所述映射信息对所述智能合约进行调试包括:
在所述虚拟机的调试器线程中获取来自用户的断点信息;
在所述虚拟机中运行所述机器码程序文件,直至所述中断处理函数基于所述断点信息使所述虚拟机的程序运行线程中断并处于所述调试器线程中;
在所述调试器线程中获取来自用户的调试命令;以及
根据所述调试命令,结合所述函数列表信息和所述映射信息对所述智能合约进行调试。
12.根据权利要求11所述的调试方法,其中,在所述虚拟机的调试器线程中获取来自用户的断点信息包括:
在所述机器码程序文件运行之前,在所述调试器线程中获取来自用户的初始的断点信息;和/或
在所述机器码程序文件被中断时,在所述调试器线程中获取来自用户的修改的断点信息。
13.根据权利要求11所述的调试方法,其中,所述第二字节码程序文件中的与每个第一指令相关联的程序块分别具有唯一地表示该程序块的程序块标识以及用于确定在该程序块处是否要中断的中断指示标识,且所有程序块的程序块标识及其相应的中断指示标识被记录在断点信息位图中。
14.根据权利要求13所述的调试方法,其中,所述中断处理函数被配置为在所述虚拟机的调试器线程中执行以下操作:
读取所述断点信息位图中的当前程序块的相应的中断指示标识;
当根据所述中断指示标识确定在当前程序块处要中断时,使所述虚拟机处于所述调试器线程中;以及
当根据所述中断指示标识确定在当前程序块处不要中断时,使所述虚拟机处于所述程序运行线程中,直至运行到与下一个第一指令相关联的程序块,并返回读取所述断点信息位图中的当前程序块的相应的中断指示标识的步骤。
15.根据权利要求13所述的调试方法,其中,当所述虚拟机获取到来自用户的修改的断点信息时,相应地修改所述断点信息位图。
16.根据权利要求11所述的调试方法,其中,所述堆栈维护函数被配置为在所述虚拟机的调试器线程中执行以下操作:
在当前运行位置为函数的入口时,向函数调用栈压栈与当前运行位置相关联的记录;以及
在当前运行位置为函数的出口时,从所述函数调用栈出栈与当前运行位置相关联的记录。
17.根据权利要求16所述的调试方法,其中,与当前运行位置相关联的记录包括当前运行位置处的指令的行号。
18.根据权利要求16所述的调试方法,其中,所述调试命令包括行进命令,根据所述调试命令,结合所述函数列表信息和所述映射信息对所述智能合约进行调试包括:
在所述调试器线程中记录在获取到所述行进命令时的函数调用栈的栈桢深度;
在所述调试器线程中根据所记录的栈桢深度和所述行进命令来修改最大调试栈桢深度和最小调试栈桢深度,其中,所述虚拟机的程序运行线程仅在当前栈桢深度大于或等于最小调试栈桢深度、且小于或等于最大调试栈桢深度的情况下运行;以及
中断所述调试器线程并进入所述程序运行线程以运行所述机器码程序文件,直至所述程序运行线程基于所修改的最小调试栈桢深度和最大调试栈桢深度再次中断并重新进入所述调试器线程。
19.根据权利要求18所述的调试方法,其中,当所记录的栈桢深度为n、所述行进命令为step over命令时,最小调试栈桢深度被修改为(n+1),最大调试栈桢深度被修改为对应于无穷大,其中,所述step over命令用于使所述程序运行线程在进行到对应于所述第二字节码程序文件中的下一个要中断的位置处中断,或使所述程序运行线程在进行到对应于智能合约的源码中的不是调用当前函数的子函数的下一条指令时中断,或使所述程序运行线程进行到引用当前函数的上一级父函数时中断。
20.根据权利要求18所述的调试方法,其中,当所记录的栈桢深度为n、所述行进命令为step out命令时,最小调试栈桢深度被修改为n,最大调试栈桢深度被修改为对应于无穷大,其中,所述step out命令用于使所述程序运行线程在进行到对应于所述第二字节码程序文件中的下一个要中断的位置处中断,或使所述程序运行线程进行到引用当前函数的上一级父函数时中断。
21.根据权利要求18所述的调试方法,其中,当所述行进命令为step in命令时,最小调试栈桢深度被修改为大于最大调试栈桢深度,其中,所述step in命令用于使所述程序运行线程单步进行到对应于所述智能合约的源码中的当前函数的下一条指令时中断,或使所述程序运行线程进行到被当前函数引用的下一级子函数时中断。
22.根据权利要求16所述的调试方法,其中,所述调试命令包括查看命令,根据所述调试命令,结合所述函数列表信息和所述映射信息对所述智能合约进行调试包括在所述调试器线程中执行以下操作:
确定在获取到所述查看指令时的当前运行位置所对应的当前函数在字节码形式的函数调用栈中的桢地址;
根据当前函数的桢地址筛选出包含当前运行位置的指令的变量,并确定与所述查看命令相应的待查看变量的索引;以及
根据当前函数的桢地址和待查看变量的索引,结合所述函数列表信息和所述映射信息获取源码形式的待查看变量。
23.一种用于智能合约的调试设备,包括处理器和存储器,所述存储器上存储有指令,当所述指令被所述处理器执行时,实现如权利要求1至22中任一项所述的调试方法的步骤。
24.一种用于智能合约的调试系统,包括虚拟机,所述虚拟机包括:
获取模块,所述获取模块被配置为获取所述智能合约的包括调试信息的第一字节码程序文件,或者获取所述智能合约的第一字节码程序文件以及包括调试信息的调试信息文件,其中,所述调试信息包括所述智能合约的源码与字节码之间的映射信息以及函数列表信息;
修改模块,所述修改模块被配置为对所述第一字节码程序文件进行修改,以产生包含用于调用中断处理函数的第一指令和用于调用堆栈维护函数的第二指令的第二字节码程序文件,并相应地修改所述映射信息,其中,所述中断处理函数用于确定是否在其所在的当前运行位置处中断运行,所述堆栈维护函数用于记录在其所在的当前运行位置处的函数调用状态;
编译模块,所述编译模块被配置为在所述虚拟机中对所述第二字节码程序文件进行编译,以产生机器码程序文件;以及
执行模块,所述执行模块被配置为根据所述获取模块获取的断点信息和调试命令,以调试状态来执行所述机器码程序文件,并结合所述函数列表信息和所述映射信息对所述智能合约进行调试。
25.根据权利要求24所述的调试系统,其中,所述虚拟机为WASM虚拟机,且所述第一字节码程序文件和所述第二字节码程序文件均为WASM文件。
26.根据权利要求24所述的调试系统,其中,所述修改模块包括:
第一划分单元,所述第一划分单元被配置为将所述第一字节码程序文件划分成一个或多个函数;
第二划分单元,所述第二划分单元被配置为将所述一个或多个函数中的每个函数分别划分成一个或多个基本块,使得该函数中的每条指令被包括且仅被包括在所述一个或多个基本块中的相应的一个基本块中,其中,每个基本块包括一条或多条指令,且一旦基本块被运行,包含在该基本块中的所有的指令被全部运行;以及
指令写入单元,所述指令写入单元被配置为在函数中的每个基本块的头部加入所述第一指令。
27.根据权利要求26所述的调试系统,其中,所述第二划分单元被配置为执行以下操作:
查找函数中的所有非线性运行指令;以及
根据查找到的非线性运行指令,将函数划分成一个或多个基本块,其中,每个非线性运行指令为其所在的基本块中的最后一条指令。
28.根据权利要求26所述的调试系统,其中,所述指令写入单元还被配置为在所述一个或多个函数中的每个函数的所有入口和出口之前加入所述第二指令。
29.根据权利要求24所述的调试系统,其中,所述修改模块还被配置为执行以下操作:
将所述映射信息中的所述智能合约的源码与所述第一字节码程序文件的字节码之间的第一映射关系修改为所述智能合约的源码与所述第二字节码程序文件的字节码之间的第二映射关系。
30.根据权利要求24所述的调试系统,其中,所述编译模块为即时编译模块。
31.根据权利要求24所述的调试系统,其中,所述获取模块还被配置为获取来自用户的断点信息;
所述执行模块被配置为执行以下操作:
在所述虚拟机中运行所述机器码程序文件,直至所述中断处理函数基于所述断点信息使所述虚拟机的程序运行线程中断并处于所述调试器线程中;
在所述调试器线程中获取来自用户的调试命令;以及
根据所述调试命令,结合所述函数列表信息和所述映射信息对所述智能合约进行调试。
32.根据权利要求24所述的调试系统,其中,所述第二字节码程序文件中的与每个第一指令相关联的程序块分别具有唯一地表示该程序块的程序块标识以及用于确定在该程序块处是否要中断的中断指示标识,且所有程序块的程序块标识及其相应的中断指示标识被记录在断点信息位图中。
33.根据权利要求32所述的调试系统,其中,所述中断处理函数被配置为在所述虚拟机的调试器线程中执行以下操作:
读取所述断点信息位图中的当前程序块的相应的中断指示标识;
当根据所述中断指示标识确定在当前程序块处要中断时,使所述虚拟机处于所述调试器线程中;以及
当根据所述中断指示标识确定在当前程序块处不要中断时,使所述虚拟机处于所述程序运行线程中,直至运行到与下一个第一指令相关联的程序块,并返回读取所述断点信息位图中的当前程序块的相应的中断指示标识的步骤。
34.根据权利要求32所述的调试方法,其中,当所述虚拟机获取到来自用户的修改的断点信息时,相应地修改所述断点信息位图。
35.根据权利要求24所述的调试方法,其中,所述堆栈维护函数被配置为在所述虚拟机的调试器线程中执行以下操作:
在当前运行位置为函数的入口时,向函数调用栈压栈与当前运行位置相关联的记录;以及
在当前运行位置为函数的出口时,从所述函数调用栈出栈与当前运行位置相关联的记录。
36.根据权利要求35所述的调试方法,其中,所述调试命令包括行进命令,所述执行模块被配置为执行以下操作:
在所述调试器线程中记录在获取到所述行进命令时的函数调用栈的栈桢深度;
在所述调试器线程中根据所记录的栈桢深度和所述行进命令来修改最大调试栈桢深度和最小调试栈桢深度,其中,所述虚拟机的程序运行线程仅在当前栈桢深度大于或等于最小调试栈桢深度、且小于或等于最大调试栈桢深度的情况下运行;以及
中断所述调试器线程并进入所述程序运行线程以运行所述机器码程序文件,直至所述程序运行线程基于所修改的最小调试栈桢深度和最大调试栈桢深度再次中断并重新进入所述调试器线程。
37.根据权利要求36所述的调试方法,其中,当所记录的栈桢深度为n、所述行进命令为step over命令时,最小调试栈桢深度被修改为(n+1),最大调试栈桢深度被修改为对应于无穷大,其中,所述step over命令用于使所述程序运行线程在进行到对应于所述第二字节码程序文件中的下一个要中断的位置处中断,或使所述程序运行线程在进行到对应于智能合约的源码中的不是调用当前函数的子函数的下一条指令时中断,或使所述程序运行线程进行到引用当前函数的上一级父函数时中断。
38.根据权利要求36所述的调试方法,其中,当所记录的栈桢深度为n、所述行进命令为step out命令时,最小调试栈桢深度被修改为n,最大调试栈桢深度被修改为对应于无穷大,其中,所述step out命令用于使所述程序运行线程在进行到对应于所述第二字节码程序文件中的下一个要中断的位置处中断,或使所述程序运行线程进行到引用当前函数的上一级父函数时中断。
39.根据权利要求36所述的调试方法,其中,当所述行进命令为step in命令时,最小调试栈桢深度被修改为大于最大调试栈桢深度,其中,所述step in命令用于使所述程序运行线程单步进行到对应于所述智能合约的源码中的当前函数的下一条指令时中断,或使所述程序运行线程进行到被当前函数引用的下一级子函数时中断。
40.根据权利要求16所述的调试方法,其中,所述调试命令包括查看命令,所述执行模块被配置为执行以下操作:
确定在获取到所述查看指令时的当前运行位置所对应的当前函数在字节码形式的函数调用栈中的桢地址;
根据当前函数的桢地址筛选出包含当前运行位置的指令的变量,并确定与所述查看命令相应的待查看变量的索引;以及
根据当前函数的桢地址和待查看变量的索引,结合所述函数列表信息和所述映射信息获取源码形式的待查看变量。
CN202111655712.3A 2021-12-30 2021-12-30 用于智能合约的调试方法、调试设备和调试系统 Pending CN114327776A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202111655712.3A CN114327776A (zh) 2021-12-30 2021-12-30 用于智能合约的调试方法、调试设备和调试系统

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202111655712.3A CN114327776A (zh) 2021-12-30 2021-12-30 用于智能合约的调试方法、调试设备和调试系统

Publications (1)

Publication Number Publication Date
CN114327776A true CN114327776A (zh) 2022-04-12

Family

ID=81019644

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202111655712.3A Pending CN114327776A (zh) 2021-12-30 2021-12-30 用于智能合约的调试方法、调试设备和调试系统

Country Status (1)

Country Link
CN (1) CN114327776A (zh)

Cited By (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN115357342A (zh) * 2022-08-23 2022-11-18 北京火山引擎科技有限公司 冷启动资源处理方法及装置
CN116205783A (zh) * 2023-04-24 2023-06-02 芯瞳半导体技术(山东)有限公司 一种基于gpu着色器代码的调试方法、装置及存储介质
CN117171110A (zh) * 2023-09-15 2023-12-05 北京云枢创新软件技术有限公司 一种指定目标位置的定位方法、电子设备及存储介质

Citations (10)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO1998052122A1 (en) * 1997-05-14 1998-11-19 Compuware Corporation Accurate profile and timing information for multitasking systems
US20050114683A1 (en) * 2003-11-26 2005-05-26 International Business Machines Corporation Tamper-resistant trusted java virtual machine and method of using the same
CN1783020A (zh) * 2005-09-12 2006-06-07 浙江大学 基于PowerPC体系结构的嵌入式操作系统的中断管理方法
US20130263094A1 (en) * 2012-03-29 2013-10-03 International Business Machines Corporation Setting breakpoints in optimized instructions
US20140366007A1 (en) * 2013-06-06 2014-12-11 Microsoft Corporation Debugging native code by transitioning from execution in native mode to execution in interpreted mode
CN106649009A (zh) * 2016-11-30 2017-05-10 北京中电华大电子设计有限责任公司 一种java卡字节码引用访问测试方法
CN109408373A (zh) * 2018-09-26 2019-03-01 深圳壹账通智能科技有限公司 智能合约的测试方法、计算机可读存储介质及测试终端
US20190215159A1 (en) * 2018-01-10 2019-07-11 Tmail Inc. System and computer program product for certified confidential data collaboration using blockchains
CN112905472A (zh) * 2021-03-04 2021-06-04 黑芝麻智能科技(上海)有限公司 内核调试系统及方法
CN113256296A (zh) * 2021-07-01 2021-08-13 支付宝(杭州)信息技术有限公司 智能合约执行方法、系统、装置和存储介质

Patent Citations (10)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO1998052122A1 (en) * 1997-05-14 1998-11-19 Compuware Corporation Accurate profile and timing information for multitasking systems
US20050114683A1 (en) * 2003-11-26 2005-05-26 International Business Machines Corporation Tamper-resistant trusted java virtual machine and method of using the same
CN1783020A (zh) * 2005-09-12 2006-06-07 浙江大学 基于PowerPC体系结构的嵌入式操作系统的中断管理方法
US20130263094A1 (en) * 2012-03-29 2013-10-03 International Business Machines Corporation Setting breakpoints in optimized instructions
US20140366007A1 (en) * 2013-06-06 2014-12-11 Microsoft Corporation Debugging native code by transitioning from execution in native mode to execution in interpreted mode
CN106649009A (zh) * 2016-11-30 2017-05-10 北京中电华大电子设计有限责任公司 一种java卡字节码引用访问测试方法
US20190215159A1 (en) * 2018-01-10 2019-07-11 Tmail Inc. System and computer program product for certified confidential data collaboration using blockchains
CN109408373A (zh) * 2018-09-26 2019-03-01 深圳壹账通智能科技有限公司 智能合约的测试方法、计算机可读存储介质及测试终端
CN112905472A (zh) * 2021-03-04 2021-06-04 黑芝麻智能科技(上海)有限公司 内核调试系统及方法
CN113256296A (zh) * 2021-07-01 2021-08-13 支付宝(杭州)信息技术有限公司 智能合约执行方法、系统、装置和存储介质

Cited By (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN115357342A (zh) * 2022-08-23 2022-11-18 北京火山引擎科技有限公司 冷启动资源处理方法及装置
CN115357342B (zh) * 2022-08-23 2024-05-28 北京火山引擎科技有限公司 冷启动资源处理方法及装置
CN116205783A (zh) * 2023-04-24 2023-06-02 芯瞳半导体技术(山东)有限公司 一种基于gpu着色器代码的调试方法、装置及存储介质
CN116205783B (zh) * 2023-04-24 2023-08-18 芯瞳半导体技术(山东)有限公司 一种基于gpu着色器代码的调试方法、装置及存储介质
CN117171110A (zh) * 2023-09-15 2023-12-05 北京云枢创新软件技术有限公司 一种指定目标位置的定位方法、电子设备及存储介质
CN117171110B (zh) * 2023-09-15 2024-04-05 北京云枢创新软件技术有限公司 一种指定目标位置的定位方法、电子设备及存储介质

Similar Documents

Publication Publication Date Title
CN111770113B (zh) 一种执行智能合约的方法、区块链节点和节点设备
CN114327776A (zh) 用于智能合约的调试方法、调试设备和调试系统
CN107644286B (zh) 工作流处理方法及装置
CN105723341B (zh) 用于布局引擎和脚本引擎的存储器模型的实现方法及系统
TWI536263B (zh) 將作業系統之原始應用程式介面投射至其它程式語言
CN100462920C (zh) 为优化的程序生成展开信息
CN109117164B (zh) 基于关键元素差异性分析的微服务更新方法及系统
CN109032631B (zh) 应用程序补丁包获取方法、装置、计算机设备及存储介质
CN105683924A (zh) 通过从在本机模式中执行转变为在经解释的模式中执行来调试本机代码
CN109101237A (zh) 代码的加密编译方法及装置
CN106909498A (zh) 一种Java程序注入故障的方法和系统
CN108614702B (zh) 字节码优化方法及装置
CN115495087A (zh) 一种区块链中实现反射机制的方法、编译方法和编译器、Wasm虚拟机
CN106293669A (zh) 一种网页组件的生成方法和装置
CN112685030A (zh) 一种生成业务代码的方法、装置、存储介质及电子设备
CN109284222B (zh) 软件单元、数据处理系统中的项目测试方法、装置及设备
US9454382B2 (en) Verification of UML state machines
CN116610568A (zh) 一种识别代码的依赖关系的方法、装置、设备及介质
CN105005497A (zh) 一种Java卡虚拟机中本地函数的调用方法及装置
CN114327759A (zh) 区块链数据的处理方法及装置
CN109409037B (zh) 一种数据混淆规则的生成方法、装置及设备
WO2017076244A1 (zh) 一种动态修复应用程序的方法、装置及相关系统
CN112711427A (zh) 一种镜像文件的获取方法以及装置
CN115048083A (zh) 组件的可视化方法、装置、存储介质及电子设备
CN109960497A (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