Posted on 2010-07-21 16:27
startpoint 阅读(503)
评论(0) 编辑 收藏 所属分类:
系统虚拟化
我们知道在xen在crash的时候会出现一段call trace,往往我们能从这个call trace里面找到bug发生在哪里。但是对于那些没有使xen crash掉的bug我们怎么办呢?我找到一个方便的方法,利用xen现有的代码——show_trace function。代码如下:
1 static void show_trace(struct cpu_user_regs *regs)
2 {
3 unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
4
5 printk("Xen call trace:\n ");
6
7 printk("[<%p>]", _p(regs->eip));
8 print_symbol(" %s\n ", regs->eip);
9
10 while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
11 {
12 addr = *stack++;
13 if ( is_kernel_text(addr) || is_kernel_inittext(addr) )
14 {
15 printk("[<%p>]", _p(addr));
16 print_symbol(" %s\n ", addr);
17 }
18 }
19
20 printk("\n");
21 }
这里面大部分代码都不需要修改的,可以被重用,只是如果获取rsp(x86_64)的方法得变一下。原函数是又上层传递下来的,我们则需要从当前寄存器里面读取出来,那么如果将一个寄存器的值存到变量里面呢?用GCC inline assembly,代码如下:
1 unsigned long *stack;
2 asm volatile ("movq %%rsp, %0": "=r"(stack))
;
;
我们用上面的方法就可以获取rsp寄存器的值了,读取的值被放在stack变量当中。
一切搞定,我们现在就可以用这个我们新创造出来的方法进行call trace的打印了。