故障定位的方法和装置的制作方法

文档序号:6462075阅读:143来源:国知局
专利名称:故障定位的方法和装置的制作方法
技术领域
本发明涉及无内部互锁流水级的孩支处理器领域,并且特别地, 涉及一种对无内部互锁流水级的微处理器的堆栈进行故障定位的方 法和装置。
背景技术
无内部互锁流水级的孩t处理器(MIPS)作为三大RISC CPU (powerpc、 arm、以及mips)之一,在嵌入式i殳备上4寻到广S乏应用, 越来越多的嵌入式程序运行于MIPS CPU之上。当应用程序因为空 指针、错误指针、溢出等错误导致异常崩溃时,打印出的可供参考 的信息寥寥无几。操作系统的异常处理程序里通常只是打印当前 CPU的所有寄存器的值以及异常进程异常时用户空间程序指针 (pc),堆栈指针(sp)的值等。通常的定位故障的办法是先反汇编异常进程可执行文件,然后 根据异常时打印的pc值去反汇编代码中查找异常发生所在的函数, 然而,这种方法有存在以下问题第一,这种做法非常的繁瑣,并且不够不直观,需要反汇编代 码、查找。并且对开发人员有较高要求,很多上层业务开发人员并 不熟悉这种反汇编定位故障的方法。第二,不能解决所有问题。第一种情况是如果当前异常函数被 很多函数调用,即使找到了异常函数,依然无法定位是上面哪个函 数调用了以及哪个流程出了问题,实际上,定位故障是定位一条函 凄t执行流程。第二种种情况是异常有时发生在库函数里(比如调用库函数的函数传给库函数参lt错误),异常记录的pc值为库函数i也 址,在反汇编用户进程里是无法找到与此pc值对应的地址的。目前,在现有技术中,尚未提出能够解决以上所述两个问题的 4支术方案。发明内容考虑到上述问题而做出本发明,为此,本发明的主要目的在于 提供一种故障定位的方法和装置,以解决相关技术中故障定位繁瑣、 定位结果不直》见、以及故障定位不准确的问题。根据本发明的一个实施例,提供了一种故障定位方法,用于对 无内部互锁流水级的微处理器的堆栈进行故障定位。该方法包括在由于函数调用异常导致进程出现异常的情况下, 在程序空间中获取异常进程的程序指针的值和堆栈指针的值;根据获取的程序指针的值和堆栈指针的值获取堆栈指针指向的当前函凄t堆栈的大小以及当前函数堆栈的栈帧中所存储的返回指令;根据当 前函数堆栈的大小和堆栈指针的值获取当前函数堆栈之后的函数堆 栈的栈帧中存储的函数的返回指令;查找异常进程的可执行文件, 并根据查找的可执行文件查找异常进程的符号表,根据在当前栈帧 和其它栈帧中获取的返回指令在符号表中查找相应的函数。此外,获取当前函数堆栈之后的函数堆栈的栈帧中存储的函数 的返回指令的处理具体为确定当前堆栈指针的值;获取当前函数 堆栈中存储的返回地址;确定当前函数堆栈的大小;将确定的值和大小相加,将相加的结果作为当前函数堆栈的下一个函数堆栈的栈 帧地址,并将下一个函数堆栈作为当前函数堆栈。其中,在每次获取了 一个函数堆栈的栈帧中存储的函数的返回指令后,进一步包括判断获取的返回指令所对应的函数是否在调 用异常的函数体内,如果判断为是,则继续查找下个函^:堆栈;否 则停止查找函数堆栈。进行判断的处理具体为获取当前获取的函 凄t堆栈的地址,并乂人程序空间获取该函凄t堆栈的大小,并4艮据当前 获取的函数堆栈的地址和大小判断其是否在函凄t体范围内。其中,根据获取的返回指令在符号表中查找相应的函数的处理 具体为将符号表中小于并且最接近于返回地址的函数地址作为对 应于该返回地址的函数地址,并根据函数地址找到相应函数。根据本发明的另一实施例,提供了一种故障定位装置,用于对 无内部互锁流水级的樣i处理器的堆栈进行故障定位。该装置包括第一获取模块,用于在由于函数调用异常导致进 程出现异常的情况下,在程序空间中获取异常进程的程序指针的值 和堆栈指针的值;第二获取模块,用于根据获取的程序指针的值和 堆栈指针的值获取堆栈指针指向的当前函数堆栈的大小以及当前函 数堆栈的栈帧中所存储的返回指令;以及根据当前函凄t堆栈的大小 和堆栈指针的值获取当前函数堆栈之后的函数堆栈的栈帧中存储的 函数的返回指令;查找模块,用于查找异常进程的可执行文件,并 根据查找的可执行文件查找异常进程的符号表,根据在当前栈帧和 其它栈帧中获取的返回指令在符号表中查找相应的函数。其中,第二获取模块获取当前函数堆栈之后的函数堆栈的栈帧 中存储的函数的返回指令的处理具体为确定当前堆栈指针的值; 获取当前函凄t堆栈中存储的返回地址;确定当前函数堆栈的大小;将确定的值和大小相加,将相加的结果作为当前函数堆栈的下一个 函数堆栈的栈帧地址,并将下一个函数堆栈作为当前函数堆栈。此外,该装置进一步包括判断模块,用于在每次获取了一个 函数堆栈的栈帧中存储的函数的返回指令后,判断获取的返回指令 所对应的函凄l是否在调用异常的函凄t体内,如果判断为是,则继续 查找下个函数堆栈;否则停止查找函数堆栈。判断模块进行的判断 处理具体为获取当前获取的函数堆栈的地址,并从程序空间获取 该函数堆栈的大小,并根据当前获取的函数堆栈的地址和大小判断 其是否在函凄t体范围内。此外,查找模块根据获取的返回指令在符号表中查找相应的函 数时所执行的处理具体为将符号表中小于并且最接近于返回地址 的函数地址作为对应于该返回地址的函数地址,并根据函数地址找 到^目应函凄丈。综上所述,借助于本发明的技术方案,能够有效实现自动化的 故障定位,大大提高了调试和故障定位的效率,简化了故障定位的 操作,并且使故障定位的操作结果更加直观。


此处所说明的附图用来提供对本发明的进一步理解,构成本申 请的一部分,本发明的示意性实施例及其说明用于解释本发明,并 不构成对本发明的不当限定。在附图中图i是才艮据本发明方法实施例的故障定位方法的流禾呈图;图2是根据相关技术的mips栈帧结构图;以及图3是根据本发明装置实施例的故障定位装置的框图。
具体实施方式
方法实施例在本实施例中,4是供了一种故障定位方法,用于对无内部互锁 流水级的孩吏处理器的堆栈进行故障定位。图1是故障定位方法的流程图,如图1所示,该方法包括步骤S102,在由于函数调用异常导致进程出现异常的情况下, 在程序空间中获取异常进程的程序指针的值和堆栈指针的值;步骤 S104,根据获取的程序指针的值和堆栈指针的值获取堆栈指针指向 的当前函数堆栈的大小以及当前函数堆栈的栈帧中所存储的返回指 令;步骤S106,根据当前函数堆栈的大小和堆栈指针的值获取当前 函数堆栈之后的函数堆栈的栈帧中存储的函数的返回指令;步骤 S108,查找异常进程的可^M于文件,并才艮据查找的可执4于文件查找 异常进程的符号表,根据在当前栈帧和其它栈帧中获取的返回指令 在符号表中查找相应的函数。也就是说,定位一条函数执行流程可以通过堆栈回溯的方法, 每个函数执行时有一个栈帧,栈帧里保存有每个函数的返回地址, 在异常时将堆栈帧里存储的各个函数地址回溯可以精确复现函数执 4亍调用关系,就可以解决在反汇编用户进程里是无法找到与此pc ^直对应的地址的问题。但是,问题的关键是确定每个栈帧的大小及每个函数返回地址 保存于栈帧中的位置,仅仅通过堆栈和异常现场的mips的32个寄 存器是无法实现的。此外,获取当前函数堆栈之后的函数堆栈的栈帧中存储的函数 的返回指令的处理具体为确定当前堆栈指针的值;获取当前函数堆栈中存储的返回地址;确定当前函数堆栈的大小;将确定的值和 大小相加,将相加的结果作为当前函数堆栈的下一个函数堆栈的栈 帧地址,并将下一个函数堆栈作为当前函lt堆栈。其中,在每次获取了一个函数堆栈的栈帧中存储的函数的返回 指令后,进一步包括判断获取的返回指令所对应的函数是否在调用异常的函数体内,如果判断为是,则继续查找下个函数堆栈;否 则停止查找函数堆栈。进行判断的处理具体为获取当前获取的函 数堆栈的地址,并从程序空间获取该函凄t堆栈的大小,并才艮据当前 获取的函数堆栈的地址和大小判断其是否在函数体范围内。当进程发生异常时,操作系统会保护进程用户空间现场进入异 常处理程序。根据异常时进程PC和SP值在此进程程序空间.text区 搜索MIPS关键二进制指令,以获得当前函数堆栈大小及返回指令 存储于此栈帧位置,gcc编译mips代码时有固有的特点,某些指令 包含了函数开始初分配栈帧空间的大小,某些指令指出了函数返回 地址保存寄存器ra保存于栈帧里的相对位置。搜索到这些特定指令 即可以获得当前函数堆栈大小及r a保存于栈帧中位置。将sp加上当前函数堆栈大小即获得下一栈帧的sp,从栈帧中取 出ra或直接从ra中可获得返回指令地址,返回指令地址即位于调用 此异常函数的母函数体内,反复重复上一过程,即获得了导致此异 常的函lt流禾呈里的所有函凄t返回;也址。此外,根据获取的返回指令在符号表中查找相应的函数的处理 具体为将符号表中小于并且最接近于返回地址的函数地址作为对 应于该返回地址的函数地址,并根据函数地址找到相应函数。至此,如果只是简单的将各个函数返回地址打印出来,对开发 人员仍然不方便,依然存在繁瑣和不直观的问题,而对照符号表就可以将函数返回地址对应的函数名查找出来,这样通过将各个函数 名打印出来就可以对出现故障的流程里的各个函数一 目了然。具体地,可以找到此进程存放在文件系统里的可执行文件,打 开,按照可执行文件格式找到符号表,通过函数地址查找符号表找 到函数名。前面获得的是函数返回地址,并非函数起始地址,而函数符号对应的是函数起始地址,可以采用如下算法在符号表里, 搜索比返回地址值小并且两者间距最小的符号地址即为函数符号。图2是根据相关技术的mips栈帧的结构示意图。下面,将结合 图2描述根据本实施例的对MIPS堆栈回溯定位故障的方法。Leaf函数是指内部没有调用其他函数的函数。函数调用leaf函 数时返回地址保存于ra中,在leaf函数里因为无需再调用其他函数, 所以通常ra无需压一戋,可以直4妄乂人ra中获4寻返回i也址。Leaf函彰: 是否需要建立堆栈是依据具体函数的,mips的gCC编译器在函数入口一次性的为此函数分配堆栈大小。如图2所示,堆栈大小包括三 部分为函ft内临时变量分配空间、 一些内部寄存器保存、为内部 4皮调用函数建立参数的空间。mips有32个内部寄存器,内部寄存 器可以做为临时变量,做被调用函数输入参数等,前提是这些寄存 器器够用,所以并非每个函数编译器都会为其建立堆栈。Nonleaf函数为内部调用了其他函数的函数,nonleaf函数通常 在函数入口处要建立堆栈,因为至少ra需要保存于堆栈中。建立堆栈的做法是编译器计算出要为此函数分配的堆栈大小, 然后一次性设定,在函lt入口处将sp减去此堆栈大小,然后所有在 堆栈中的数据都通过Sp加上固定的偏移量来获取,在函凄t出口处将 sp加上堆栈大小恢复前一堆栈值。Mips指令为32bit长,里面包含操作码(opcode ),操作寄存器, 操作数等,每条指令都有其固定编码格式,将32bit的指令与特定掩 码相与提取出操作数,操作寄存器等,则可以确定此指令。下面的 搜索指令均采用此方法。才艮据pc值在用户进程程序空间中往前4臾索如果搜索到swra, x(sp),这条指令指出ra保存于堆栈sp+x处, 从指令提取出偏移量x,而一个函数的sp是固定指向此函数堆栈顶 的,所以从堆栈sp+x处可以取处保存的ra值,而ra里存方文的是此 函凄t的返回地J止。如果没有搜索到sw ra, x(sp),则表明此函数没有保存m于堆 栈里,则ra里存放的就是返回地址,从寄存器器ra里直接可以获得 函凄t返回i也址。如果搜索到addiusp, sp, +-offset指令,这条指令通常位于函 数入口最开始处由编译器用来为此函数分配堆栈大小,在函数返回 之前由编译器回收堆栈。异常通常发生在用户代码里,而我们是根 据pc往前4叟索,所以4臾索到的应该是addiusp, sp, -offset, 乂人此 指令中提取立即数offset,此即为此函数栈帧大小。如果没有4臾索到 此指令,表示此函数没有分配堆栈,则下一函数堆栈指针依然为此 sp值。直到搜索到另一个函数体内肯定是错误的为止,有两个结束条 件 一个是搜索到addiu sp, sp, -offset指令。 一个是搜索到jr ra 指令,jr ra是每个函数的返回指令,如果搜索到此指令表示已搜索 脱离了本函数,进入此函数相邻的函数里了 ,则此时搜索应该结束。上述操作的输入是当前函数体内的一个pc值;当前函数的堆 栈起始地址sp。输出是调用此函数的返回地址,此返回地址位于调用函数的地址范围内;当前函数堆栈大小,加上当前堆栈起始地 址,即,获得调用函数的堆栈起始地址。将输出再次作为输入,重 复上述过程就可以获得一个完整的调用链里所有函凄t体内的一个地 址值。进程在内核的进程控制块里保存有进程的用户空间堆栈开始地 址;用户空间程序开始及结束地址,上述循环搜索始终判断获得函 数堆栈地址,函数地址是否在范围之类,如果不在,循环4臾索结束。可执行文件格式很多,本实施例以ELF格式为例进行说明。 找到此进程在文件系统里的elf文件,打开,按照elf文件格式,提 取出4个section: .dynsym、 .symtab、 .dynstr、 .strtab、 .dynsym, 其 中,.symtab为符号表,.dynstr和.strtab为符号对应字符串。其中,符号表里每个符号对应的数据结构为 typedef structElf32—Word st—name;/*符号名索引号*/ Elf32—Addr st—value;/*才寻号;也址^f直*/ Elfi2—Word st—size;/*符号对应的代码长度*/ unsigned char st—info;/*符号类型和4邦定4言息*/ unsigned char st一other; /*未用,值为0 */ Elf32—Section st—shndx;/*所在节的节索引号*/} Elf32—Sym;前面搜索出的是一条返回地址链,并非每个函数的初始地址, 返回地址位于每个函数地址范围内,可以采用如下算法计算处函数 初始地址在符号表里,搜索比返回地址值小并且两者间距最小的 符号i也址(即st—value)即为函凄t初始i也址,它对应的st_name为符 号名索引号,通过此索引号到.dynstr节或.strtab节即可以获得每个 函数的符号名。将每个函数的符号名逐一打印出来就可以看到异常发生时整个 调用关系里的所有函数名,定位故障位置直^L、方遍、并且迅速。装置实施例在本实施例中,提供了一种故障定位装置,用于对无内部互锁 流水级的;f效处理器的堆栈进行故障定位。图3为这种故障定位装置的流程图,如图3所示,该装置包括第一获取模块302,用于在由于函数调用异常导致进程出现异 常的情况下,在程序空间中获取异常进程的程序指针的值和堆栈指 针的值;第二获取模块304,用于根据获取的程序指针的值和堆栈 指针的值获取堆栈指针指向的当前函数堆栈的大小以及当前函数堆 栈的栈帧中所存储的返回指令;以及根据当前函数堆栈的大小和堆 栈指针的值获取当前函数堆栈之后的函数堆栈的栈帧中存储的函数 的返回指令;查找模块306,用于查找异常进程的可4丸行文件,并 根据查找的可执行文件查找异常进程的符号表,根据在当前栈帧和 其它栈帧中获取的返回指令在符号表中查找相应的函数。其中,第二获取模块304获取当前函数堆栈之后的函数堆栈的 栈帧中存储的函数的返回指令的处理具体为确定当前堆栈指针的值;获取当前函数堆栈中存储的返回地址;确定当前函数堆栈的大 小;将确定的值和大小相加,将相加的结果作为当前函数堆栈的下 一个函数堆栈的栈帧地址,并将下一个函数堆栈作为当前函数堆栈。该装置还包括判断模块,用于在每次获取了一个函数堆栈的 栈帧中存储的函数的返回指令后,判断获取的返回指令所对应的函 数是否在调用异常的函数体内,如果判断为是,则继续查找下个函 数堆栈;否则停止查找函数堆栈。判断模块进行的判断处理具体为 获取当前获取的函数堆栈的地址,并从程序空间获取该函lt堆栈的 大小,并根据当前获取的函数堆栈的地址和大小判断其是否在函数 体范围内。此外,查找模块306根据获取的返回指令在符号表中查找相应 的函数时所执行的处理具体为将符号表中小于并且最接近于返回 地址的函数地址作为对应于该返回地址的函数地址,并才艮据函数地 址找到相应函数。综上所述,本发明能够通过堆栈回溯的方法,乂人可执4亍文件里 直接提取出符号表查找以找到函数名。借助于本发明的技术方案, 能够有效实现自动化的故障定位,大大"t是高了调试和故障定位的效 率,简化了故障定位的操作,并且使故障定位的操作结果更加直观。以上所述^f又为本发明的优选实施例而已,并不用于限制本发明, 对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在 本发明的精神和原则之内,所作的任何修改、等同替换、改进等, 均应包含在本发明的保护范围之内。
权利要求
1. 一种故障定位方法,用于对无内部互锁流水级的微处理器的堆栈进行故障定位,其特征在于,所述方法包括在由于函数调用异常导致进程出现异常的情况下,在程序空间中获取异常进程的程序指针的值和堆栈指针的值;根据获取的所述程序指针的值和所述堆栈指针的值获取所述堆栈指针指向的当前函数堆栈的大小以及所述当前函数堆栈的栈帧中所存储的返回指令;根据所述当前函数堆栈的大小和所述堆栈指针的值获取所述当前函数堆栈之后的函数堆栈的栈帧中存储的函数的返回指令;查找所述异常进程的可执行文件,并根据查找的所述可执行文件查找所述异常进程的符号表,根据在当前栈帧和其它栈帧中获取的所述返回指令在所述符号表中查找相应的函数。
2. 根据权利要求1所述的方法,其特征在于,获取所述当前函数 堆栈之后的函数堆栈的栈帧中存储的函数的返回指令的处理 具体为确定当前堆栈指针的值;获取所述当前函数堆栈中存储的返回地址;确定当前函数堆栈的大小;将确定的所述值和所述大小相加,将相加的结果作为所述 当前函数堆栈的下一个函tt堆栈的栈帧地址,并将所述下一个 函数堆栈作为所述当前函数堆栈。
3. 根据权利要求2所述的方法,其特征在于,在每次获取了一个 函数堆栈的栈帧中存储的函数的返回指令后,进一步包括判断获取的所述返回指令所对应的函数是否在调用异常 的函数体内,如果判断为是,则继续查找下个函数堆栈;否则 停止查找函数堆栈。
4. 根据权利要求3所述的方法,其特征在于,进行所述判断的处 理具体为获取当前获取的所述函数堆栈的地址,并乂人所述程序空间 获取该函数堆栈的大小,并根据所述当前获取的所述函数堆栈 的地址和大小判断其是否在所述函数体范围内。
5. 根据权利要求1至4中任一项所述的方法,其特征在于,根据 获取的所述返回指令在所述符号表中查找相应的函数的处理 具体为将所述符号表中小于并且最接近于所述返回地址的函数 地址作为对应于该返回地址的函数地址,并一艮据所述函ft地址 ^戈到相应函凄文。
6. —种故障定位装置,用于对无内部互锁流水级的孩t处理器的堆 栈进行故障定位,其特征在于,所述装置包括第 一获取模块,用于在由于函数调用异常导致进程出现异 常的情况下,在程序空间中获取异常进程的程序指针的值和堆 栈指针的值;第二获取模块,用于根据获取的所述程序指针的值和所述 堆栈指针的值获取所述堆栈指针指向的当前函数堆栈的大小 以及所述当前函数堆栈的栈帧中所存储的返回指令;以及根据 所述当前函数堆栈的大小和所述堆栈指针的值获取所述当前 函数堆栈之后的函数堆栈的栈帧中存4诸的函凌t的返回指令;查找模块,用于查找所述异常进程的可执行文件,并根据 查找的所述可执行文件查找所述异常进程的符号表,根据在当 前栈帧和其它栈帧中获取的所述返回指令在所述符号表中查 才戈才目应的函凄t。
7. 根据权利要求6所述的装置,其特征在于,所述第二获取模块 获取所述当前函数堆栈之后的函数堆栈的栈帧中存储的函数 的返回指令的处理具体为确定当前堆栈指针的值;获取所述当前函数堆栈中存储的返回地址;确定当前函数堆栈的大小;将确定的所述值和所述大小相力。,将相加的结果作为所述 当前函数堆栈的下一个函数堆栈的栈帧地址,并将所述下一个 函数堆栈作为所述当前函数堆栈。
8. 根据权利要求7所述的装置,其特征在于,进一步包括判断模块,用于在每次获取了 一个函数堆栈的栈帧中存储 的函数的返回指令后,判断获取的所述返回指令所对应的函数 是否在调用异常的函数体内,如果判断为是,则继续查找下个 函数堆栈;否则停止查找函数堆栈。
9. 根据权利要求8所述的装置,其特征在于,所述判断模块进行 的判断处理具体为获耳又当前获取的所述函凄t堆栈的地址,并/人所述程序空间 获取该函数堆栈的大小,并根据所述当前获取的所述函数堆栈 的地址和大小判断其是否在所述函数体范围内。
10. 根据权利要求6至9中任一项所述的装置,其特征在于,所述 查找模块根据获取的所述返回指令在所述符号表中查找相应 的函数时所执行的处理具体为将所述符号表中小于并且最接近于所述返回地址的函f欠 地址作为对应于该返回地址的函凄史地址,并4艮据所述函凄t地址 找到相应函凄史。
全文摘要
本发明公开了一种故障定位的方法,该方法包括在由于函数调用异常导致进程出现异常的情况下,在程序空间中获取异常进程的程序指针的值和堆栈指针的值;根据获取的程序指针的值和堆栈指针的值获取堆栈指针指向的当前函数堆栈的大小以及当前函数堆栈的栈帧中所存储的返回指令;根据当前函数堆栈的大小和堆栈指针的值获取当前函数堆栈之后的函数堆栈的栈帧中存储的函数的返回指令;查找异常进程的可执行文件,并根据查找的可执行文件查找异常进程的符号表,根据在当前栈帧和其它栈帧中获取的返回指令在符号表中查找相应的函数。此外,本发明还公开了一种故障定位的装置。
文档编号G06F11/36GK101261603SQ20081008991
公开日2008年9月10日 申请日期2008年4月9日 优先权日2008年4月9日
发明者朱怀云, 李金虎 申请人:中兴通讯股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1