一种程序错误定位方法与流程

文档序号:12824648阅读:657来源:国知局
一种程序错误定位方法与流程

本发明涉及计算机技术领域,尤其涉及一种程序错误定位方法。



背景技术:

程序调试是软件产品开发的重要环节,一般会占用软件产品开发的大部分时间。程序调试最主要的工作是定位程序错误位置和修改程序错误,其中定位程序错误位置对于程序调试来说至关重要。

通常来说,程序错误定位方法有日志记录方法(以下简称日志法)和错误码记录法(以下简称错误码法)。

日志法是常用的程序错误定位方法,通过在程序错误分支打印与该错误相关的日志信息,程序出现错误时,通过日志信息定位程序错误位置。记录日志的方法可以是存储在log文件中,也可以直接打印到屏幕上。打印到屏幕的方式一般只适用于产品调试阶段,在实际运行阶段则存储在专门的log文件中。

错误码法是将错误进行分类,每一个错误码对应一类错误。如在linux系统中采用errno记录系统最后一次的错误代码。当程序运行故障时,通过查看errno值即可判断是哪一类错误。

日志法需要有一定的存储空间存储错误日志信息,并要求错误日志信息是可读取的,在很多场合日志法并不实用。如在资源受限的嵌入式系统中,没有足够的空间存储错误日志,这种方法并不适用;在很多安全产品中,出于安全考虑,不能输出过多的日志信息,这种方法也不适用。

另外,假如打印错误日志信息的函数被调用的位置过多,也无法确定是谁调用该函数导致的出错,为此需要逐层加入打印信息。而为应对这种问题,提高程序执行效率,日志法在具体实施时不同阶段采用不同策略,产品调试阶段打开日志信息(debug版本),正式发布时则关闭大部分日志信息(release版本),因此在正式发布版程序如果出现错误由于日志信息少,很难定位实际错误位置。

错误码法只能确定程序错误属于哪一类,并不能准确定位调用哪个函数导致的出错,因此常常需要和日志法相结合进行错误定位。



技术实现要素:

鉴于上述的分析,本发明旨在提供一种程序错误定位方法,用以解决传统程序错误定位方法无法准确定位程序错误位置或需要存储空间较大的问题。

本发明的目的主要是通过以下技术方案实现的:

在基于本发明的一个实施例中,提供了一种程序错误定位方法,包括步骤:

步骤s1、统一编排错误码并存储;

步骤s2、运行程序,当出现错误时,得到各级错误分支的级联值;

步骤s3、将各级错误分支的级联值进行级联,得到级联结果并存储,同时返回返回值;

步骤s4、根据步骤s1的编排结果,对级联结果进行解析,定位程序错误位置。

在基于本发明方法的另一个实施例中,步骤s1中编排错误码,是将同一函数不同的错误分支采用不同的错误码标记。

在基于本发明方法的另一个实施例中,步骤s1中编排错误码,是将错误码分为预定义错误码和通用错误码,同一函数相同错误类型的错误分支采用相同的预定义错误码标记,当预定义错误码在同一个函数中出现了两次以上,则每个错误分支分配不同的通用错误码,并将预定义错误码和通用错误码级联;当预定义错误码只在同一函数出现了一次,则无需为其分配通用错误码。

在基于本发明方法的另一个实施例中,步骤s2中,当错误分支为条件判断失败时,所述级联值为错误码;当错误分支为调用函数返回失败时,所述级联值为错误码和调用函数返回值的级联。

在基于本发明方法的另一个实施例中,步骤s3中,所述级联结果直接存储到返回值中。

在基于本发明方法的另一个实施例中,步骤s2中,当错误分支为条件判断失败时,所述级联值为错误码;当错误分支为调用函数返回失败时,所述级联值为错误码与全局变量的级联。

在基于本发明方法的另一个实施例中,步骤s3中,将所述级联结果存储到全局变量中。

在基于本发明方法的另一个实施例中,步骤s3中还包括将最后一级错误码存储到调用函数返回值中。

本发明有益效果如下:本发明通过对错误返回分支作级联处理,通过级联值确定程序错误的位置。相对于日志法和错误码法,对程序的软件开销要求小,对存储空间要求小,而且能准确记录出现错误的函数的调用层次。

本发明的其他特征和优点将在随后的说明书中阐述,并且,部分的从说明书中变得显而易见,或者通过实施本发明而了解。本发明的目的和其他优点可通过在所写的说明书、权利要求书、以及附图中所特别指出的结构来实现和获得。

附图说明

附图仅用于示出具体实施例的目的,而并不认为是对本发明的限制,在整个附图中,相同的参考符号表示相同的部件。

图1为定位程序错误方法流程图;

图2为返回值法函数fun流程图;

图3为返回值法函数fun2流程图;

图4为返回值法函数funb流程图;

图5为返回值法函数func流程图;

图6为函数执行返回失败的级联结果示例;

图7为全局变量法函数fun流程图;

图8为更优的错误码编排示例。

具体实施方式

下面结合附图来具体描述本发明的优选实施例,其中,附图构成本申请一部分,并与本发明的实施例一起用于阐释本发明的原理。

在定位程序错误位置之前,先统一编排错误码,编排错误码的规则是每个函数的各错误分支都有唯一的错误码对应,保证同一函数不同的错误分支返回采用不同的错误码标记。

假设在一个工程项目中,单一函数方法可能出现的错误分支不会超过99种,没有错误定义为0,则依次需定义100种错误码:

#definenoerr0

#defineerr11

#defineerr22

#defineerr9999

计算机一般采用二进制存储,因此100种错误码共需要n=7个bit来表达。错误码最小占用bit数n的一般计算方法如下:

假设一个工程项目中一共有n个函数,每个函数错误返回分支个数记为mi(i=1,2…n),并记mi的最大值为mmax,解下列不等式求出m值。

2m-1<(1+mmax)≤2m,m为正整数(1)

m的值即为n的最小值,即当编排错误码所占的比特数为n满足n≥m即可。如上例,mmax=99,26<(1+99)≤27,则错误码所占的比特数n=7,即可保证同一函数不同的错误分支返回采用不同的错误码标记。

在本发明的第一个实施例中,定位程序错误的方法包括以下步骤:

步骤1、统一编排错误码并存储;

fun函数运行时调用fun1、fun2函数,fun2函数运行时调用funb函数,funb函数运行时调用func函数,func函数运行时调用fund函数,根据编排错误码的规则,如图2、表1所示,错误分支1为调用fun1函数失败,将错误分支1的错误码标记为err1,错误分支2为调用fun2函数失败,将错误分支2的错误码标记为err2,错误分支3为没有调用函数但是条件判断失败,将错误分支3的错误码标记为err3,三处可能出现的错误分支分别采用了err1、err2、err3来标记,err1、err2和err3均不相同,符合本申请编排错误码的规则。

表1错误码编排规则示例

同理,如图3、表1所示,fun2函数运行时,错误分支1、2、3为条件判断错误,则将错误分支1、2、3的错误码分别标记为err1、err2、err3,错误分支4调用funb函数失败,则将错误分支4的错误码标记为err4。

如图4、表1所示,funb函数运行时,错误分支1为调用func函数失败,则将错误分支1的错误码标记为err1。

如图5、表1,所示func函数运行时,错误分支1、2为条件判断错误,则将错误分支1、2的错误码分别标记为err1、err2,错误分支3为调用fund函数失败,则将错误分支3的错误码标记为err3。

步骤2、运行程序,当出现错误时,得到各级错误分支的级联值;

根据级联结果存储位置,实施方式包括返回值法和全局变量法。本实施例中使用返回值法进行错误码的级联。为方便表述,定义级联操作符号为“||”,则a=b||c,表示将b和c级联并赋给a;a=a||b表示将a和b级联后重新赋给a,进一步的,a=b||c||d,则表示将b和c级联后,得到的级联值再与d级联,并将最后的级联值赋给a。下面是一种可实现的具体级联方式实施实例(以c语言为例):#definecas(curerr,lowererr)((lowererr<<n)|curerr)

lowererr<<n表示将lowererr变量左移nbit,((lowererr<<n)|curerr)表示将lowererr左移nbit的结果与curerr变量进行“或”操作。

这种级联操作下,上述实施例中的级联操作“a=b||c”则可以用a=cas(b,c)具体实现,具体来说实施实例(a)中的分支1处的表达式”ret=err1||ret”可以改写为:

ret=cas(err1,ret)

当错误分支为条件判断失败时,级联值为错误码;

当错误分支为调用函数返回失败时,级联值为错误码和调用函数返回值的级联;

步骤3、将各级错误分支的级联值级联,得到级联结果并存储到返回值中,返回该返回值;

以c语言为例:

{

//此处调用函数失败,返回值ret,错误码分配err3

ret=cas(err3,ret);

returnret;

}

也可以直接简写为

{

//此处调用函数失败,返回值ret,错误码分配err3

returncas(err3,ret);

}

通过级联的方式对错误码进行记录,然后通过级联的结果对错误进行追溯。上述实施实例中,级联方式为左移方式实现。

步骤4、解析级联结果,定位程序错误位置;

将级联值进行解析,每层错误码对应一个错误分支,由于步骤1中错误码的编排规则是一一对应的,可以准确找到程序错误的位置。

以图6所示,假定该函数执行返回失败,最终得到的返回值ret为err2||err4||err1||err3。

第一层错误码为err2,查看函数源码,可知由于调用函数fun2失败导致;第二层错误码为err4,查看函数fun2源码,可知由于调用函数funb失败导致;第三层错误码为err1,查看函数funb源码,可知由于调用函数func失败导致;第四层错误码为err3,查看函数func源码,可知由于调用函数fund失败导致。简言之,根据该级联值,依次可以定位出fun2、funb、func、fund执行失败,从而找到程序错误位置为fund调用失败导致。

或者,函数执行返回失败,最终得到的返回值ret为err2||err3,则:

根据第一层错误码为err2,查看函数源码,可知由于调用函数fun2失败导致;第二层错误码为err3,查看fun2源码可知,由于fun2中程序执行到条件2不满足时返回,从而定位到函数错误位置。

在本发明的第二个实施例中,步骤1同上,错误码的级联存储使用的是全局变量法:首先设置全局变量cas,如图7所示:

步骤2’、运行程序,得到各级错误分支的级联值;

当错误分支为条件判断失败时,级联值为错误码;

当错误分支为调用函数返回失败时,级联值为错误码与全局变量的级联。

步骤3’、将各级错误分支的级联值级联,得到级联结果并存储到全局变量中,返回返回值;

当错误分支为条件判断失败时,将该错误码存储到全局变量cas和返回值ret中,返回返回值。

比如,错误分支3没有调用子函数,但是某条件判断失败进入错误分支流程,此处直接将err3赋值给cas和ret,并返回ret。

以c语言为例:

{

//此处为错误分支,错误码为err1

cas=err1;

returnerr1;

}

当错误分支为调用函数返回失败时,将级联值存储到cas中,将最后一级错误分支的错误码存储在调用函数返回值中并返回。

以c语言为例:

{

//执行子函数失败,返回值为err2

cas=cas(err2,cas);

returnerr2;

}

步骤4’、根据存储在全局变量cas中的级联结果,定位程序错误的位置。

和返回值法的区别就是,返回值法最后查看的是最后一步函数的返回值,全局变量是查看最后一步函数失败时的全局变量值,根据步骤1中编排的错误码进行解析定位的方法是一样的。

综上所述,级联存储位置可以是返回值或全局变量,但并不限于上述两种方法,除此之外,还可以通过数组、队列、环行队列、链表等方式对错误码进行存储和级联,只要能够区分出错误返回码的起始值和追溯方向即可。

在本发明的第三个实施例中,给出了一种更优的错误码编排方法,假如某个函数的若干个分支中,某几个分支代表的错误类型可能是一样的,如果这几个分支的错误码采用了不同的错误码标记,上一级函数在判断该函数返回值类型的时候,还需要逐一判断。所以本实施例中对这几个分支作归并处理,以简化代码。

对s1步骤的编排错误码时进行改进,其他步骤与第一个实施例相同。将错误码分为:预定义错误码和通用错误码,并统一编码,预定义错误码和通用错误码编码空间不重叠。例如,假设预定义错误码不超过30种,并且每种预定义错误码在同一函数中不同分支出现时,最多不超过20处分支。则可以定义:

#definenoerr0

#definererr11

#definererr22

#definererr3030

#defineuerr131

#defineuerr232

#defineuerr2050

对图3中fun2中,假如错误分支1和错误分支2代表的错误类型一致,则预定义错误码均为rerr1,为区分分支1和分支2,为分支1和分支2再分别分配通用错误码uerr1、uerr2,并将预定义错误码和各自的通用错误码进行一次级联;同时,假如错误分支3和错误分支4,代表的预定义错误码一致,均为rerr2,为区分分支3和分支4,再为分支3和分支4分别分配通用错误码uerr1、uerr2,并将其进行级联,由于分支4还调用了子函数,因此将子函数的返回值ret也进行级联,如图8所示。如果预定义错误码只在同一函数出现了一次,则无需为其分配通用错误码。

采用上述方法编排错误码,当某函数的同一类型的错误分支可以忽略,程序员需要判断函数返回值属于某一类型的时候,直接取最近一层的错误码和该类型错误码进行相等判断即可,大大简化了代码量,而需要判断具体是哪个分支返回错误时也可以准确定位。

本实施例中步骤s2-s4可选择实施例一的返回值法或实施例二的全局变量法。

本领域技术人员可以理解,实现上述实施例方法的全部或部分流程,可以通过计算机程序来指令相关的硬件来完成,所述的程序可存储于计算机可读存储介质中。其中,所述计算机可读存储介质为磁盘、光盘、只读存储记忆体或随机存储记忆体等。

以上所述,仅为本发明较佳的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1