我們知道在xen在crash的時候會出現(xiàn)一段call trace,往往我們能從這個call trace里面找到bug發(fā)生在哪里。但是對于那些沒有使xen crash掉的bug我們怎么辦呢?我找到一個方便的方法,利用xen現(xiàn)有的代碼——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 }
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)的方法得變一下。原函數(shù)是又上層傳遞下來的,我們則需要從當(dāng)前寄存器里面讀取出來,那么如果將一個寄存器的值存到變量里面呢?用GCC inline assembly,代碼如下:
1 unsigned long *stack;
2 asm volatile ("movq %%rsp, %0": "=r"(stack)) ;
2 asm volatile ("movq %%rsp, %0": "=r"(stack)) ;
我們用上面的方法就可以獲取rsp寄存器的值了,讀取的值被放在stack變量當(dāng)中。
一切搞定,我們現(xiàn)在就可以用這個我們新創(chuàng)造出來的方法進(jìn)行call trace的打印了。