CN113220334B - 程序故障定位方法、终端设备及计算机可读存储介质 - Google Patents

程序故障定位方法、终端设备及计算机可读存储介质 Download PDF

Info

Publication number
CN113220334B
CN113220334B CN202110573162.4A CN202110573162A CN113220334B CN 113220334 B CN113220334 B CN 113220334B CN 202110573162 A CN202110573162 A CN 202110573162A CN 113220334 B CN113220334 B CN 113220334B
Authority
CN
China
Prior art keywords
function
target
program
target program
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
Application number
CN202110573162.4A
Other languages
English (en)
Other versions
CN113220334A (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.)
PAX Computer Technology Shenzhen Co Ltd
Original Assignee
PAX Computer Technology Shenzhen 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 PAX Computer Technology Shenzhen Co Ltd filed Critical PAX Computer Technology Shenzhen Co Ltd
Priority to CN202110573162.4A priority Critical patent/CN113220334B/zh
Publication of CN113220334A publication Critical patent/CN113220334A/zh
Application granted granted Critical
Publication of CN113220334B publication Critical patent/CN113220334B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/70Software maintenance or management
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/53Decompilation; Disassembly

Landscapes

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

Abstract

本申请适用于计算机技术领域,提供了一种程序故障定位方法、装置、终端设备及计算机可读存储介质,包括:当目标程序中出现死循环故障时,通过中断程序获取断点在所述目标程序中所属的第一函数;确定所述目标程序中所述第一函数对应的返回地址;根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址;根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数;根据所述第二函数定位所述目标程序的故障位置。通过上述方法,克服了现有技术中当死循环发生在公共函数时、无法获取被调用函数的上级函数的缺点,进而提高了程序死循环故障定位的准确度。

Description

程序故障定位方法、终端设备及计算机可读存储介质
技术领域
本申请属于计算机技术领域,尤其涉及一种程序故障定位方法、装置、终端设备及计算机可读存储介质。
背景技术
死循环故障是指,程序一直停留在某个状态,在约定的触发条件下,不再向预定的后续程序执行,但底层***及其输入、输出设备仍然处于正常工作或可正常工作状态。死循环故障不仅会影响程序的正常运行,还会损耗***资源。因此,排除死循环故障是亟需解决的问题。
现有技术中,通常是利用中断程序检测死循环故障,即在死循环过程中特意触发中断,通过获取中断断点的地址来判断死循环故障的位置。但是当死循环代码中含有对耗时较长的公共函数的调用时,由于中断断点的地址大概率会落在这些公共函数中、且整个程序中调用这些公共函数的地方很多,因而仍然无法明确死循环故障的准确位置。
发明内容
本申请实施例提供了一种程序故障定位方法、装置、终端设备及计算机可读存储介质,可以提高程序死循环故障定位的准确度。
第一方面,本申请实施例提供了一种程序故障定位方法,包括:
当目标程序中出现死循环故障时,通过中断程序获取断点在所述目标程序中所属的第一函数;
确定所述目标程序中所述第一函数对应的返回地址;
根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址;
根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数;
根据所述第二函数定位所述目标程序的故障位置。
在本申请实施例中,在通过中断程序确定当前发生中断的第一函数后,确定第一函数的返回地址,然后根据返回地址确定第一函数在目标程序中的相对调用地址,最后根据相对调用地址确定第一函数的上级调用函数(即第二函数)。通过上述方法,克服了现有技术中当死循环发生在公共函数时、因无法获取被调用函数的上级函数而无法确定准确的死循环部位的缺点,进而提高了程序死循环故障定位的准确度。
在第一方面的一种可能的实现方式中,所述根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址,包括:
根据所述第一函数对应的返回地址确定所述第一函数在目标内存中的绝对调用地址,所述目标内存为运行所述目标程序的操作***中用于加载所述目标程序的存储空间;
根据所述第一函数在目标内存中的绝对调用地址确定所述第一函数在所述目标程序中的相对调用地址。
在第一方面的一种可能的实现方式中,所述根据所述第一函数对应的返回地址确定所述第一函数在目标内存中的绝对调用地址,包括:
获取目标调用指令的指令长度,所述目标调用指令为所述操作***中用于调用所述第一函数的指令;
根据所述第一函数对应的返回地址和所述指令长度计算所述第一函数在所述目标内存中的绝对调用地址。
在第一方面的一种可能的实现方式中,所述根据所述第一函数在目标内存中的绝对调用地址确定所述第一函数在所述目标程序中的相对调用地址,包括:
获取所述目标内存中加载所述目标程序的起始地址;
根据所述第一函数在目标内存中的绝对调用地址和所述起始地址计算所述第一函数在所述目标程序中的相对调用地址。
在第一方面的一种可能的实现方式中,所述根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数,包括:
生成所述目标程序的反汇编代码;
在所述反汇编代码中查找所述第一函数在所述目标程序中的相对调用地址所属的目标函数;
将所述目标函数确定为所述第二函数。
在第一方面的一种可能的实现方式中,所述根据所述第二函数定位所述目标程序的故障位置,包括:
若第一函数未落在第二函数的死循环代码体内,则确定所述目标程序中所述第二函数所属的第三函数;
根据所述第三函数定位所述目标程序的故障位置,直到满足预设条件。
在第一方面的一种可能的实现方式中,所述根据所述第二函数定位所述目标程序的故障位置,包括:
若第一函数落在第二函数的死循环代码体内,则获取所述第二函数在目标内存中的绝对调用地址,所述目标内存为运行所述目标程序的操作***中用于加载所述目标程序的存储空间;
将所述第二函数在目标内存中的绝对调用地址确定所述目标程序的故障位置。
第二方面,本申请实施例提供了一种程序故障定位装置,包括:
函数获取单元,用于当目标程序中出现死循环故障时,通过中断程序获取断点在所述目标程序中所属的第一函数;
返回地址确定单元,用于确定所述目标程序中所述第一函数对应的返回地址;
调用地址确定单元,用于根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址;
函数确定单元,用于根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数;
故障定位单元,用于根据所述第二函数定位所述目标程序的故障位置。
第三方面,本申请实施例提供了一种终端设备,包括存储器、处理器以及存储在所述存储器中并可在所述处理器上运行的计算机程序,其特征在于,所述处理器执行所述计算机程序时实现如上述第一方面中任一项所述的程序故障定位方法。
第四方面,本申请实施例提供了一种计算机可读存储介质,本申请实施例提供了一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现如上述第一方面中任一项所述的程序故障定位方法。
第五方面,本申请实施例提供了一种计算机程序产品,当计算机程序产品在终端设备上运行时,使得终端设备执行上述第一方面中任一项所述的程序故障定位方法。
可以理解的是,上述第二方面至第五方面的有益效果可以参见上述第一方面中的相关描述,在此不再赘述。
附图说明
为了更清楚地说明本申请实施例中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1是本申请实施例提供的程序故障定位方法的流程示意图;
图2是本申请实施例提供的存储空间的示意图;
图3是本申请实施例提供的程序故障定位的实施流程示意图;
图4是本申请实施例提供的程序故障定位装置的结构框图;
图5是本申请实施例提供的终端设备的结构示意图。
具体实施方式
以下描述中,为了说明而不是为了限定,提出了诸如特定***结构、技术之类的具体细节,以便透彻理解本申请实施例。然而,本领域的技术人员应当清楚,在没有这些具体细节的其它实施例中也可以实现本申请。在其它情况中,省略对众所周知的***、装置、电路以及方法的详细说明,以免不必要的细节妨碍本申请的描述。
应当理解,当在本申请说明书和所附权利要求书中使用时,术语“包括”指示所描述特征、整体、步骤、操作、元素和/或组件的存在,但并不排除一个或多个其它特征、整体、步骤、操作、元素、组件和/或其集合的存在或添加。
如在本申请说明书和所附权利要求书中所使用的那样,术语“若”可以依据上下文被解释为“当...时”或“一旦”或“响应于确定”或“响应于检测到”。
另外,在本申请说明书和所附权利要求书的描述中,术语“第一”、“第二”、“第三”等仅用于区分描述,而不能理解为指示或暗示相对重要性。
在本申请说明书中描述的参考“一个实施例”或“一些实施例”等意味着在本申请的一个或多个实施例中包括结合该实施例描述的特定特征、结构或特点。由此,在本说明书中的不同之处出现的语句“在一个实施例中”、“在一些实施例中”、“在其他一些实施例中”、“在另外一些实施例中”等不是必然都参考相同的实施例,而是意味着“一个或多个但不是所有的实施例”,除非是以其他方式另外特别强调。
首先介绍本申请实施例提供的程序故障定位方法的技术背景。
死循环故障,是指程序一直停留在某个状态,在约定的触发条件下,不再向预定的后续流程执行,但底层***及其输入、输出设备(例如按键、串口等)仍然处于正常工作或可正常工作状态。
公共函数,是指为其它的众多更高层函数提供共同的基础服务、并被这些函数根据自身需要随时地调用的函数。
耗时公共函数,是指从单次进入函数到退出函数所耗用时间相对较长的公共函数。
多级嵌套调用,是指一个函数调用下一级函数,被调用的下一级函数调用再下一级函数,以此嵌套而形成的多级调用关系。
在计算机***的软件运行中,***程序或应用程序有时会发生死循环故障,需要定位发生死循环故障的位置。现有技术中,通常是利用处理器提供的中断机制、通过***软件提供的中断服务程序来采集断点地址,以此定位死循环故障的发生位置。但是当死循环代码中含有对公共函数(尤其是耗时公共函数)的调用时,采集到的断点地址大概率会落在该公共函数内。而在当前运行的程序中往往会大量调用公共函数,因此,还需要找出被中断的公共函数的上级函数,才能找到死循环代码体、由此确定死循环故障的确切位置。
***程序或应用程序通常是基于高级语言(如C语言、C++语言等)编写的。高级语言中的函数是相对独立的代码体,通常无法知道一个函数的上级函数的名称。因此,当死循环代码中包含多级嵌套调用时,无法准确定位故障位置。
为了解决上述问题,本申请实施例提供了一种程序故障定位方法,以解决包含多级嵌套调用的死循环代码的故障定位问题。本申请实施例提供的程序故障定位方法的流程示意图,可参见图1,作为示例而非限定,所述方法可以包括以下步骤:
S101,当目标程序中出现死循环故障时,通过中断程序获取断点在目标程序中所属的第一函数。
本申请实施例中的目标程序是指,操作***当前正在运行的程序。目标程序可以是***程序,也可以是应用程序。
中断程序是基于操作***的处理器、由***软件所提供的中断服务程序,通过中断服务程序可以采集中断触发时的断点地址。对照操作***的设计和数据结构,可以检索到断点地址在目标程序中所属的第一函数。
由于目标程序中可能有多个位置调用第一函数,而发生中断的断点位置只有一个,因此,需要利用下述的S102-S104中的方法确定第一函数的当前调用者(即上级函数)是哪一个函数。
S102,确定目标程序中第一函数对应的返回地址。
这里需要介绍本申请实施例中绝对地址和相对地址的概念。一个软件模块被编译完成后,成为一个相对独立的整体;相对地址是指软件模块中的一处地址相对于该模块起始处的偏移地址。目标程序,在本方案中是指所选定的软件模块。当需要运行目标程序时,操作***将目标程序加载到为其分配的运行空间中,即在运行空间中运行目标程序。当目标程序中需要调用某个公共函数时,处理器跳转到该公共函数所在的运行空间中运行。代码被加载到运行空间后的实际运行地址称为代码的绝对地址。
示例性的,参见图2,是本申请实施例提供的存储空间的示意图。如图2中的(a)所示,公共函数中的代码aaa相对于模块起始处的偏移地址为02500,即其相对地址为02500;类似地,公共函数PUBLIC未加载运行前在所属模块中的相对地址为02000到03000。如图2中的(b)所示,操作***的内存中为目标程序分配的运行空间的地址为10000到90000。则当前运行到代码aaa,对应运行空间地址为10000+02500=12500,即代码aaa在运行空间中的绝对地址为12500。上述的绝对地址和相对地址为示例,并不对数值做具体限定。
本申请实施例中的返回地址是指,从第一函数返回后,目标程序继续执行的指令在目标内存中的绝对地址。目标内存为操作***的内存中运行目标程序的运行空间。
对于一个固定的编译器来说,其在编译函数参数传递及其调用过程时,遵循固定或由代码行所指定的规则,例如:在调用一个函数前,会将入口参数写入固定的寄存器或是压入当前的堆栈,或者是这两种方式的组合;将执行该函数时的返回地址写入特定的地址寄存器或是压入堆栈,约定为两者之一;入口参数和返回地址的压栈,也遵循约定的次序,如:先压栈返回地址、再压栈入口参数。因此,根据编译规则,可以在被调用的第一函数中嵌入较低级语言(如:汇编语言)代码,以此获取第一函数的返回地址。
S103,根据第一函数对应的返回地址确定第一函数在目标程序中的相对调用地址。
在一个实施例中,S103的步骤可以包括:
根据第一函数对应的返回地址确定第一函数在目标内存中的绝对调用地址;根据第一函数在目标内存中的绝对调用地址确定第一函数在目标程序中的相对调用地址。
相对调用地址是指目标调用指令的相对地址,绝对调用地址是指目标调用指令的绝对地址。目标调用指令为目标程序中用于调用第一函数的指令。例如:在X86***中,调用指令为call。
可选的,第一函数在目标内存中的绝对调用地址的确定方式可以包括:
获取目标调用指令的指令长度;根据第一函数对应的返回地址和该指令长度计算第一函数在目标内存中的绝对调用地址。
具体的,将第一函数对应的返回地址减去目标调用指令的指令长度,得到第一函数在目标内存中的绝对调用地址。例如:在ARM32位***中,调用一个函数的机器指令长度为4,则:调用地址=返回地址―4。
可选的,第一函数在目标程序中的相对调用地址的确定方式可以包括:
获取目标内存中加载目标程序的起始地址;根据第一函数在目标内存中的绝对调用地址和起始地址计算第一函数在目标程序中的相对调用地址。
具体的,通过中断程序获取断点所属的目标程序被加载到目标内存中的起始地址;将第一函数在目标内存中的绝对调用地址减去起始地址,得到第一目标函数在目标程序中的相对调用地址。
若目标程序是***程序,且目标程序是作为操作***内核的一部分、与操作***内核一起加载到内存中,则其起始地址一般就是内核整体被加载的起始地址;若目标程序是***作***动态加载到内存中,则其起始地址就是目标程序被加载的起始地址。若目标程序是应用程序,目标程序***作***加载到内存中时,会被放入一块空闲的、临时的连续逻辑内存中,然后以一个新进程的方式进行运行,目标程序的起始地址,就是进程被加载的起始地址。
实际应用中,可以在目标程序中第一函数的起始处嵌入以较低级语言实现的地址获取程序代码。通过地址获取程序获取第一函数的返回地址,进而获取第一函数的相对调用地址。获取到的相对调用地址可以通过输出程序输出,显示给用户。地址获取程序可以嵌入在返回地址采集的过程之后,也可以放在输出程序之前。
其中,地址获取程序的处理流程可以包括:
1)选择一个公共寄存器作为工作寄存器1、另一个公共寄存器作为工作寄存器2。
2)将工作寄存器的当前内容压栈,以备份工作寄存器的原值。
3)将全局变量A[i]的地址,存入到工作寄存器1。
此处,数组下标i的取值应根据所追溯的函数层数来确定。原则上,不同的函数层数取值应不同,以使得各取值不会相互覆盖。可以令处于最低层的函数i为0,次上层的i依次增一。
4)根据编译器对函数调用时写入返回地址的方式,进行如下的赋值处理:
若是将返回地址写入特定的地址寄存器的方式,则将该地址寄存器的值,赋值给工作寄存器2。
若是将返回地址压入堆栈的方式,则从堆栈中的对应偏移处,读出所压入返回地址的值到工作寄存器2。
5)根据工作寄存器2中的返回地址计算出绝对调用地址,重新存入工作寄存器2中。
6)将工作寄存器2的值存入工作寄存器1的A[i]。
7)将刚压入栈的工作寄存器值弹出堆栈,以恢复工作寄存器的原值。
8)将A[i]中的绝对调用地址转换为相对调用地址。
9)输出地址信息。
示例性的,假设硬件平台为ARM系列CPU(采用了将返回地址写入特定的地址寄存器lr的方式),定位出的第一函数为_delay_us(),那么在_delay_us()的起始位置嵌入地址获取程序,如下:
S104,根据第一函数在目标程序中的相对调用地址确定第一函数在目标程序中所属的第二函数。
可选的,第二函数的确定方式可以包括:
生成所述目标程序的反汇编代码;在反汇编代码中查找第一函数在目标程序中的相对调用地址所属的目标函数;将目标函数确定为第二函数。
通常反汇编代码中显示的是代码的相对地址,因此,可以通过在反汇编代码中查找第一函数的相对调用地址所在的位置,然后确定该位置所处的代码范围,进而根据代码范围确定出第一函数所属的第二函数。
示例性的,如下所示,是***程序的反汇编代码片段,每行最左边8字符是代码的相对地址:
200ae1a0<_delay_us>:
200ae1a0:e24dd008 sub sp,sp,#8;0x8
200ae1a4:e92d0006 stmdb sp!,{r1,r2}
200ae1a8:e59f1078 ldr r1,[pc,#120];200ae228<.text+0xae228>
200ae1ac:e24e2004 sub r2,lr,#4;0x4
200ae1b0:e5812000 str r2,[r1]
200ae1b4:e8bd0006 ldmia sp!,{r1,r2}
200ae1b8:e3a01000 mov r1,#0;0x0
200ae1bc:e58d1004 str r1,[sp,#4]
200ae1c0:e58d1000 str r1,[sp]
200ae1c4:e58d1004 str r1,[sp,#4]
200ae1c8:e59d3004 ldr r3,[sp,#4]
200ae1cc:e59f2050 ldr r2,[pc,#80];200ae224<.text+0xae224>
200ae1d0:e1500003 cmp r0,r3
200ae1d4:e5820000 str r0,[r2]
200ae1d8:9a00000f bls 200ae21c<_delay_us+0x7c>
200ae1dc:e58d1000 str r1,[sp]
200ae1e0:e59d3000 ldr r3,[sp]
200ae1e4:e3530010 cmp r3,#16;0x10
200ae1e8:8a000005 bhi 200ae204<_delay_us+0x64>
200ae1ec:e59d3000 ldr r3,[sp]
200ae1f0:e2833001 add r3,r3,#1;0x1
200ae1f4:e58d3000 str r3,[sp]
200ae1f8:e59d2000 ldr r2,[sp]
200ae1fc:e3520010 cmp r2,#16;0x10
200ae200:9afffff9 bls 200ae1ec<_delay_us+0x4c>
200ae204:e59d3004 ldr r3,[sp,#4]
200ae208:e2833001 add r3,r3,#1;0x1
200ae20c:e58d3004 str r3,[sp,#4]
200ae210:e59d2004 ldr r2,[sp,#4]
200ae214:e1500002 cmp r0,r2
200ae218:8affffef bhi 200ae1dc<_delay_us+0x3c>
200ae21c:e28dd008 add sp,sp,#8;0x8
200ae220:e12fff1e bx lr
200ae224:2025534c eorcs r5,r5,ip,asr#6
200ae228:20255354 eorcs r5,r5,r4,asr r3
200ae22c<DelayUs>:
200ae22c:e52de004 str lr,[sp,#-4]!
200ae230:ebffffda bl 200ae1a0<_delay_us>
200ae234:e49de004 ldr lr,[sp],#4
200ae238:eaffff8d b 200ae074<GetMs>
通过上述S101-S104步骤,输出地址信息:
输出的第一组断点信息:
Interruped APP:Kernel
Relative InterrupedAddress:200ae208
Relative CallAddress0:200ae230
第二组断点信息:
Interruped APP:Kernel
Relative InterrupedAddress:200ae1f8
Relative CallAddress0:200ae230
第三组断点信息:
Interruped APP:Kernel
Relative InterrupedAddress:200ae1fc
Relative CallAddress0:200ae230
上述断点信息中,“Interruped APP:Kernel”表示所定位的目标程序的名称为Kernel,“Relative InterrupedAddress”表示断点的相对地址,“Relative CallAddress0”表示确定出的第一函数的相对调用地址。
具体的,根据断点地址(200ae208、200ae1f8、200ae1fc)和目标程序的反汇编代码,可以看到这些地址均位于函数_delay_us()的代码体范围,因此可判断程序持续在函数_delay_us()内运行,即第一函数为_delay_us()。
接着,根据S102-S104中的方法获取第一函数的相对调用地址(200ae230),可以看到该地址落在函数DelayUs()的代码体范围,故上述第一函数所属的第二函数的名称为DelayUs。
S105,根据第二函数定位目标程序的故障位置。
在一个实施例中,检查第一函数是否落在第二函数的死循环代码体内,根据检查结果判断是否找到准确的故障位置。死循环代码体通常以循环结构的形式来出现,循环结构中循环次数不确定、可能无限大或耗时无限长,例如:C语言中for、while、goto等语句所构成的循环体。
具体的,S105的实现方式可以包括以下两种情况:
I、第一函数未落在第二函数的死循环代码体内。
所谓第一函数未落在第二函数的死循环代码体内,包含了下列情形:第二函数的自身代码体内不存在循环代码体;第二函数的自身代码体内存在至少一个循环代码体,但第一函数未被任何循环代码体包含;第二函数的自身代码体内存在至少一个循环代码体,第一函数被一个循环代码体包含,但该循环代码体的循环次数是明确的、有限的、可快速运行完成。
确定目标程序中第二函数所属的第三函数;根据第三函数定位目标程序的故障位置,直到满足预设条件。
其中,确定目标程序中第二函数所属的第三函数的方式,可以参见S102-S105的步骤。具体的,可以在第二函数中嵌入较低语言的地址获取程序,以获取第二函数的相对调用地址。继续S104中的示例,第二函数为DelayUs(),仍是一个公共函数,那么在DelayUs()的起始处嵌入地址获取程序,如下:
void DelayUs(uint us)
{
//以下是地址获取程序,用于获取上一级相对调用地址
__asm("stmdb sp!,{r1,r2}");//选择r1、r2为工作寄存器,并将其压入栈
__asm("LDR r1,=A");//本句和下句是取全局变量A[i]的地址,此处i=1
__asm("ADD r1,r1,#4");
__asm("sub r2,lr,#4");//根据返回地址计算出调用地址
__asm("STR r2,[r1]");//将调用地址的值写入全局变量A[i]
__asm("ldmia sp!,{r1,r2}");//出栈,恢复工作寄存器的值
//以下是原有代码
_delay_us(us);
GetMs();
}
通过地址获取程序可以获得第二函数的上级调用函数(即第三函数),然后根据第三函数定位目标程序的故障位置(即检查第二函数是否落在第三函数的死循环代码体内)。依次循环,直到满足预设条件。
本申请实施例中的预设条件为:当前函数落在当前函数所属的上级函数的死循环代码体内。
II、第一函数落在第二函数的死循环代码体内。
获取第二函数在目标内存中的绝对调用地址;根据第二函数在目标内存中的绝对调用地址确定目标程序的故障位置。
示例性的,参见图3,是本申请实施例提供的程序故障定位的实施流程示意图。如图3所示,运行***软件提供的中断服务程序,定位出断点所属的公共函数(即第一函数);在定位出的公共函数中嵌入地址获取程序;输出地址信息;生成目标程序的反汇编代码;根据地址信息和反汇编代码确定当前公共函数的上级函数(即第二函数);检查当前公共函数是否落在当前公共函数的上级函数的死循环代码体内;若是,则停止定位;若否,则继续在上级函数中嵌入地址获取程序。
在本申请实施例中,通过在高级语言代码中嵌入低级语言代码来实现对所定位函数的相对调用地址的获取,解决了单纯采用高级语言难以在本函数中获取其上一级函数调用地址的问题,进而有利于准确、高效地定位出死循环部位。另外,本申请实施例提供的方法,无需增加大量的调试语句,也无需对原代码进行大量修订,代码修改量小、对程序的原有运行状况影响小、定位效率较高。
应理解,上述实施例中各步骤的序号的大小并不意味着执行顺序的先后,各过程的执行顺序应以其功能和内在逻辑确定,而不应对本申请实施例的实施过程构成任何限定。
对应于上文实施例所述的程序故障定位方法,图4是本申请实施例提供的程序故障定位装置的结构框图,为了便于说明,仅示出了与本申请实施例相关的部分。
参照图4,该装置包括:
函数获取单元41,用于当目标程序中出现死循环故障时,通过中断程序获取断点在所述目标程序中所属的第一函数。
返回地址确定单元42,用于确定所述目标程序中所述第一函数对应的返回地址。
调用地址确定单元43,用于根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址。
函数确定单元44,用于根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数。
故障定位单元45,用于根据所述第二函数定位所述目标程序的故障位置。
可选的,调用地址确定单元43包括:
绝对地址确定模块,用于根据所述第一函数对应的返回地址确定所述第一函数在目标内存中的绝对调用地址,所述目标内存为运行所述目标程序的操作***中用于加载所述目标程序的存储空间。
相对地址确定模块,用于根据所述第一函数在目标内存中的绝对调用地址确定所述第一函数在所述目标程序中的相对调用地址。
可选的,绝对地址确定模块还用于:
获取目标调用指令的指令长度,所述目标调用指令为所述操作***中用于调用所述第一函数的指令;根据所述第一函数对应的返回地址和所述指令长度计算所述第一函数在所述目标内存中的绝对调用地址。
可选的,相对地址确定模块还用于:
获取所述目标内存中加载所述目标程序的起始地址;根据所述第一函数在目标内存中的绝对调用地址和所述起始地址计算所述第一函数在所述目标程序中的相对调用地址。
可选的,函数确定单元44还用于:
生成所述目标程序的反汇编代码;在所述反汇编代码中查找所述第一函数在所述目标程序中的相对调用地址所属的目标函数;将所述目标函数确定为所述第二函数。
可选的,故障定位单元45还用于:
若第一函数未落在第二函数的死循环代码体内,则确定所述目标程序中所述第二函数所属的第三函数;根据所述第三函数定位所述目标程序的故障位置,直到满足预设条件。
可选的,故障定位单元45还用于:
若第一函数落在第二函数的死循环代码体内,则获取所述第二函数在目标内存中的绝对调用地址,所述目标内存为运行所述目标程序的操作***中用于加载所述目标程序的存储空间;将所述第二函数在目标内存中的绝对调用地址确定所述目标程序的故障位置。
需要说明的是,上述装置/单元之间的信息交互、执行过程等内容,由于与本申请方法实施例基于同一构思,其具体功能及带来的技术效果,具体可参见方法实施例部分,此处不再赘述。
另外,图4所示的程序故障定位装置可以是内置于现有的终端设备内的软件单元、硬件单元、或软硬结合的单元,也可以作为独立的挂件集成到所述终端设备中,还可以作为独立的终端设备存在。
所属领域的技术人员可以清楚地了解到,为了描述的方便和简洁,仅以上述各功能单元、模块的划分进行举例说明,实际应用中,可以根据需要而将上述功能分配由不同的功能单元、模块完成,即将所述装置的内部结构划分成不同的功能单元或模块,以完成以上描述的全部或者部分功能。实施例中的各功能单元、模块可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中,上述集成的单元既可以采用硬件的形式实现,也可以采用软件功能单元的形式实现。另外,各功能单元、模块的具体名称也只是为了便于相互区分,并不用于限制本申请的保护范围。上述***中单元、模块的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
图5是本申请实施例提供的终端设备的结构示意图。如图5所示,该实施例的终端设备5包括:至少一个处理器50(图5中仅示出一个处理器)、存储器51以及存储在所述存储器51中并可在所述至少一个处理器50上运行的计算机程序52,所述处理器50执行所述计算机程序52时实现上述任意各个程序故障定位方法实施例中的步骤。
所述终端设备可以是桌上型计算机、笔记本、掌上电脑及云端服务器等计算设备。该终端设备可包括,但不仅限于,处理器、存储器。本领域技术人员可以理解,图5仅仅是终端设备5的举例,并不构成对终端设备5的限定,可以包括比图示更多或更少的部件,或者组合某些部件,或者不同的部件,例如还可以包括输入输出设备、网络接入设备等。
所称处理器50可以是中央处理单元(Central Processing Unit,CPU),该处理器50还可以是其他通用处理器、数字信号处理器(Digital Signal Processor,DSP)、专用集成电路(Application Specific Integrated Circuit,ASIC)、现成可编程门阵列(Field-Programmable Gate Array,FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。
所述存储器51在一些实施例中可以是所述终端设备5的内部存储单元,例如终端设备5的硬盘或内存。所述存储器51在另一些实施例中也可以是所述终端设备5的外部存储设备,例如所述终端设备5上配备的插接式硬盘,智能存储卡(Smart Media Card,SMC),安全数字(Secure Digital,SD)卡,闪存卡(Flash Card)等。进一步地,所述存储器51还可以既包括所述终端设备5的内部存储单元也包括外部存储设备。所述存储器51用于存储操作***、应用程序、引导装载程序(BootLoader)、数据以及其他程序等,例如所述计算机程序的程序代码等。所述存储器51还可以用于暂时地存储已经输出或者将要输出的数据。
本申请实施例还提供了一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行时实现可实现上述各个方法实施例中的步骤。
本申请实施例提供了一种计算机程序产品,当计算机程序产品在终端设备上运行时,使得终端设备执行时实现可实现上述各个方法实施例中的步骤。
所述集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本申请实现上述实施例方法中的全部或部分流程,可以通过计算机程序来指令相关的硬件来完成,所述的计算机程序可存储于一计算机可读存储介质中,该计算机程序在被处理器执行时,可实现上述各个方法实施例的步骤。其中,所述计算机程序包括计算机程序代码,所述计算机程序代码可以为源代码形式、对象代码形式、可执行文件或某些中间形式等。所述计算机可读介质至少可以包括:能够将计算机程序代码携带到装置/终端设备的任何实体或装置、记录介质、计算机存储器、只读存储器(ROM,Read-Only Memory)、随机存取存储器(RAM,Random AccessMemory)、电载波信号、电信信号以及软件分发介质。例如U盘、移动硬盘、磁碟或者光盘等。在某些司法管辖区,根据立法和专利实践,计算机可读介质不可以是电载波信号和电信信号。
在上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述或记载的部分,可以参见其它实施例的相关描述。
本领域普通技术人员可以意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、或者计算机软件和电子硬件的结合来实现。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。
在本申请所提供的实施例中,应该理解到,所揭露的装置/终端设备和方法,可以通过其它的方式实现。例如,以上所描述的装置/终端设备实施例仅仅是示意性的,例如,所述模块或单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个***,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通讯连接可以是通过一些接口,装置或单元的间接耦合或通讯连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
以上所述实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述实施例对本申请进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的精神和范围,均应包含在本申请的保护范围之内。

Claims (8)

1.一种程序故障定位方法,其特征在于,包括:
当目标程序中出现死循环故障时,通过中断程序获取断点在所述目标程序中所属的第一函数;
确定所述目标程序中所述第一函数对应的返回地址;所述返回地址是指从所述第一函数返回后,所述目标程序继续执行的指令在目标内存中的绝对地址;
根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址;
根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数;
根据所述第二函数定位所述目标程序的故障位置;
所述根据所述第二函数定位所述目标程序的故障位置,包括:
若第一函数未落在第二函数的死循环代码体内,则确定所述目标程序中所述第二函数所属的第三函数;
根据所述第三函数定位所述目标程序的故障位置,直到满足预设条件;
若第一函数落在第二函数的死循环代码体内,则获取所述第二函数在目标内存中的绝对调用地址,所述目标内存为运行所述目标程序的操作***中用于加载所述目标程序的存储空间;
将所述第二函数在目标内存中的绝对调用地址确定所述目标程序的故障位置。
2.如权利要求1所述的程序故障定位方法,其特征在于,所述根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址,包括:
根据所述第一函数对应的返回地址确定所述第一函数在目标内存中的绝对调用地址,所述目标内存为运行所述目标程序的操作***中用于加载所述目标程序的存储空间;
根据所述第一函数在目标内存中的绝对调用地址确定所述第一函数在所述目标程序中的相对调用地址。
3.如权利要求2所述的程序故障定位方法,其特征在于,所述根据所述第一函数对应的返回地址确定所述第一函数在目标内存中的绝对调用地址,包括:
获取目标调用指令的指令长度,所述目标调用指令为所述操作***中用于调用所述第一函数的指令;
根据所述第一函数对应的返回地址和所述指令长度计算所述第一函数在所述目标内存中的绝对调用地址。
4.如权利要求2所述的程序故障定位方法,其特征在于,所述根据所述第一函数在目标内存中的绝对调用地址确定所述第一函数在所述目标程序中的相对调用地址,包括:
获取所述目标内存中加载所述目标程序的起始地址;
所述第一函数在目标内存中的绝对调用地址和所述起始地址计算所述第一函数在所述目标程序中的相对调用地址。
5.如权利要求1所述的程序故障定位方法,其特征在于,所述根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数,包括:
生成所述目标程序的反汇编代码;
在所述反汇编代码中查找所述第一函数在所述目标程序中的相对调用地址所属的目标函数;
将所述目标函数确定为所述第二函数。
6.一种程序故障定位装置,其特征在于,包括:
函数获取单元,用于当目标程序中出现死循环故障时,通过中断程序获取断点在所述目标程序中所属的第一函数;
返回地址确定单元,用于确定所述目标程序中所述第一函数对应的返回地址;所述返回地址是指从所述第一函数返回后,所述目标程序继续执行的指令在目标内存中的绝对地址;
调用地址确定单元,用于根据所述第一函数对应的返回地址确定所述第一函数在所述目标程序中的相对调用地址;
函数确定单元,用于根据所述第一函数在所述目标程序中的相对调用地址确定所述第一函数在所述目标程序中所属的第二函数;
故障定位单元,用于根据所述第二函数定位所述目标程序的故障位置;
所述故障定位单元用于:
若第一函数未落在第二函数的死循环代码体内,则确定所述目标程序中所述第二函数所属的第三函数;根据所述第三函数定位所述目标程序的故障位置,直到满足预设条件;
若第一函数落在第二函数的死循环代码体内,则获取所述第二函数在目标内存中的绝对调用地址,所述目标内存为运行所述目标程序的操作***中用于加载所述目标程序的存储空间;将所述第二函数在目标内存中的绝对调用地址确定所述目标程序的故障位置。
7.一种终端设备,包括存储器、处理器以及存储在所述存储器中并可在所述处理器上运行的计算机程序,其特征在于,所述处理器执行所述计算机程序时实现如权利要求1至5任一项所述的方法。
8.一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,其特征在于,所述计算机程序被处理器执行时实现如权利要求1至5任一项所述的方法。
CN202110573162.4A 2021-05-25 2021-05-25 程序故障定位方法、终端设备及计算机可读存储介质 Active CN113220334B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202110573162.4A CN113220334B (zh) 2021-05-25 2021-05-25 程序故障定位方法、终端设备及计算机可读存储介质

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202110573162.4A CN113220334B (zh) 2021-05-25 2021-05-25 程序故障定位方法、终端设备及计算机可读存储介质

Publications (2)

Publication Number Publication Date
CN113220334A CN113220334A (zh) 2021-08-06
CN113220334B true CN113220334B (zh) 2024-04-16

Family

ID=77099476

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202110573162.4A Active CN113220334B (zh) 2021-05-25 2021-05-25 程序故障定位方法、终端设备及计算机可读存储介质

Country Status (1)

Country Link
CN (1) CN113220334B (zh)

Citations (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2017107576A1 (zh) * 2015-12-25 2017-06-29 华为技术有限公司 一种生成处理器故障记录的方法及装置
CN107220175A (zh) * 2017-05-08 2017-09-29 百富计算机技术(深圳)有限公司 应用程序死循环定位方法、装置、计算机设备和存储介质
CN109766273A (zh) * 2018-12-27 2019-05-17 百富计算机技术(深圳)有限公司 死循环的定位方法、装置、计算机设备和存储介质
CN110750450A (zh) * 2019-09-19 2020-02-04 深圳震有科技股份有限公司 一种软件死循环的定位方法、装置、***及存储介质
CN110928778A (zh) * 2019-11-19 2020-03-27 百富计算机技术(深圳)有限公司 死循环定位方法、装置、计算机设备和存储介质

Patent Citations (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2017107576A1 (zh) * 2015-12-25 2017-06-29 华为技术有限公司 一种生成处理器故障记录的方法及装置
CN107220175A (zh) * 2017-05-08 2017-09-29 百富计算机技术(深圳)有限公司 应用程序死循环定位方法、装置、计算机设备和存储介质
CN109766273A (zh) * 2018-12-27 2019-05-17 百富计算机技术(深圳)有限公司 死循环的定位方法、装置、计算机设备和存储介质
CN110750450A (zh) * 2019-09-19 2020-02-04 深圳震有科技股份有限公司 一种软件死循环的定位方法、装置、***及存储介质
CN110928778A (zh) * 2019-11-19 2020-03-27 百富计算机技术(深圳)有限公司 死循环定位方法、装置、计算机设备和存储介质

Also Published As

Publication number Publication date
CN113220334A (zh) 2021-08-06

Similar Documents

Publication Publication Date Title
US8769504B2 (en) Method and apparatus for dynamically instrumenting a program
CN110287702B (zh) 一种二进制漏洞克隆检测方法及装置
CN106933733B (zh) 一种确定内存泄露位置的方法和装置
US9753730B2 (en) Decoding instructions from multiple instructions sets
CN112015491B (zh) 实现函数跳转的方法、装置及计算机存储介质
CN109271789B (zh) 恶意进程检测方法、装置、电子设备及存储介质
US9639451B2 (en) Debugger system, method and computer program product for utilizing hardware breakpoints for debugging instructions
US7539979B1 (en) Method and system for forcing context-switch during mid-access to non-atomic variables
CN101533370B (zh) 一种内存异常访问定位方法及装置
CN111897711A (zh) 代码中bug的定位方法、装置、电子设备及可读存储介质
CN109582542B (zh) 一种嵌入式***核心转储的方法
CN106502707B (zh) 代码生成方法及装置
CN113220334B (zh) 程序故障定位方法、终端设备及计算机可读存储介质
CN116521414A (zh) 故障代码定位方法、云端服务器、***及存储介质
US9182990B1 (en) Method and apparatus for detecting execution of unsupported instructions while testing multiversioned code
CN108959915B (zh) 一种rootkit检测方法、装置及服务器
CN111190658B (zh) 一种基于片内执行且在不具有MMU的SoC片上支持应用程序动态加载的***
US20110144958A1 (en) Detection of design redundancy
US8359456B2 (en) Generating random addresses for verification of distributed computerized devices
CN113031956A (zh) 程序编译方法和装置以及程序运行方法和装置
CN112527660B (zh) 代码的静态检测方法和装置
JP2016029547A (ja) 実行モジュール生成装置、及び電子制御装置
US11989572B2 (en) Computer system enabled with runtime software module tracking
CN112612471B (zh) 代码处理方法、装置、设备及存储介质
CN112860224B (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