BlogJava-起点-文章分类-系统虚拟化http://www.blogjava.net/rogershijicheng/category/45663.html梦的开始zh-cnThu, 22 Jul 2010 21:28:07 GMTThu, 22 Jul 2010 21:28:07 GMT60Xen 获取call trace 的方法http://www.blogjava.net/rogershijicheng/articles/326767.htmlstartpointstartpointWed, 21 Jul 2010 08:27:00 GMThttp://www.blogjava.net/rogershijicheng/articles/326767.htmlhttp://www.blogjava.net/rogershijicheng/comments/326767.htmlhttp://www.blogjava.net/rogershijicheng/articles/326767.html#Feedback0http://www.blogjava.net/rogershijicheng/comments/commentRss/326767.htmlhttp://www.blogjava.net/rogershijicheng/services/trackbacks/326767.html 我们知道在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的打印了。


startpoint 2010-07-21 16:27 发表评论
]]>