本申请涉及嵌入式系统技术领域,尤其涉及一种内核态程序的断点处理方法及装置。
背景技术:
在运行基于armv8指令集架构的linux操作系统的电子设备中,各类应用程序一般要调用内核态程序及资源才能实现预期功能。在这类电子设备内核态程序的开发调试过程中,通常需要对内核态程序设置断点以便检查程序运行的中间状态。
在相关技术中,通常采用基于jtag(jointtestactiongroup,联合测试工作组)接口的硬件仿真器进行断点设置:使用专用的硬件仿真器,将运行ide(integrateddevelopmentenvironment,集成开发环境)的调试主机与待调试的电子设备相连接,用上述调试主机控制设置断点并进行程序调试;或利用cpu(centralprocessingunit,中央处理器)内置的硬件断点功能:待调试电子设备的cpu通常具有内置的硬件断点资源供用户使用。
然而,一方面,采用基于jtag接口的硬件仿真器,不仅仿真器硬件及调试主机等额外设备会增加调试成本,而且还要在待调试电子设备上预留专用接口,导致使用不便;另一方面,cpu内置的硬件断点资源数量有限且形式固定,常常无法满足调试需求;因此,相关技术中的断点处理方法普遍效率较低。
技术实现要素:
有鉴于此,本申请提供一种内核态程序的断点处理方法及装置,以在降低调试成本的同时提高断点设置的灵活性,最终提高断点处理效率。
为实现上述目的,本申请提供技术方案如下:
根据本申请的第一方面,提出了一种内核态程序的断点处理方法,应用于运行linux操作系统的电子设备,所述方法包括:
运行内核态程序,所述内核态程序中位于第一地址的第一指令被替换为第一断点触发指令,所述第一地址和所述第一指令被关联记录于断点表的断点表项中;
在所述内核态程序执行到所述第一断点触发指令的情况下,从所述断点表项中提取所述第一指令;
将所述内核态程序中的所述第一断点触发指令恢复为所述第一指令;
根据用户发出的后续操作信号,删除所述断点表项或从所述第一指令处继续执行所述内核态程序。
根据本申请的第二方面,提出了一种内核态程序的断点处理方法,应用于运行linux操作系统的电子设备,所述方法包括:
在内核态程序运行状态下,读取接收的断点设置信号所对应第一地址处的第一指令;
将所述第一地址和所述第一指令关联记录于断点表的断点表项中;
将所述第一指令替换为第一断点触发指令,以在内核态程序执行到所述第一断点触发指令的情况下,由所述第一断点触发指令触发cpu异常,并基于所述断点表项将所述第一断点触发指令恢复为所述第一指令。
根据本申请的第三方面,提出了一种内核态程序的断点处理装置,应用于运行linux操作系统的电子设备,所述装置包括:
第一指令提取单元,用于在内核态程序执行到第一断点触发指令的情况下,在匹配于所述第一断点触发指令的断点表项中提取第一指令;其中,所述内核态程序中位于第一地址的所述第一指令被替换为所述第一断点触发指令,所述第一地址和所述第一指令被关联记录于断点表中的断点表项;
第一指令恢复单元,用于将所述内核态程序中的所述第一断点触发指令恢复为所述第一指令;
后续操作执行单元,用于根据用户发出的后续操作信号,删除所述断点表项或从所述第一指令处继续运行所述内核态程序。
根据本申请的第四方面,提出了一种内核态程序的断点处理装置,应用于运行linux操作系统的电子设备,所述装置包括:
第一指令读取单元,用于在内核态程序运行状态下,读取接收的断点设置信号所对应第一地址处的第一指令;
关联记录单元,用于将所述第一地址和所述第一指令关联记录于断点表的断点表项中;
第一指令替换单元,用于将所述第一指令替换为第一断点触发指令,以在内核态程序执行到所述第一断点触发指令的情况下,由所述第一断点触发指令触发cpu异常,并基于所述断点表项将所述第一断点触发指令恢复为所述第一指令。
根据本申请的第五方面,提出了一种电子设备,包括:
处理器;
用于存储处理器可执行指令的存储器;
其中,所述处理器被配置为实现如上述第一方面方案中任一项所述方法的步骤。
根据本申请的第六方面,提出了一种计算机可读存储介质,其上存储有计算机指令,该指令被处理器执行时实现如上述第一方面方案中任一项所述方法的步骤。
由以上技术方案可见,基于预设的断点表,将断点地址及原有指令暂存在断点表项中实现断点设置,并用断点触发指令替换断点处的原有指令;当内核态程序运行到该断点时触发cpu异常,然后从断点表项中恢复原有指令并运行以便用户查看该断点,最后根据用户的后续操作信号选择清除断点或继续执行断点后程序。显然,本申请所提方法中,上述内核态程序的断点设置及处理过程均由软件完成,除待测试电子设备本身外并不涉及额外的硬件,因此不仅测试成本低,而且无需在待测试电子设备上预留测试接口,简化了硬件配置,提高了测试操作的便利性。另外,该方法中断点数量及断点位置理论上允许用户任意设置,设置过程灵活方便且能够满足用户需求,便于提高用户的测试效率。
附图说明
为了更清楚地说明本申请实施例或相关技术中的技术方案,下面将对实施例或相关技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1是本申请一示例性实施例示出的一种内核态程序的断点设置及处理方法流程图。
图2是本申请一示例性实施例示出的一种内核态程序的断点设置方法流程图。
图3是本申请一示例性实施例示出的一种内核态程序的断点处理方法流程图。
图4是本申请一示例性实施例示出的另一种命中断点后的处理方法流程图。
图5是本申请一示例性实施例示出的一种用户选择从第一指令处继续执行内核态程序时继续设置断点的方法流程图。
图6是本申请一示例性实施例示出的另一种用户选择从第一指令处继续执行内核态程序时再次命中断点后的处理方法流程图。
图7是本申请一示例性实施例示出的一种电子设备的结构示意图。
图8是本申请一示例性实施例示出的一种内核态程序的断点处理装置的框图。
图9是本申请一示例性实施例示出的另一种内核态程序的断点处理装置的框图。
具体实施方式
这里将详细地对示例性实施例进行说明,其示例表示在附图中。下面的描述涉及附图时,除非另有表示,不同附图中的相同数字表示相同或相似的要素。以下示例性实施例中所描述的实施方式并不代表与本申请相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本申请的一些方面相一致的装置和方法的例子。
在本申请使用的术语是仅仅出于描述特定实施例的目的,而非旨在限制本申请。在本申请和所附权利要求书中所使用的单数形式的“一种”、“所述”、“上述”和“该”也旨在包括多数形式,除非上下文清楚地表示其他含义。还应当理解,本文中使用的术语“和/或”是指并包含一个或多个相关联的列出项目的任何或所有可能组合。
应当理解,尽管在本申请可能采用术语第一、第二、第三等来描述各种信息,但这些信息不应限于这些术语。这些术语仅用来将同一类型的信息彼此区分开。例如,在不脱离本申请范围的情况下,第一报文也可以被称为第二报文,类似地,第二报文也可以被称为第一报文。取决于语境,如在此所使用的词语“如果”可以被解释成为“在……时”或“当……时”或“响应于确定”。
作为支持多线程和多cpu的类unix操作系统,linux操作系统被广泛应用在各种电子设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机等。这类电子设备中运行的程序主要分为两类:内核态程序和用户态程序,通常各类用户态程序都要调用内核态程序及资源才能实现预期功能,作为系统基础的内核态程序对于电子设备的正常工作至关重要,因此在电子设备的研发阶段通常会对内核态程序进行调试。在调试过程中,调试人员(可视为电子设备的用户)可能需要随时查看程序中某指令的运行结果以便分析程序出现的问题,因此需要在内核态程序的调试过程中设置断点,并在程序运行到断点位置后进行相应的处理。
现有的断点处理方法主要有两种:一种是采用基于jtag接口的硬件仿真器进行断点设置:使用专用的硬件仿真器,将运行ide的调试主机与待调试的电子设备相连接,调试人员通过调试主机控制设置断点,并在内核态程序运行到断点之后进行查看、记录等操作,以便完成后续程序调试。另一种是利用cpu内置的硬件断点功能进行调试:通常情况下,待调试电子设备的cpu内存在厂家预置的硬件断点资源,调试人员可以直接使用这些内置断点资源对内核态程序进行调试。
然而,对于上述第一种方法,由于采用基于jtag接口的硬件仿真器,因此调试过程中还需要与调试主机进行连接才能完成调试系统的搭建,显然该方法需要额外的仿真器和调试主机等硬件设备,增加了调试成本;而且待调试电子设备上需要预置调试接口才能与仿真器相连接,因此在用户现场等很多场景下易导致使用不便。对于第二种方法,由于cpu内置的硬件断点资源数量有限且位置固定,因此可能难以满足用户的实际调试需求。
因此,本申请提出一种通过软件方法设置断点并对被命中的断点进行处理的技术方案,以解决相关技术中存在的上述不足。为对本申请进行进一步说明,提供下列实施例。显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员所获得的所有其他实施例,都应当属于本申请保护的范围。
首先需要说明的是,为避免行文繁琐,本申请中涉及到的指令保存位置仅以该指令对应的地址进行描述,实际上应该被理解为该指令保存在该地址对应的存储空间中,如“将第一指令保存在第一地址中”,应该被理解为“将第一指令保存在第一地址对应的存储空间中”。
图1是本申请一示例性实施例示出的一种内核态程序的断点设置及处理方法流程图。如图1所示,该方法可以包括以下步骤:
步骤101,根据用户发出的断点设置信号设置断点。
首先需要明确的是,在电子设备开机运行时,内核态程序进行编译并生成程序语句对应的指令,各指令存放在相应地址处。在设置断点之前,预先构建具有若干个空表项的断点表,然后根据用户发出的断点设置信号开始进行断点设置。
将断点相关信息保存在预设断点表中的空表项内,得到断点表项及该断点的索引号;然后将第一地址处原有的第一指令替换为第一断点触发指令,从而完成一个断点的设置。断点表中的一条空表项可以对应设置一个断点,因此预设的断点表中的空表项数量就等于该断点表中可设置断点的最大数量。
在一实施例中,断点设置完成后,注册对应于该断点的第一回调函数,以便后续断点被命中时调用该回调函数进行相应处理。若上述电子设备的cpu中运行的是armv8架构指令集,则上述第一回调函数可以为该架构自带的断点回调函数,当然也可以为用户在内核态程序中自定义的具有回调功能的其他函数,本申请对比并不进行限制。
步骤102,内核态程序运行过程中命中断点后,进行相应的处理。
断点设置完成后,在内核态程序的继续运行过程中,若程序运行到第一地址处,会执行该地址当前保存的第一断点触发指令,即为命中断点。断点被命中后进行相应处理,包括:从该断点对应的断点表项中提取第一指令;将内核态程序中的第一地址处保存的第一断点触发指令恢复为上述第一指令;等待用户发出后续操作信号,在接收到后续操作信号后,删除所述断点表项或从所述第一指令处继续执行所述内核态程序。
在一实施例中,与步骤101中相对应,若在断点设置完成后注册了该断点对应的第一回调函数,则在该断点被命中后,可以调用上述第一回调函数执行相应的后续处理。
上述处理完成后,将程序的控制权交还给用户,由用户进行断点检查操作。在一实施例中,用户可以查看和/或保存断点信息,如查看断点的执行次数、断点的索引号、断点对应的第一指令和/或第一地址等信息;在另一实施例中,用户可以查看和/或保存程序的当前参数值,如查看程序参数列表、某个或某类参数值等。用户在上述断点检查操作完成后,可以针对当前断点发出后续操作信号。
步骤103,等待用户发出后续操作信号,根据接收到的后续操作信号,判断进行何种后续处理。
断点处理完成后,等待用户发出后续操作信号,并在确实接收到用户发出的后续操作信号的情况下,判断该信号的类型:若用户发出的后续操作信号为继续执行信号,则转入步骤104;若用户发出的后续操作信号为删除断点信号,则转入步骤105。
在一实施例中,在“等待用户发出后续操作信号”时,只要用户不发出明确的后续操作信号,就一直等待,直到用户发出明确的后续操作信号,再进行后续操作。
在另一实施例中,可以预设等待时长,如10s、30s或1min等,若在命中断点后的预设时长内用户发出明确的后续操作信号,则判断该后续操作信号的类型;若在命中断点后的预设时长内用户未发出明确的后续操作信号,则结束等待,直接执行内核态程序中该断点后的程序或直接删除该断点。当然,在用户超时未发出后续操作信号的情况下,也可以直接删除断点表中的所有断点,或忽略所有断点重新执行内核态程序。
步骤104,从第一指令处继续执行内核态程序。
在断点被命中后的处理过程中,第一地址处的指令已经恢复为原有的第一指令,在用户发出继续执行信号的情况下,从当前断点处的第一指令开始,继续执行后续的内核态程序。
步骤105,删除断点。
用户发出的删除断点信号可能存在两种情况:删除当前断点或删除全部断点。相应的,用户发出的删除断点信号中可以携带断点索引号或全部删除标记,在接收到用户发出的删除断点信号后,判断用户发出的删除断点信号中中携带的是何种信息,分别进行不同的处理:若删除断点信号中携带的是当前断点的索引号,则删除当前断点对应的断点表项;若删除断点信号中中携带的是全部删除标记,则删除断点表中的所有断点表项。需要说明的是,上述“删除断点表项”应该被理解为清空该断点表项中的断点信息,从而将该断点表项恢复为空表项,而并非在断点表中彻底删除该表项。
利用上述断点设置及断点命中后的处理方法,用户能够基于预设置的断点表以及与之相配合的第一断点触发指令设置断点,并在断点被命中后按照用户操作进行相应处理。上述方法全部通过软件实现,无需额外硬件即可实现断点设置及处理,降低了测试成本也提高了测试的便利性;而且用户可以自由设置断点多个断点,能够更好的满足用户的测试需求。
图2是本申请一示例性实施例示出的一种内核态程序的断点设置方法流程图。该方法对应于图1中的步骤101。首先需要说明的是:在内核态程序的运行状态下,需要预先构建断点表,再根据用户发出的断点设置信号设置断点。
预先构建的断点表中包含至少一条断点表项,在未进行断点设置时,所有标项均为空表项,在空表项中记录入断点对应的指令相关信息后,该空表项即变为断点表项。每条断点表项至少包括索引号、第一指令空间(保存第一地址和第一指令)和第二指令空间(保存第二地址和第二指令),当然也可以包括其他断点信息,对此本申请并不进行限制。如图2所示,该方法可以包括以下步骤:
步骤201,根据用户发出的断点设置信号,读取相应的第一指令。
在内核态程序的运行过程中进行断点设置,需要先根据用户发出的断点设置信号获取将要设置的断点对应的指令(第一指令)及该指令保存的地址(第一地址)。用户可以采用多种方式发出断点设置信号,由于不同方式发出的断点设置信号中包含的信息不同,因此需要针对断点设置信号的不同发出方式分别进行不同的处理,以获取断点对应的第一指令。
在一实施例中,用户发出的断点设置信号中可以包含有断点对应的函数或程序语句,如用户在内核态程序的显示界面中直接选中某个函数或某条程序语句。此时根据上述函数或程序语句查询符号表,找到对应的第一地址,然后在第一地址中直接读取第一指令。
在另一实施例中,用户发出的断点设置信号中可以包含函数或程序语句的地址,如用户在断点设置窗口中输入某条程序语句的行号。此时根据上述行号查询地址表,找到对应的第一地址,然后在第一地址中直接读取第一指令。
在一实施例中,用户发出的断点设置信号中包含第一地址,如在断点设置窗口中输入某条指令的地址,此时直接在第一地址中直接读取第一指令。
在另一实施例中,用户发出的断点设置信号中包含第一指令,如在断点设置窗口中输入某条指令,此时直接将该指令作为第一指令。当然,根据内核态程序显示界面及断点设置交互方式的不同,用户发出断点设置信号可能还有其他方式,对此本申请并不进行限制。
步骤202,将第一指令和第一地址保存在空表项中,得到断点表项。
获取到第一指令及其所处的第一地址后,将包含上述第一指令及第一地址的断点信息记录在断点表中的某一空表项中,得到断点表项。根据预先构建的断点表中索引号的不同情况,上述第一指令相关信息的记录方式可能有多种,下文分别结合表1和表2对两种可能的实施例进行示例性说明:
在一实施例中,若各空表项的索引号在构建断点表时已经按顺序分配完成,则直接选择当前所有空表项的第一个空表项,并将上述第一地址与第一指令对应记录在该空表项中。以下表1所示断点表中的表项情况为例:
表1
在构建断点表时就已对各表项进行编号,即已分配索引号。当前索引号为1和2的表项已经被设置断点,均为断点表项;索引号为3的表项及其后表项尚未被设置断点,均为空表项。对于将要设置的第三个断点,将对应的第一指令i3_1和第一地址p3_1记录在上述索引号为3的空表项的第一指令空间中,得到索引号为3的断点表项。该实施例的设置方法按照断点的设置顺序依次选择空表项,使得最后设置的断点索引号与所在的断点表项的位置顺序相一致,便于后续断点被命中后的断点信息查询,从而缩短断点响应时间。
在另一实施例中,若各空表项的索引号在构建断点表时并未分配,则在当前所有空表项中选择其中一个,将上述第一地址与第一指令对应记录在该空表项中,得到断点表项,然后为该断点表项分配相应的索引号。以下表2所示断点表中的表项情况为例:
表2
在构建断点表时并未对各表项进行编号,即未分配索引号。当前索引号为1和2的表项已经被设置断点,均为断点表项;索引号为2的表项以后的所有表项尚未被设置断点,均为空表项。对于将要设置的第三个断点,将对应的第一指令i3_1和第一地址p3_1记录在第二个空表项的第一指令空间中,得到断点表项,为该断点表项分配索引号“3”。在该实施例中,可以在所有空表项中任意选择一个空表项,也可以在所有空表项中按照将要设置断点对应的程序语句在内核态程序中的位置进行选择,采用该实施例方法设置的各断点表项之间可能存在空表项,便于用户后续在已有断点之间添加新断点。
需要说明的是:上述表1和表2示出的索引号、第一指令空间和第二指令空间并不应视为三者位置关系之间的限定,三者之间的实际位置关系可以与上表所示方式不同,但无论采用何种位置关系进行保存,都应满足三者之间的映射关系。另外,上表中仅示出了三种信息,但可以理解的是:任一表项中除上述三种信息外,还可以保存对应断点的其他断点信息,如指令上下文信息、断点有效时长和/或断点类型标识等信息。
步骤203,用第一断点触发指令替换第一地址处的第一指令。
在根据第一地址读取得到第一指令后,使用第一断点触发指令替换第一地址处原有的第一指令。此处的“替换”应被理解为“写入”,即在第一地址对应的存储空间中写入第一断点触发指令;可以理解的是,第一断点触发指令被写入后,第一地址处原有的第一指令即因被覆盖而消失,相当于第一地址处保存的第一指令被替换为第一断点触发指令。
第一断点触发指令具有cpu异常触发功能,在该指令被执行到时,其会触发电子设备的cpu进入异常状态,进而引发关于断点的后续操作。
可以理解的是,上述步骤202与步骤203之间并不存在确定的前后时序关系,上述描述仅以步骤202在前,步骤203在后为例进行说明,实际上也可以先执行步骤203再执行步骤202。
步骤204,根据第一指令注册第一回调函数。
按照断点的相关信息,注册与上述第一指令对应的第一回调函数。具体的,可以根据上述断点的索引号注册第一回调函数,也可以根据上述断点对应的第一指令或第一地址注册回调函数。根据某断点注册的第一回调函数,会在该断点被命中时自动调用,以便进行相应处理。需要说明的是,步骤204为可选步骤,后续步骤402中根据是否执行步骤204分别执行不同的处理,此处不再赘述。
图3是本申请一示例性实施例示出的一种内核态程序的断点处理方法流程图。该方法对应于图1中的步骤101和步骤102。如图2所示,该方法可以包括以下步骤:
步骤301,运行内核态程序,所述内核态程序中位于第一地址的第一指令被替换为第一断点触发指令,所述第一地址和所述第一指令被关联记录于断点表的断点表项中。
步骤301对应于图1中的步骤101,步骤301的具体实现方式参见上述步骤101及步骤201-204,此处不再赘述。
步骤302,在所述内核态程序执行到所述第一断点触发指令的情况下,从所述断点表项中提取所述第一指令。
在内核态程序执行到第一断点触发指令的情况下,第一断点触发指令会触发cpu异常,相应的异常地址即为当前第一断点触发指令所在的地址,也就是其所对应断点的断点表项中保存的第一地址。
对应于前述步骤204中在断点设置阶段注册了该断点对应的第一回调函数,在一实施例中,在所述内核态程序执行到所述第一断点触发指令的情况下,cpu直接调用该断点对应的第一回调函数;然后通过该函数在断点表中查询匹配于上述第一断点触发指令的断点表项,在查询到匹配的断点表项的情况下,从该断点表项中提取其第一指令空间记录的第一指令;否则,在未查询到匹配的断点表项的情况下,提示程序执行错误。
在另一实施例中,在所述内核态程序执行到所述第一断点触发指令的情况下,cpu异常会激活系统自带的异常处理函数,然后由异常处理函数调用该断点对应的第一回调函数,后续操作同上一实施例,不再赘述。
对应于在断点设置阶段未执行注册第一回调函数的步骤204,在另一实施例中,在所述内核态程序执行到所述第一断点触发指令的情况下,直接查询匹配于上述第一断点触发指令的断点表项。由于第一断点触发指令中可能携带该指令对应断点表项中记录的索引号,所以需要对第一断点触发指令中是否携带索引号进行判断,并分别进行处理:
在一实施例中,在判断出第一断点触发指令中携带索引号的情况下,从该指令中提取其携带的上述索引号,然后在断点表中查询与该索引号相匹配的断点表项,最后在查询到的断点表项中提取其第一指令空间记录的第一指令。
在另一实施例中,在判断出第一断点触发指令中未携带索引号的情况下,先提取上述cpu异常对应的异常地址,再在断点表中查询与该异常地址相匹配的断点表项,最后在查询到的断点表项中提取其第一指令空间记录的第一指令。
步骤303,将所述内核态程序中的所述第一断点触发指令恢复为所述第一指令。
在从与被命中断点相对应的断点表项中提取出第一指令的同时,也将该第一指令对应的第一地址提取出来,然后将该提取出的上述第一指令写入上述第一地址,以替换当前第一地址所保存的第一断点触发指令,可以理解的是,第一指令被写入后,第一地址处原有的第一断点触发指令即因被覆盖而消失,相当于第一地址处当前保存的第一断点触发指令被恢复为断点设置前的第一指令。
步骤304,根据用户发出的后续操作信号,删除所述断点表项或从所述第一指令处继续执行所述内核态程序。
第一地址处的第一指令恢复完成后,等待用户发出后续操作信号,并在确实接收到用户发出的后续操作信号的情况下,判断该信号的类型:若用户发出的后续操作信号为继续执行信号,则继续顺序执行上述断点后的内核态程序;若用户发出的后续操作信号为删除断点信号,则根据删除断点信号的类型删除相应的断点表项,具体判断及删除过程详见前述步骤105,此处不再赘述。
图4是本申请一示例性实施例示出的另一种命中断点后的处理方法流程图。该方法对应于图1中的步骤102。如图4所示,该方法可以包括以下步骤:
步骤401,内核态程序执行过程中命中断点。
断点设置完成后,断点表项中保存的是断点对应的第一地址和第一指令,第一地址处保存的是第一断点触发指令。在内核态程序正常运行时,运行到第一地址处的第一断点触发指令后,该指令会触发cpu异常。
步骤402,调用第一回调函数。
由前述步骤204可知,若在断点设置阶段注册了对应于上述断点的第一回调函数,则在cpu异常之后调用该第一回调函数,并由该第一回调函数执行后续步骤403-步骤406。
显然,该步骤402是基于步骤204存在的,若在断点设置阶段未执行步骤204,即未注册与上述断点相对应的第一回调函数,则不存在该步骤402,相应的后续步骤403-步骤406由cpu执行,而非调用函数执行。
步骤403,判断第一断点触发指令中是否包含索引号。
由于第一断点触发指令中可能携带该指令对应断点表项中记录的索引号,所以需要对第一断点触发指令中是否携带索引号进行判断,并分别进行处理:在判断出第一断点触发指令中携带索引号的情况下,则转入步骤404a;否则,在判断出第一断点触发指令中未携带索引号的情况下,则转入步骤404b。
可以理解的是,上述第一断点触发指令中还可以携带断点的其他信息,如断点第一地址和/或第一指令等信息。
步骤404a,提取第一断点触发指令中携带的索引号。
从第一断点触发指令携带的断点信息中提取索引号,可以按照预设的信息保存格式,直接从第一触发指令中提取该索引号;也可以从第一触发指令中提取其携带的断点信息,然后从断点信息中解析出索引号。
步骤405a,在断点表中查询匹配于索引号的断点表项。
断点表中保存了若干条断点表项,在断点表中依次查找匹配于该索引号的断点表项。此处的“匹配”应理解为“某断点表项的索引号与上述索引号相同”。
步骤404b,提取cpu异常事件对应的异常地址。
从第一断点触发指令携带的断点信息中提取异常地址,可以按照预设的信息保存格式,直接从第一触发指令中提取该异常地址;也可以从第一触发指令中提取其携带的断点信息,然后从断点信息中解析出异常地址。
步骤405b,在断点表中查询匹配于断点地址的断点表项。
断点表中保存了若干条断点表项,在断点表中依次查找匹配于该异常地址的断点表项。此处的“匹配”应理解为“某断点表项中保存的第一地址与上述异常地址相同”。
可以理解的是,在一次计算过程中,上述步骤404a-405a与步骤404b-405b择一执行:根据步骤403的判断结果,选择执行步骤404a-405a或选择执行步骤404b-405b。下述步骤步骤604a-605a与步骤604b-605b与此相同,下文不再赘述。
步骤406,在断点表项中提取第一指令。
在查找到匹配的断点表项的情况下,在断点表项中提取第一指令。可以按照预设的信息保存格式,直接从该断点表项的第一指令空间中提取该第一指令;也可以从该断点表项中提取其第一指令空间中的所有信息,然后从上述所有信息中解析出第一指令。
步骤407,恢复第一地址处的第一指令。
在提取出第一指令后,将该第一指令写入到上述断点表项中的第一地址。由于此时上述断点表项中的第一地址即为异常地址,因此根据步骤406中第一指令的提取方式分别进行处理:
若第一指令是直接从该断点表项的第一指令空间中提取得到的,则将该第一指令写入到异常地址中;
若第一指令是从该断点表项中提取的第一指令空间的所有信息中解析得到的,则同时解析出其中的第一地址,然后将该第一指令写入到该第一地址中。
步骤408,等待用户发出的后续操作信号。
等待用户发出后续操作信号,并在确实接收到用户发出的后续操作信号的情况下,判断该信号的类型:若用户发出的后续操作信号为继续执行信号,则转入步骤104;若用户发出的后续操作信号为删除断点信号,则转入步骤105。
在一实施例中,在“等待用户发出后续操作信号”时,只要用户不发出明确的后续操作信号,就一直等待,直到用户发出明确的后续操作信号,再进行后续操作。
在另一实施例中,可以预设等待时长,如10s、30s或1min等,若在命中断点后的预设时长内用户发出明确的后续操作信号,则判断该后续操作信号的类型;若在命中断点后的预设时长内用户未发出明确的后续操作信号,则结束等待,直接执行内核态程序中该断点后的程序或直接删除该断点。当然,在用户超时未发出后续操作信号的情况下,也可以直接删除断点表中的所有断点,或跳过所有断点重新执行内核态程序。
图5是本申请一示例性实施例示出的一种用户选择从第一指令处继续执行内核态程序时继续设置断点的方法流程图。如图5所示,该方法可以包括以下步骤:
步骤501,通过第一指令获取第二指令。
在用户发出的后续操作信号为继续执行信号的情况下,即说明用户选择从第一指令处继续执行内核态程序。由于此时第一指令处的断点命中后的处理已经执行完毕,因此需要顺序执行第一指令的下一指令,即第二指令,该第二指令是基于指令执行的逻辑顺序确定出的。确定上述第二指令的方法可以有多种:
在一实施例中,通过第一指令对应程序语句的上下文关系直接解析,计算出第二指令。上述解析可以通过局部编译来实现,也可以通过查询指令记录表来实现,其中指令记录表在电子设备开机编译阶段生成,其中记录有程序中各指令的特征标记与保存地址之间的对应关系。计算得到第二指令后,获取保存该指令的第二地址。
在另一实施例中,先通过解析上述第一指令得到对应的第二地址,再在第二地址中读取其保存的第二指令。由于编译生成的各指令之间满足指令执行的逻辑顺序关系,因此能够通过解析第一指令得到满足上述逻辑顺序的下一条指令的保存地址,即第二地址。在获取到的第二地址处直接读取该地址保存的指令,即得到第二指令。
步骤502,将第二指令及第二地址记录在断点表项中。
将前述获取到的第二地址与第二指令对应记录在预先生成的断点表的第二指令空间中,具体保存方式参见表1和表2。
步骤503,使用第二断点触发指令替换第二地址处的第二指令。
将第二断点触发指令写入到第二地址处,以替换第二地址处保存的第二指令。可以理解的是,第一断点触发指令被写入后,第一地址处原有的第一指令即因被覆盖而消失,相当于第一地址处保存的第一指令被替换为第一断点触发指令。
可以理解的是,上述步骤502与步骤503之间并不存在确定的前后时序关系,上述描述仅以步骤502在前,步骤503在后为例进行说明,实际上也可以先执行步骤503再执行步骤502。
步骤504,根据第二指令注册第二回调函数。
按照断点的相关信息,注册与上述第二指令对应的第二回调函数。具体的,可以根据上述断点的索引号注册第二回调函数,也可以根据上述断点对应的第二指令或第二地址注册回调函数。根据某断点注册的第二回调函数,会在该断点被命中时自动调用,以便进行相应处理。上述第二回调函数可以为该架构自带的断点处理函数,当然也可以为用户在内核态程序中自定义的具有断点处理功能的其他函数,本申请对比并不进行限制。
需要说明的是,步骤504为可选步骤,后续步骤602中根据是否执行步骤504分别执行不同的处理,此处不再赘述。
图6是本申请一示例性实施例示出的另一种用户选择从第一指令处继续执行内核态程序时再次命中断点后的处理方法流程图。如图6所示,该方法与图4所述方法具有很多相似之处,下文仅对该方法不同于图4所述方法的步骤进行详细描述,该方法可以包括以下步骤:
步骤601,内核态程序执行过程中再次命中断点。
断点中的第二指令相关信息设置完成后,断点表项中保存有断点对应的第二地址和第二指令,第二地址处保存的是第二断点触发指令。在内核态程序执行完第一指令继续运行,执行到第二地址处的第二断点触发指令后,该指令会触发cpu再次异常。
步骤602,调用第二回调函数。
该步骤对应步骤504:若执行了步骤504,则此处调用第二指令对应的第二回调函数,并由该第二回调函数执行后续步骤603-步骤606;否则,若未执行步骤504,则直接跳过步骤602,执行步骤603。
步骤603,判断第二断点触发指令中是否包含索引号。
步骤604a,提取第二断点触发指令中携带的索引号。
步骤605a,在断点表中查询匹配于索引号的断点表项。
步骤604b,提取cpu异常事件对应的异常地址。
步骤605b,在断点表中查询匹配于断点地址的断点表项。
步骤606,在断点表项中提取第二指令。
步骤607,恢复第二地址处的第二指令。
上述步骤603-步骤607的执行对象第二指令信息,前述步骤403-步骤407的执行对象是第一指令信息,二者具体执行步骤并无区别,此处不再赘述。
步骤608,删除断点表项中的第二指令信息。
在内核态程序执行过程中,不同执行情况下(如循环的不同次数或程序的不同分支等),同一个第一指令对应的第二指令可能并不相同,因此在某一断点设置完成后直到该断点被清除的一个断点生命周期内,该断点对应断点表项中记录的第一指令信息不会改变,而其中的第二指令信息则在每次断点执行到之后都要清除,并在下次执行到的时再次进行设置。
在步骤607执行完后,针对上述断点中第二断点触发指令的相关处理即告完成,此时需要将该断点对应断点表项中的第二指令信息完全清除,即删除断点表项中的第二指令信息。可以理解的是,断点表项中的第二断点信息被删除之后,该段表项中的第二指令空间即被清空,当该断点再次被执行到,且针对第一断点触发指令的处理完成后,会再次写入新的第二指令信息。
需要说明的是,若上述电子设备的操作系统采用armv8架构指令集,则上述第一断点触发指令和第二断点触发指令可以为自带的brk指令,具体的,第一断点触发指令可以为brk0x402指令,第二断点触发指令可以为brk0x403指令;也可以第一断点触发指令可以为brk0x403指令,第二断点触发指令可以为brk0x402指令。当然二者可以也可以为具有cpu异常触发功能的其他系统指令或用户自定义函数,本申请对此并不进行限制。
图7是本申请一示例性实施例示出的一种电子设备的结构示意图。如图7所示,在硬件层面,该电子设备包括处理器701、内部总线702、网络接口703、内存704以及非易失性存储器705,当然还可能包括其他业务所需要的硬件。处理器701从非易失性存储器705中读取对应的计算机程序到内存704中并运行,在逻辑层面上形成内核态程序的断点处理装置。当然,除了软件实现方式之外,本申请并不排除其他实现方式,比如逻辑器件抑或软硬件结合的方式等等,也就是说以下处理流程的执行主体并不限定于各个逻辑单元,也可以是硬件或逻辑器件。
图8是本申请一示例性实施例示出的一种内核态程序的断点处理装置的框图。如图8所示,在软件实施方式中,该内核态程序的断点处理装置应用于运行linux操作系统的电子设备,可以包括第一提取单元801、第一恢复单元802和后续操作执行单元803。其中:
第一提取单元801,用于在内核态程序执行到第一断点触发指令的情况下,在匹配于所述第一断点触发指令的断点表项中提取第一指令;其中,所述内核态程序中位于第一地址的所述第一指令被替换为所述第一断点触发指令,所述第一地址和所述第一指令被关联记录于断点表中的断点表项;
第一恢复单元802,用于将所述内核态程序中的所述第一断点触发指令恢复为所述第一指令;
后续操作执行单元803,用于根据用户发出的后续操作信号,删除所述断点表项或从所述第一指令处继续运行所述内核态程序。
可选的,所述内核态程序的断点处理装置还包括:
第一注册单元804,在所述内核态程序中位于第一地址的第一指令被替换为第一断点触发指令后,注册匹配于所述第一断点触发指令的第一回调函数。
相应的,第一提取单元801具体用于:通过调用所述第一回调函数,在所述断点表中查询匹配于所述第一断点触发指令的断点表项,并从所述断点表项中提取所述第一指令。
可选的,在所述内核态程序执行到所述第一断点触发指令的情况下,第一恢复单元802查询所述匹配于所述第一断点触发指令的断点表项以供提取所述第一指令,具体包括:
提取cpu异常对应的异常地址,所述cpu异常在所述第一断点触发指令被执行到时由所述第一断点触发指令所触发;在所述断点表中查询匹配于所述异常地址的断点表项;
或者,从所述第一断点触发指令中提取其携带的索引号;在所述断点表中查询匹配于所述索引号的断点表项。
可选的,在用户发出的所述后续操作信号为继续执行信号的情况下,后续操作执行单元803具体用于:
通过所述第一指令获取第二指令,所述第二指令是基于指令执行逻辑顺序确定出的所述第一指令的下一条指令;
将所述第二指令和所述第二指令所处的第二地址保存在所述断点表项中;
将所述第二指令替换为第二断点触发指令;其中,在程序执行到所述第二断点触发指令的情况下,所述第二断点触发指令用于触发cpu异常。
可选的,后续操作执行单元803通过所述第一指令获取第二指令,具体包括:
解析所述第一指令得到第二地址;
读取位于所述第二地址的第二指令。
可选的,后续操作执行单元803还包括:
第二注册单元8031,用于在所述第二指令被替换为第二断点触发指令后,注册匹配于所述第二断点触发指令的第二回调函数;
第二调用单元8032,用于在cpu异常的情况下,通过调用所述第二回调函数,从匹配于所述第二断点触发指令的断点表项中提取所述第二指令,并删除所述断点表项中的所述第二地址和所述第二指令。
可选的,在cpu异常的情况下,后续操作执行单元803查询匹配于所述第二断断点触发指令的断点表项以提取所述第二指令,具体包括:
提取cpu异常对应的异常地址;在所述断点表中查询匹配于所述异常地址的断点表项;
或者,从所述第二断点触发指令中提取其携带的索引号;在所述断点表中查询匹配于所述索引号的断点表项。
图9是本申请一示例性实施例示出的另一种内核态程序的断点处理装置的框图。如图9所示,在软件实施方式中,该内核态程序的断点处理装置应用于运行linux操作系统的电子设备,可以包括第一读取单元901、关联记录单元902和第一替换单元903。其中:
第一读取单元901,用于在内核态程序运行状态下,读取接收的断点设置信号所对应第一地址处的第一指令;
关联记录单元902,用于将所述第一地址和所述第一指令关联记录于断点表的断点表项中;
第一替换单元903,用于将所述第一指令替换为第一断点触发指令,以在内核态程序执行到所述第一断点触发指令的情况下,由所述第一断点触发指令触发cpu异常,并基于所述断点表项将所述第一断点触发指令恢复为所述第一指令。
在一个典型的配置中,电子设备包括一个或多个处理器(cpu)、输入/输出接口、网络接口和内存。
内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(ram)和/或非易失性内存等形式,如只读存储器(rom)或闪存(flashram)。内存是计算机可读介质的示例。
计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(pram)、静态随机存取存储器(sram)、动态随机存取存储器(dram)、其他类型的随机存取存储器(ram)、只读存储器(rom)、电可擦除可编程只读存储器(eeprom)、快闪记忆体或其他内存技术、只读光盘只读存储器(cd-rom)、数字多功能光盘(dvd)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括暂存电脑可读媒体(transitorymedia),如调制的数据信号和载波。
对于上述装置实施例而言,由于其基本对应于方法实施例,所以相关之处参见方法实施例的部分说明即可。以上所描述的装置实施例仅仅是示意性的,其中所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本申请方案的目的。本领域普通技术人员在不付出创造性劳动的情况下,即可以理解并实施。
以上所述仅为本申请的较佳实施例而已,并不用以限制本申请,凡在本申请的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本申请保护的范围之内。