在遇上一些偶尔才能出现的bug的时候, 根据寄存器的相关信息结合汇编语句, 可以迅速定位到问题, 提高debug的效率.
正好今天项目上报了一个bug, 死机的, 用这个方法很快定位到问题.
死机的一些打印:
#AP!# exception!
Coprocessor Unusable exception
EPC[0x80240760], CAUSE[0x1080002c], SR[0xff03], SP[0x80c0b558]!
showcs 80240760 80c0b558 80103510
OSIntNesting=0 OSLockNesting=0
先看寄存器:
ra:[0x8010351] epc[0x80240760] fp:[0x80034e70] gp:[0x80618b48] at:[0xfffffffe]
t9:[0x8001306] t8:[0x00000008] t7:[0x00000000] t6:[0x00000005] t5:[0x00000000]
t4:[0x816baff] t3:[0x00000000] t2:[0x00000000] t1:[0x80fbd330] t0:[0x806f0000]
s7:[0x8023f55] s6:[0x80034ed0] s5:[0x80c0c27c] s4:[0x8111fdb0] s3:[0x80c0be28]
s2:[0x0000000] s1:[0x80c0b6c4] s0:[0x800341f0]
a3:[0x80c0b4c] a2:[0x000000fe] a1:[0x80c0b588] a0:[0x00000000]
v1:[0x8024075] v0:[0x000000fe]
注意这边的a0寄存器.
相应的汇编:
80240758 <xxxx_func>:
80240758: 27bdffe8 addiu sp,sp,-24
8024075c: afbf0014 sw ra,20(sp)
80240760: 90830204 lbu v1,516(a0) //这边有问题
80240764: 3c0280ab lui v0,0x80ab
80240768: 2442b778 addiu v0,v0,-18568
8024076c: 00033180 sll a2,v1,0x6
80240770: 00031900 sll v1,v1,0x4
由于a0一般用来做参数传递, 所以检查这个函数的参数的定义.
typedef struct
{
void *dir;
tchar_t name[256];
u8 use_logic; //正好是516的偏移
u32 file_num;
}xxx;
结合函数中的语句, 有p_dj->use_logic的操作, 因此这个死机是由于传递的这个参数是NULL导致的.
==============================下面是网上找的mips寄存器的介绍================================
表格来自 http://blog.sina.com.cn/s/blog_6cf6b58d0100lot7.html
;REGISTER |
NAME |
USAGE |
$0 |
$zero |
常量0(constant value 0) |
$1 |
$at |
保留给汇编器(Reserved for assembler) |
$2-$3 |
$v0-$v1 |
函数调用返回值(values for results and expressionevaluation) |
$4-$7 |
$a0-$a3 |
函数调用参数(arguments) |
$8-$15 |
$t0-$t7 |
暂时的(或随便用的) |
$16-$23 |
$s0-$s7 |
保存的(或如果用,需要SAVE/RESTORE的)(saved) |
$24-$25 |
$t8-$t9 |
暂时的(或随便用的) |
$28 |
$gp |
全局指针(Global Pointer) |
$29 |
$sp |
堆栈指针(Stack Pointer) |
$30 |
$fp |
帧指针(Frame Pointer) |
$31 |
$ra |
返回地址(return address) |