??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品无码久久青草,亚洲Av无码国产情品久久,久久久久久精品久久久久http://www.shnenglu.com/tqsheng/category/19662.htmlgo.....zh-cnSun, 15 Jul 2012 07:44:30 GMTSun, 15 Jul 2012 07:44:30 GMT60?Graphviz 可视化函数调?/title><link>http://www.shnenglu.com/tqsheng/archive/2012/07/15/183549.html</link><dc:creator>tqsheng</dc:creator><author>tqsheng</author><pubDate>Sun, 15 Jul 2012 06:58:00 GMT</pubDate><guid>http://www.shnenglu.com/tqsheng/archive/2012/07/15/183549.html</guid><wfw:comment>http://www.shnenglu.com/tqsheng/comments/183549.html</wfw:comment><comments>http://www.shnenglu.com/tqsheng/archive/2012/07/15/183549.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/tqsheng/comments/commentRss/183549.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/tqsheng/services/trackbacks/183549.html</trackback:ping><description><![CDATA[<span style="font-family: Simsun; line-height: normal; background-color: #ffffff; font-size: medium; "><div class="u8ya00g" id="dw-summary-article" style="width: 930px; background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ffffff), to(#ececec)); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; margin-top: 3px; border-bottom-color: #cccccc; border-bottom-style: solid; border-bottom-width: 1px; background-position: initial initial; background-repeat: initial initial; "><div style="padding-top: 10px; padding-right: 10px; padding-left: 10px; "><h1>?Graphviz 可视化函数调?/h1><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 1em; padding-left: 4px; "><em style="font-family: verdana, sans-serif; font-weight: bold; font-size: 1.1em; font-style: normal; color: #666666; ">使用开源Y件来化复杂调用结?/em></p></div><div ibm-two-column"="" style="overflow-x: visible; overflow-y: visible; height: 240px; "><div ibm-first"="" style="width: 500px; float: left; padding-left: 14px; margin-bottom: 10px; "><div style="font-size: 0.76em; font-family: arial, sans-serif; "><a rel="#authortip1" style="color: #4c6e94; ">M. Tim Jones</a>, 资深软g工程? Emulex</div><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 1em; padding-left: 0em; "></p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 1em; padding-left: 0em; "><strong>介:(x)</strong> ׃些时间遍历一下源代码Q可以向(zhn)展现所有的函数调用q程Q但是如果函数指针非常复杂,或者代码太长且晦ӆ难懂Q那么这个过E就可能更加困难了。本文将向?zhn)介绍如何使用开源Y件和一些定制的代码来构Z个动态的囑Ş函数调用生成器?/p><div class="omyiu80" id="dw-tag-content"><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 0px; padding-left: 0em; line-height: 20px; "><strong style="font-size: 1em; ">本文的标{:(x)</strong>  <a style="color: #4c6e94; text-decoration: none; ">代码?/a>, <a style="color: #4c6e94; text-decoration: none; ">囑Ş?/a>, <a style="color: #4c6e94; text-decoration: none; ">开放源?/a>, <a style="color: #4c6e94; text-decoration: none; ">调试</a></p></div><div class="8muo0sc" id="dw-moretags-access" style="position: absolute; left: -3000px; width: 500px; "></div><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 1em; padding-left: 0em; "></p><div class="o8m0iue" id="dw-tag-this" style="background-image: url(http://dw1.s81c.com/developerworks/i/dwtag_icon_maverick.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-size: 0.76em; font-family: arial, sans-serif; display: inline; background-position: 2px 0px; background-repeat: no-repeat no-repeat; "><a style="color: #4c6e94; text-decoration: none; background-image: url(http://dw1.s81c.com/developerworks/i/dwtag_icon_maverick.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 19px; margin-left: 2px; margin-right: 18px; font-weight: bold !important; background-position: 0px 0px; background-repeat: no-repeat no-repeat; ">标记本文Q?/a></div><div class="086kiiq" id="interestShow" style="display: inline; "></div><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 1em; padding-left: 0em; "></p></div><div ibm-second"="" style="width: 380px; float: right; padding-right: 10px; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 1em; padding-left: 0em; line-height: 25px; "><strong style="font-size: 1em; ">发布日期Q?/strong> 2005 q?7 ?11 ?nbsp;<br /><strong style="font-size: 1em; ">U别Q?/strong> 初 <br /><strong>讉K情况 Q?/strong> 12381 ơ浏?nbsp;<br /><strong>评论Q?/strong> <span id="nCmts">1 (<a style="padding-top: 0px; padding-right: 0px; padding-bottom: 3px; padding-left: 15px; background-image: url(http://www.ibm.com/i/v16/icons/d_bold.gif); margin-left: -4px; color: #4c6e94; background-repeat: no-repeat no-repeat; ">查看</a> | <a style="color: #4c6e94; ">d评论</a> - d)</span></p><div class="msa88ay" id="art-rating-summary" style="font-family: arial, sans-serif !important; font-size: 0.76em !important; "><img alt="q_?5 ??19 个评? src="http://dw1.s81c.com/developerworks/i/stars120x20-5b.jpg" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0px !important; padding-right: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; vertical-align: -4px; " /> q_?(19个评?<br /><a style="padding-top: 0px; padding-right: 0px; padding-bottom: 3px; padding-left: 15px; background-image: url(http://www.ibm.com/i/v16/icons/d_bold.gif); margin-left: -4px; color: #4c6e94; background-repeat: no-repeat no-repeat; ">为本文评?/a></div><br /><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; margin-top: 0em; margin-right: 0em; margin-bottom: 0em; margin-left: 0em; padding-top: 0em; padding-right: 0em; padding-bottom: 1em; padding-left: 0em; "></p></div></div></div><div class="8uyma60" id="ibm-content-body" style="background-image: none; background-attachment: scroll; width: 930px; padding-top: 15px; padding-bottom: 15px; clear: both; background-position: 0px 0px; background-repeat: no-repeat no-repeat; "><div class="6qug8iq" id="ibm-content-main" style="float: left; clear: left; width: 710px; padding-left: 10px; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 0px; width: 710px; "><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">可以以囑Ş形式查看应用E序的调用过E看作是一个学?fn)经历。这样做可以帮助(zhn)理解应用程序的内部行ؓ(f)Qƈ获得有关E序优化斚w的信息。例如,通过寚w些经常调用的函数q行优化Q?zhn)可以用最的努力来获得最佳的性能。另外,调用跟踪q可以判断用户函数的最大调用深度,q可以用来对调用栈用的内存q行有效限制Q在嵌入式系l中Q这是非帔R要的一个考虑因素Q?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Z捕获q显C用图Q?zhn)需?4 个元素:(x)GNU ~译器工具链、Addr2line 工具、定制的中间代码和一个名?Graphviz 的代码。Addr2line 工具可以识别函数、给定地址的源代码行数和可执行映像。定制的中间代码是一个非常简单的工具Q它可以减少对图形规范的地址跟踪。Graphviz 工具可以生成囑Ş映像。整个过E如?1 所C?/p><br /><a name="N10064"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">?1. 搜集、简化和可视化跟t\径的q程</strong></a><br /><img alt="跟踪q程" height="407" src="http://www.ibm.com/developerworks/cn/linux/l-graphvis/figure1.gif" width="407" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " /> <br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N10073"><span style="font-size: 1.5em; font-weight: bold; ">数据搜集Q捕获函数调用\?/span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">要收集一个函数调用的t迹Q?zhn)需要确定每个函数在应用E序中调用的旉。在q去Q都是通过在函数的入口处和退出处插入一个惟一的符h手工(g)每个函数的。这个过E非常繁琐,而且很容易出错,通常需要对源代码进行大量的修改?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">q运的是QGNU ~译器工具链Q也UCؓ(f) <em>gcc</em>Q提供了一U自动检应用程序中的各个函数的Ҏ(gu)。在执行应用E序Ӟ可以收集相关的分析数据。?zhn)只需要提供两个特D的分析函数卛_。其中一个函数在每次执行惌跟踪的函数时都会(x)调用Q而另外一个函数则在每ơ退出想要跟t的函数时调用(参见清单 1Q。这两个函数都是特别指定的,因此Q编译器可以识别它们?/p><br /><a name="N10087"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">清单 1. GNU 的入口和出口配置函数</strong></a><br /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-style: solid; border-color: #cccccc; padding: 2px 2px 5px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; "> void __cyg_profile_func_enter( void *func_address, void *call_site ) __attribute__ ((no_instrument_function)); void __cyg_profile_func_exit ( void *func_address, void *call_site ) __attribute__ ((no_instrument_function)); </pre></td></tr></tbody></table><br /><div ibm-alt-header="" dw-container-sidebar"="" style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 10px; width: 320px; float: right; "><h2>避免使用Ҏ(gu)的检函?/h2><div style="background-image: url(http://1.www.s81c.com/i/v16/t/container-gradient.gif); border-bottom-color: #cccccc; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #cccccc; border-left-style: solid; border-left-width: 1px; border-right-color: #cccccc; border-right-style: solid; border-right-width: 1px; font-size: 0.76em; font-family: arial, sans-serif; padding: 5px; background-position: 0px 100%; background-repeat: repeat no-repeat; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">(zhn)或怼(x)产生疑惑Q如?gcc 是我们需要的(g)函敎ͼ那么Z么它不检?code style="font-size: small !important; ">__cyg_*</code> 分析函数呢?gcc 的开发者曾思考过q个问题Q他们提供了一个名?code style="font-size: small !important; ">no_instrument_function</code> 的函数属性,q个函数属性可以应用于函数原型Q禁止对它们q行(g)。不要将q个函数属性应用到分析函数上,q样?x)导致无限递归分析循环和大量的无用数据?/p></div></div><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">在调用一个检函数时Q?code style="font-size: small !important; ">__cyg_profile_func_enter</code> 同时也会(x)被调用,q以 <code style="font-size: small !important; ">func_address</code> 形式传递调用的函数地址Q以?qing)从中调用该函数?nbsp;<code style="font-size: small !important; ">call_site</code> 形式的地址。反之,当一个函数退出时Q也?x)调?code style="font-size: small !important; ">__cyg_profile_func_exit</code> 函数Qƈ传?nbsp;<code style="font-size: small !important; ">func_address</code> 形式的函数地址Q以?qing)函C中退出的真实地址Q该地址的表CŞ式ؓ(f) <code style="font-size: small !important; ">call_site</code>?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">在这些分析函CQ?zhn)可以记录下地址对,以供以后再进行分析用。要h gcc 所有的(g)函敎ͼ每个文g都必M?nbsp;<code style="font-size: small !important; ">-finstrument-functions</code> ?nbsp;<code style="font-size: small !important; ">-g</code>选项q行~译Q这样可以保留调试符受?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">因此Q现在?zhn)可以?f) gcc 提供一些分析函CQ这些函数可以透明地插入应用程序中的函数入口点和函数退出点。但在调用分析函数时Q又应该怎样处理所提供的地址呢?(zhn)有很多选择Q但是ؓ(f)了简便v见,可以这个地址单地写入一个文Ӟ要注意哪个地址是函数的入口地址Q哪个地址是函数的出口地址Q参见清?2Q?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><strong>注意Q?/strong>在清?2 中ƈ没有使用调用 Callsite 信息Q因些信息对于分析程序来说是不必要的?/p><br /><a name="N100D5"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">清单 2. 分析函数</strong></a><br /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-style: solid; border-color: #cccccc; padding: 2px 2px 5px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; "> void __cyg_profile_func_enter( void *this, void *callsite ) { /* Function Entry Address */ fprintf(fp, "E%p\n", (int *)this); } void __cyg_profile_func_exit( void *this, void *callsite ) { /* Function Exit Address */ fprintf(fp, "X%p\n", (int *)this); } </pre></td></tr></tbody></table><br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">现在(zhn)可以搜集分析数据了Q但是?zhn)应该在什么地Ҏ(gu)开或关闭?zhn)的跟t输出文件呢Q到现在为止Q还不需要ؓ(f)了进行分析而对源程序进行Q何修攏V因此,(zhn)该如何(g)整个应用程序(包括 <code style="font-size: small !important; ">main</code> 函数Q而不用对分析数据的输出结果进行初始化呢?gcc 的开发者也考虑q这个问题,它们?nbsp;<code style="font-size: small !important; ">main</code> 函数?constructor 函数?destructor 函数提供了一些碰巧能够满个要求一些方法?code style="font-size: small !important; ">constructor</code> 函数是在调用 <code style="font-size: small !important; ">main</code> 函数之前调用的,?nbsp;<code style="font-size: small !important; ">destructor</code> 函数则是在应用程序退出时调用的?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">要创?constructor ?destructor 函数Q则需要声明两个函敎ͼ然后对这两个函数应用<code style="font-size: small !important; ">constructor</code> ?nbsp;<code style="font-size: small !important; ">destructor</code> 函数属性。在 <code style="font-size: small !important; ">constructor</code> 函数中,?x)打开一个新的跟t文Ӟ分析数据的地址跟踪是写入q个文g的;?nbsp;<code style="font-size: small !important; ">destructor</code> 函数中,?x)关闭这个跟t文Ӟ参见清单 3Q?/p><br /><a name="N1010A"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">清单 3. 分析 constructor ?destructor 函数</strong></a><br /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-style: solid; border-color: #cccccc; padding: 2px 2px 5px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; "> /* Constructor and Destructor Prototypes */ void main_constructor( void ) __attribute__ ((no_instrument_function, constructor)); void main_destructor( void ) __attribute__ ((no_instrument_function, destructor)); /* Output trace file pointer */ static FILE *fp; void main_constructor( void ) { fp = fopen( "trace.txt", "w" ); if (fp == NULL) exit(-1); } void main_deconstructor( void ) { fclose( fp ); } </pre></td></tr></tbody></table><br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">如果~译分析函数Q在 instrument.cQƈ它们与目标应用E序链接在一P然后再执行目标应用程序,l果?x)生成一个应用程序的调用q踪Q追t记录被写入 <em>trace.txt</em> 文g。跟t文件与调用的应用程序处于相同的目录中。最l结果是Q?zhn)可能会(x)得C个其中满是地址的非常大的文件。ؓ(f)了能够让q些数据更有意义Q?zhn)可以使用一个不太出名的叫做 Addr2line ?GNU 工具?/p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); height: 1px; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 21px; "><a style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页?/a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N10117"><span style="font-size: 1.5em; font-weight: bold; ">使用 Addr2line 函数地址解析为函数名</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Addr2line 工具Q它是标准的 GNU Binutils 中的一部分Q是一个可以将指o(h)的地址和可执行映像转换成文件名、函数名和源代码行数的工兗这U功能对于将跟踪地址转换成更有意义的内容来说直是太棒了?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">要了解这个过E是怎样工作的,我们可以试验一个简单的交互式的例子。(我直接从 shell 中进行操作,因ؓ(f)q是最单地展示q个q程的方法,如清?4 所C。)q个CZ C 文gQtest.cQ是通过 <code style="font-size: small !important; ">cat</code> 一个简单的应用E序实现的(也就是说Q将标准输出的文本重定向C个文件中Q。然后?gcc 来编译这个文Ӟ它会(x)传递一些特D的选项。首先,要(使用 <code style="font-size: small !important; ">-Wl</code>选项Q通知链接器生成一个映像文ӞqӞ使用 <code style="font-size: small !important; ">-g</code> 选项Q通知~译器生成调试符受最l生成可执行文g <em>test</em>。得到新的可执行应用E序之后Q?zhn)可以?nbsp;<code style="font-size: small !important; ">grep</code> 工具在映像文件中查找 <code style="font-size: small !important; ">main</code> 来寻扑֮的地址了。用这个地址?Addr2line 工具Q就可以判断出函数名Q?code style="font-size: small !important; ">main</code>Q、源文gQ?home/mtj/test/test.cQ以?qing)它在源文g中的行号Q?Q?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">在调?Addr2line 工具Ӟ要?nbsp;<code style="font-size: small !important; ">-e</code> 选项来指定可执行映像?nbsp;<code style="font-size: small !important; ">test</code>。通过使用 <code style="font-size: small !important; ">-f</code> 选项Q可以告诉工兯出函数名?/p><br /><a name="N10152"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">清单 4. addr2line 的一个交互式例子</strong></a><br /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-style: solid; border-color: #cccccc; padding: 2px 2px 5px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; "> $ cat >> test.c #include <stdio.h> int main() { printf("Hello World\n"); return 0; } <ctld-d> $ <strong>gcc -Wl,-Map=test.map -g -o test test.c</strong> $ grep main test.map 0x08048258 __libc_start_main@@GLIBC_2.0 0x08048258 main $ <strong>addr2line 0x08048258 -e test -f</strong> main /home/mtj/test/test.c:4 $ </pre></td></tr></tbody></table><br /><div ibm-alt-header="" dw-container-sidebar"="" style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 10px; width: 320px; float: right; "><h2>Addr2line 和调试器</h2><div style="background-image: url(http://1.www.s81c.com/i/v16/t/container-gradient.gif); border-bottom-color: #cccccc; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #cccccc; border-left-style: solid; border-left-width: 1px; border-right-color: #cccccc; border-right-style: solid; border-right-width: 1px; font-size: 0.76em; font-family: arial, sans-serif; padding: 5px; background-position: 0px 100%; background-repeat: repeat no-repeat; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">Addr2line 工具提供了基本的W号调试信息Q不q?GNU Debugger QGDBQ用的是其他一些内部方法?/p></div></div><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); height: 1px; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 21px; "><a style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页?/a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N1016B"><span style="font-size: 1.5em; font-weight: bold; ">_函数跟踪数据</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">现在(zhn)有了一个可以搜集函数函数地址的追t数据的Ҏ(gu)Q还可以使用 Addr2line 工具地址转换为函数名。然而,从应用程序中产生大量的跟t数据之后,如何对这些数据进行精Q从而其更有意义呢Q这是使用一些定制的中间代码在开源工具之间徏立联pȝ地方。本文提供了q个工具QPvtraceQ的带有注释的完整代码,包括如何~译和用该工具的一些说明。(有关的更多信息,请参?nbsp;<a style="color: #4c6e94; ">下蝲</a> 一节。)</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">回想一下图 1 中的内容Q在执行讄了检函数的应用E序Ӟ?x)创Z个名?nbsp;<em>trace.txt</em> 的文本文件。这个h们可以读取的文g中包含了一pd地址信息 —— 每行一个地址Q每行都有一个前~字符。如果前~?nbsp;<em>E</em>Q那么这个地址是一个函数的入口地址Q也是_(d)(zhn)正在调用这个函敎ͼ。如果前~是一?nbsp;<em>X</em> 字符Q那么这个地址是一个出口地址Q也是_(d)(zhn)正在从q个函数中退出)?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">因此Q如果在跟踪文g中有一个入口地址QAQ紧跟着另外一个入口地址QBQ,那么(zhn)就可以推断?A 调用?B。如果一个入口地址QAQ后面跟着一个出口地址QAQ,那么p明这个函敎ͼAQ被调用后就直接q回了。当涉及(qing)大量的调用链Ӟ很隑ֈ析究竟是谁调用了谁,因此Q一U简单的解决Ҏ(gu)是维护一个整个地址的堆栈。每ơ在跟踪文g中碰C个入口地址Ӟ将其压入堆栈。栈的地址׃表最后一ơ被调用的函敎ͼ也就是当前的zd函数Q。如果后面紧接着是另外一个入口地址Q这说明堆栈中的地址调用了这个刚从跟t文件处d的地址。在到退出函数时Q当前的zd函数׃(x)q回Qƈ释放栈顶元素。这?x)将上下文返到回前一个函敎ͼ由此Q就可以产生正确的调用链q程?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">?2 介绍了这个概念,以及(qing)_数据的方法。在分析跟踪文g中的调用链时Q会(x)构徏一个连通矩阵,用来表示哪个函数调用了其他哪些函数。这个矩늚行表C用函数的地址Q列表示被调用的地址。对于每个调用对来说Q行与列的交叉点不断q行累加Q调用次敎ͼ。当处理完整个跟t文件时Q其l果是该应用E序的整个调用历史的一个非常简单的表示Q其中包含了调用的次数?/p><br /><a name="N1018D"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">?2. 对跟t数据进行处理和_Qƈ生成矩阵格式</strong></a><br /><img alt="_q程" height="493" src="http://www.ibm.com/developerworks/cn/linux/l-graphvis/figure2.gif" width="295" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " /> <br /><div ibm-alt-header="" dw-container-sidebar"="" style="margin-top: 0px; margin-right: 0px; margin-bottom: 1.2em; margin-left: 10px; width: 320px; float: right; "><h2>~译q安装工?/h2><div style="background-image: url(http://1.www.s81c.com/i/v16/t/container-gradient.gif); border-bottom-color: #cccccc; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #cccccc; border-left-style: solid; border-left-width: 1px; border-right-color: #cccccc; border-right-style: solid; border-right-width: 1px; font-size: 0.76em; font-family: arial, sans-serif; padding: 5px; background-position: 0px 100%; background-repeat: repeat no-repeat; "><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">在下载ƈ解压 Pvtrace 工具之后Q只需在子目录中输?nbsp;<code style="font-size: small !important; ">make</code> 命o(h)Q就可以~译 Pvtrace 工具了。也可以使用下面的代码将q个工具安装?/usr/local/bin 目录中:(x)</p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">$ unzip pvtrace.zip -d pvtrace</p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">$ cd pvtrace</p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">$ make</p><p style="font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; ">$ make install</p></div></div><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">现在我们已经构徏了简化的函数q通性矩阵,接下来应该构建图形的表示了。让我们深入研究 GraphvizQ了便理解如何从q通矩는成一个调用图?/p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); height: 1px; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 21px; "><a style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页?/a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N101BB"><span style="font-size: 1.5em; font-weight: bold; ">使用 Graphviz</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Graphviz ?Graph Visualization 是由 AT&T 开发的一个开源的囑Ş可视化工兗它提供了多U画图能力,但是我们重点x的是它?Dot 语言直连囄能力。在本文中,我们简单介l如何?Dot 来创Z个图形,q展C如何将分析数据转换?Graphviz 可以使用的规范。(请参?nbsp;<a style="color: #4c6e94; ">参考资?/a> 一节,以获得有关下载这个开源Y件的信息。)</p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N101C9"><span style="font-size: 1.2em; font-weight: bold; ">Dot 使用的图形规?/span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">使用 Dot 语言Q?zhn)可以指定三种对象Q图、节点和辏Vؓ(f)了让(zhn)理解这些对象的含义Q我们将构徏一个例子来展示q些元素的用法?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">清单 5 l出了一个简单的定向图(directed graphQ,其中包含 3 个节炏V第一行声明这个图?nbsp;<em>G</em>Qƈ且声明了该图的类型(digraphQ。接下来的三行代码用于创囄节点Q这些节点分别名?nbsp;<em>node1</em>?em>node2</em> ?nbsp;<em>node3</em>。节Ҏ(gu)在它们的名字出现在图规范中时创徏的。边是在在两个节点用边操作Q?code style="font-size: small !important; ">-></code>Q连接在一h创徏的,如第 6 行到W?8 行所C。我q对边用了一个可选的属?nbsp;<code style="font-size: small !important; ">label</code>Q用它来表示边在图中的名U。最后,在第 9 行完成对该图规范的定义?/p><br /><a name="N101ED"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">清单 5. 使用 Dot W号表示的示例图Qtest.dotQ?/strong></a><br /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-style: solid; border-color: #cccccc; padding: 2px 2px 5px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; "> 1: digraph G { 2: node1; 3: node2; 4: node3; 5: 6: node1 -> node2 [label="edge_1_2"]; 7: node1 -> node3 [label="edge_1_3"]; 8: node2 -> node3 [label="edge_2_3"]; 9: } </pre></td></tr></tbody></table><br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">要将q个 .dot 文g转换成一个图形映像,则需要?Dot 工具Q这个工h?Graphviz 包中提供的。清?6 介绍了这U{换?/p><br /><a name="N101FB"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">清单 6. 使用 Dot 来创?JPG 映像</strong></a><br /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-style: solid; border-color: #cccccc; padding: 2px 2px 5px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; "> $ dot -Tjpg test.dot -o test.jpg $ </pre></td></tr></tbody></table><br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">在这D代码中Q我告诉 Dot 使用 test.dot 囑Ş规范Qƈ生成一?JPG 囑փQ将其保存在文g test.jpg 中。所生成的图像如?3 所C。在此处Q我使用?JPG 格式Q但?Dot 工具也可以支持其他格式,其中包括 GIF、PNG ?postscript?/p><br /><a name="N10207"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">?3. Dot 创徏的示例图</strong></a><br /><img alt="Dot 创徏的示例图" height="248" src="http://www.ibm.com/developerworks/cn/linux/l-graphvis/figure3.gif" width="207" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " /> <br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">Dot 语言q可以支持其他一些选项Q包括外形、颜色和很多属性。但是就我们惌实现的功能而言Q这个选项p够了?/p><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); height: 1px; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 21px; "><a style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页?/a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N10219"><span style="font-size: 1.5em; font-weight: bold; ">l合</span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">现在我们已经看到了整个过E的各个阶段了,下面可以采用一个例子来展示如何这些阶D合q在一起了。现在,(zhn)应该已l展开q安装了 Pvtrace 工具Q然后还需要将 instrument.c 文g复制到工作源代码目录中?/p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">在这个例子中Q我使用了一个源文g <em>test.c</em> q行(g)。清?7 l出了整个过E。在W?3 行中Q我使用(g)源Qinstrument.cQ来构徏Q编译ƈq接Q应用程序。然后在W?4 行执?code style="font-size: small !important; ">test</code>Q再使用 <code style="font-size: small !important; ">ls</code> 命o(h)验证已经生成?trace.txt 文g。在W?8 行,我调用了 Pvtrace 工具Qƈ提供q个映像文g作ؓ(f)它惟一的参数。映像名是必需的,q样 Addr2lineQ在 Pvtrace 中调用)可以访问这个映像中的调试信息。在W?9 行中Q我又执行了一?nbsp;<code style="font-size: small !important; ">ls</code> 命o(h)Q以保 Pvtrace 生成?graph.dot 文g。最后,在第 12 行,使用 Dot 这个图形规范{换成一?JPG 囑Ş映像?/p><br /><a name="N10239"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">清单 7. 创徏调用跟踪囄整个q程</strong></a><br /><table width="100%" cellpadding="0" cellspacing="0" border="0" style="font-size: 0.8em; "><tbody><tr><td style="font-family: arial, nsimsun, sans-serif; background-color: #f7f7f7 !important; border-style: solid; border-color: #cccccc; padding: 2px 2px 5px; "><pre style="width: 694px; margin-top: 0px; margin-bottom: 0px; font-family: 'Andale Mono', 'Lucida Console', Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; "> 1: $ ls 2: instrument.c test.c 3: $ <strong>$ gcc -g -finstrument-functions test.c instrument.c -o test</strong> 4: $ ./test 5: $ ls 6: instrument.c test.c 7: test trace.txt 8: $ <strong>pvtrace test</strong> 9: $ ls 10: graph.dot test trace.txt 11: instrument.c test.c 12: $ <strong>dot -Tjpg graph.dot -o graph.jpg</strong> 13: $ ls 14: graph.dot instrument.c test.c 15: graph.jpg test trace.txt 16: $ </pre></td></tr></tbody></table><br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">q个q程的示例输出如?4 所C。这个示例图是从使用 Q 学习(fn)的一个简单增强式学习(fn)应用E序中得到的?/p><br /><a name="N1024E"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">?4. CZ应用E序的跟t结?/strong></a><br /><img alt="CZ应用E序的跟t结? height="356" src="http://www.ibm.com/developerworks/cn/linux/l-graphvis/figure4.gif" width="479" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " /> <br /><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">(zhn)也可以使用q种Ҏ(gu)Ҏ(gu)大的应用E序q行分析。我要展C的最后一个例子是 Gzip 工具。我单地?instrument.c 加入 Gzip ?Makefile 中,作ؓ(f)其依赖的一个源文gQ然后编?GzipQƈ使用它生成一个跟t文件。这个图形太大了Q不太容易进行更详细的分析,但是下图表示?Gzip 对一个小文gq行压羃时的处理q程?/p><br /><a name="N10262"><strong style="font-size: 0.76em; padding: 0.3em 5px 0.7em; font-family: arial, sans-serif; ">?5. Gzip 跟踪l果</strong></a><br /><img alt="Gzip 跟踪l果" height="281" src="http://www.ibm.com/developerworks/cn/linux/l-graphvis/figure5.jpg" width="580" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; " /> <br /><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); height: 1px; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 21px; "><a style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页?/a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><a name="N10272"><span style="font-size: 1.5em; font-weight: bold; ">l束?/span></a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; ">使用开源Y件和量的中间代码,只需要花很少的时间就可以开发出非常有用的项目。通过使用对应用程序进行分析的几个 GNU ~译器扩展,可以使用 Addr2line 工具q行地址转换Qƈ?Graphviz 应用E序q行囑Ş可视化,然后(zhn)就可以得到一个程序,该程序可以对应用E序q行分析Qƈ展示一个说明调用链的定向图。通过囑Ş来查看一个应用程序的调用铑֯于理解应用程序的内部行ؓ(f)来说非常重要。在正确了解调用铑֏(qing)其各自的频率之后Q这些知识可能对调试和优化应用程序非常有用?/p><br /><div style="clear: both; background-image: url(http://1.www.s81c.com/i/solid.gif); height: 1px; background-repeat: repeat no-repeat; "></div><p ibm-back-to-top"="" style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; font-size: 0.76em; clear: both; text-align: right; height: 21px; "><a style="color: #4c6e94; display: inline; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 18px; text-decoration: none; background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; font-weight: bold; background-position: 0px -1px; background-repeat: no-repeat no-repeat; ">回页?/a></p><p style="font-family: arial, nsimsun, sans-serif; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0.3em; padding-right: 5px; padding-bottom: 0.7em; padding-left: 5px; font-size: 0.76em; "><span style="font-size: 1.5em; font-weight: bold; ">下蝲</span></p><table width="100%" cellspacing="0" cellpadding="0" border="0" style="font-size: 0.8em; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-top-width: 0px; width: 709px; "><tbody><tr><th scope="col" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; border-top-width: 1px; padding-top: 8px; padding-right: 5px; padding-bottom: 8px; padding-left: 5px; vertical-align: top; background-image: url(http://1.www.s81c.com/i/v16/t/text-tabs-bg.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f7f8fc; text-align: left; background-position: initial initial; background-repeat: repeat no-repeat; ">描述</th><th scope="col" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; border-top-width: 1px; padding-top: 8px; padding-right: 5px; padding-bottom: 8px; padding-left: 5px; vertical-align: top; background-image: url(http://1.www.s81c.com/i/v16/t/text-tabs-bg.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f7f8fc; text-align: left; background-position: initial initial; background-repeat: repeat no-repeat; ">名字</th><th scope="col" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; border-top-width: 1px; padding-top: 8px; padding-right: 5px; padding-bottom: 8px; padding-left: 5px; vertical-align: top; background-image: url(http://1.www.s81c.com/i/v16/t/text-tabs-bg.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f7f8fc; text-align: left; background-position: initial initial; background-repeat: repeat no-repeat; ">大小</th><th scope="col" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; border-top-width: 1px; padding-top: 8px; padding-right: 5px; padding-bottom: 8px; padding-left: 5px; vertical-align: top; background-image: url(http://1.www.s81c.com/i/v16/t/text-tabs-bg.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #f7f8fc; text-align: left; background-position: initial initial; background-repeat: repeat no-repeat; ">下蝲Ҏ(gu)</th></tr><tr><td scope="row" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; padding: 8px 5px; vertical-align: top; ">Instrumentation source and Pvtrace source</td><td nowrap="nowrap" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; padding: 8px 5px; vertical-align: top; ">pvtrace.zip</td><td nowrap="nowrap" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; padding: 8px 5px; vertical-align: top; ">4 KB</td><td nowrap="nowrap" style="font-family: arial, nsimsun, sans-serif; border-top-color: #cccccc; border-top-style: solid; padding: 8px 5px; vertical-align: top; "><a style="color: #4c6e94; ">HTTP</a></td></tr></tbody></table></div></div></div></span><img src ="http://www.shnenglu.com/tqsheng/aggbug/183549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/tqsheng/" target="_blank">tqsheng</a> 2012-07-15 14:58 <a href="http://www.shnenglu.com/tqsheng/archive/2012/07/15/183549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.lzjrdfl.cn" target="_blank">þ߿ۿƷ㽶</a>| <a href="http://www.kanglue.cn" target="_blank">ŷ˼Ծþ</a>| <a href="http://www.kqb8.cn" target="_blank">žžƷþþþþ</a>| <a href="http://www.scjyzj.cn" target="_blank">ƷŮþþ</a>| <a href="http://www.hoqw.cn" target="_blank">һֻƴƬ99þ</a>| <a href="http://www.sic-mosi2.cn" target="_blank">þۺϹapp</a>| <a href="http://www.02324.cn" target="_blank">˳wwwþþ</a>| <a href="http://www.threecar.com.cn" target="_blank">þ뾫Ʒһ</a>| <a href="http://www.xorfbrt.cn" target="_blank">þ</a>| <a href="http://www.ptrjmfv.cn" target="_blank">þþþޱٸ</a>| <a href="http://www.bash001.cn" target="_blank">ձձȾþþƷ</a>| <a href="http://www.ubzr.cn" target="_blank">þþ</a>| <a href="http://www.wordboy.cn" target="_blank">þþþ޾Ʒվ</a>| <a href="http://www.sem588.cn" target="_blank">ŷ˾þô߽ۺ</a>| <a href="http://www.aktg.com.cn" target="_blank">޹ŮƷþþþá</a>| <a href="http://www.liaoningluntan.cn" target="_blank">þ޾ƷVA</a>| <a href="http://www.baicar.cn" target="_blank">Ʒ׾þAAAƬ69</a>| <a href="http://www.qdtiandiyuan.cn" target="_blank">þþþƷ </a>| <a href="http://www.jojo-m.cn" target="_blank">þӰӹ</a>| <a href="http://www.ijlm.cn" target="_blank">þĻƷһ</a>| <a href="http://www.tobeok.cn" target="_blank">þ޾ƷVA</a>| <a href="http://www.zhhhtch.cn" target="_blank">޾ƷƷþ99һ</a>| <a href="http://www.ruannews.com.cn" target="_blank">þ޾ƷĻ</a>| <a href="http://www.shaoxingncp.cn" target="_blank">þ777߿ۿƷ</a>| <a href="http://www.xibu520.cn" target="_blank">Ʒݾþþþø</a>| <a href="http://www.fimtb.cn" target="_blank">ƬҹƬþ </a>| <a href="http://www.terris.cn" target="_blank">2021ƷþþƷ</a>| <a href="http://www.61fushi.cn" target="_blank">޾ƷþþþþðĦ</a>| <a href="http://www.chefax.cn" target="_blank">˾þþùۿëƬ</a>| <a href="http://www.010tk.cn" target="_blank">þùҹaӰԺ </a>| <a href="http://www.zhengulao.cn" target="_blank">þþƷ99þ㽶</a>| <a href="http://www.tianit.cn" target="_blank">þ99Ʒ鶹լլ</a>| <a href="http://www.56dn.cn" target="_blank">þþƷƵ</a>| <a href="http://www.caster.org.cn" target="_blank">Ʒþþþþ벻</a>| <a href="http://www.dztsc.cn" target="_blank">վþþ</a>| <a href="http://www.114best.com.cn" target="_blank">޵һAVվþþƷ˵AV </a>| <a href="http://www.zhoupeng520.cn" target="_blank">þ91Ʒ91</a>| <a href="http://www.xn88.cn" target="_blank">պŷþþwwwۺ</a>| <a href="http://www.anacli.cn" target="_blank">ŷ˾þۺ</a>| <a href="http://www.depsys.cn" target="_blank">Ʒþþþþ</a>| <a href="http://www.e-meng.com.cn" target="_blank">޹Ʒ˾þ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>