﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-起点-文章分类-系统虚拟化</title><link>http://www.blogjava.net/rogershijicheng/category/45663.html</link><description>梦的开始</description><language>zh-cn</language><lastBuildDate>Thu, 22 Jul 2010 21:28:07 GMT</lastBuildDate><pubDate>Thu, 22 Jul 2010 21:28:07 GMT</pubDate><ttl>60</ttl><item><title>Xen 获取call trace 的方法</title><link>http://www.blogjava.net/rogershijicheng/articles/326767.html</link><dc:creator>startpoint</dc:creator><author>startpoint</author><pubDate>Wed, 21 Jul 2010 08:27:00 GMT</pubDate><guid>http://www.blogjava.net/rogershijicheng/articles/326767.html</guid><wfw:comment>http://www.blogjava.net/rogershijicheng/comments/326767.html</wfw:comment><comments>http://www.blogjava.net/rogershijicheng/articles/326767.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/rogershijicheng/comments/commentRss/326767.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/rogershijicheng/services/trackbacks/326767.html</trackback:ping><description><![CDATA[<span class="Apple-tab-span" style="white-space:pre">  </span>我们知道在xen在crash的时候会出现一段call trace，往往我们能从这个call trace里面找到bug发生在哪里。但是对于那些没有使xen crash掉的bug我们怎么办呢？我找到一个方便的方法，利用xen现有的代码——show_trace function。代码如下：
<div id="">
<div style="font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; " id=""><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;show_trace(</span><span style="color: #0000FF; ">struct</span><span style="color: #000000; ">&nbsp;cpu_user_regs&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">regs)<br />
</span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #000000; ">{<br />
</span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: #0000FF; ">long</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">stack&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;ESP_BEFORE_EXCEPTION(regs),&nbsp;addr;<br />
</span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;printk(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">Xen&nbsp;call&nbsp;trace:\n&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;printk(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">[&lt;%p&gt;]</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;_p(regs</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">eip));<br />
</span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;print_symbol(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;%s\n&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;regs</span><span style="color: #000000; ">-&gt;</span><span style="color: #000000; ">eip);<br />
</span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">while</span><span style="color: #000000; ">&nbsp;(&nbsp;((</span><span style="color: #0000FF; ">long</span><span style="color: #000000; ">)stack&nbsp;</span><span style="color: #000000; ">&amp;</span><span style="color: #000000; ">&nbsp;(STACK_SIZE</span><span style="color: #000000; ">-</span><span style="color: #000000; ">BYTES_PER_LONG))&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">0</span><span style="color: #000000; ">&nbsp;)<br />
</span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addr&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">stack</span><span style="color: #000000; ">++</span><span style="color: #000000; ">;<br />
</span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(&nbsp;is_kernel_text(addr)&nbsp;</span><span style="color: #000000; ">||</span><span style="color: #000000; ">&nbsp;is_kernel_inittext(addr)&nbsp;)<br />
</span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
</span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printk(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">[&lt;%p&gt;]</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;_p(addr));<br />
</span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print_symbol(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;%s\n&nbsp;&nbsp;&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,&nbsp;addr);<br />
</span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #000000; "><br />
</span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;printk(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">\n</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
</span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #000000; ">}</span></div>
</div>
<div id="">这里面大部分代码都不需要修改的，可以被重用，只是如果获取rsp(x86_64)的方法得变一下。原函数是又上层传递下来的，我们则需要从当前寄存器里面读取出来，那么如果将一个寄存器的值存到变量里面呢？用GCC inline assembly，代码如下：</div>
<div id="">
<div style="font-size: 13px; border-left-color: #cccccc; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; " id=""><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">1</span>&nbsp;<span style="color: #000000; ">unsigned&nbsp;</span><span style="color: #0000FF; ">long</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">*</span><span style="color: #000000; ">stack;<br />
</span><span style="color: #008080; ">2</span>&nbsp;<span style="color: #000000; ">asm&nbsp;</span><span style="color: #0000FF; ">volatile</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">movq&nbsp;%%rsp,&nbsp;%0</span><span style="color: #000000; ">"</span><span style="color: #000000; ">:&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">=r</span><span style="color: #000000; ">"</span><span style="color: #000000; ">(stack))
<div style="display: inline; height: auto; position: absolute; visibility: hidden; width: auto; ">;</div>
;</span></div>
</div>
<div id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown">我们用上面的方法就可以获取rsp寄存器的值了，读取的值被放在stack变量当中。</div>
<div id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown">一切搞定，我们现在就可以用这个我们新创造出来的方法进行call trace的打印了。</div>
<img src ="http://www.blogjava.net/rogershijicheng/aggbug/326767.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/rogershijicheng/" target="_blank">startpoint</a> 2010-07-21 16:27 <a href="http://www.blogjava.net/rogershijicheng/articles/326767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>