﻿<?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>C++博客-曲径通幽-随笔分类-Debug \ Reverse Engineering</title><link>http://www.cppblog.com/chinloon/category/14090.html</link><description>Happy Programming &amp; Designing</description><language>zh-cn</language><lastBuildDate>Wed, 28 Mar 2012 01:10:41 GMT</lastBuildDate><pubDate>Wed, 28 Mar 2012 01:10:41 GMT</pubDate><ttl>60</ttl><item><title>Linux下调试死循环</title><link>http://www.cppblog.com/chinloon/archive/2011/06/13/148580.html</link><dc:creator>chinloon</dc:creator><author>chinloon</author><pubDate>Mon, 13 Jun 2011 05:49:00 GMT</pubDate><guid>http://www.cppblog.com/chinloon/archive/2011/06/13/148580.html</guid><wfw:comment>http://www.cppblog.com/chinloon/comments/148580.html</wfw:comment><comments>http://www.cppblog.com/chinloon/archive/2011/06/13/148580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chinloon/comments/commentRss/148580.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chinloon/services/trackbacks/148580.html</trackback:ping><description><![CDATA[&nbsp; 最近在工作中发现网络通信收发文件部分，发送一次文件后，就再也不能发第二次了。本以为是协议的问题，后来用TOP发现CPU过高，才通过GDB看到了是一个清空Buffer类的代码有BUG，计算无符号整形的操作溢出了。<br />&nbsp; 具体跟踪方法记录一下。首先正常启动程序，然后进行收发文件操作，触发死循环。而后通过 top -H 查看哪个线程(其实是PID，redhat的线程是fork进程实现的)占用CPU过高，而后gdb -p [pid] attach 之，最后bt 打印堆栈。<img src ="http://www.cppblog.com/chinloon/aggbug/148580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chinloon/" target="_blank">chinloon</a> 2011-06-13 13:49 <a href="http://www.cppblog.com/chinloon/archive/2011/06/13/148580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一段 汇编代码</title><link>http://www.cppblog.com/chinloon/archive/2011/01/06/138068.html</link><dc:creator>chinloon</dc:creator><author>chinloon</author><pubDate>Thu, 06 Jan 2011 04:48:00 GMT</pubDate><guid>http://www.cppblog.com/chinloon/archive/2011/01/06/138068.html</guid><wfw:comment>http://www.cppblog.com/chinloon/comments/138068.html</wfw:comment><comments>http://www.cppblog.com/chinloon/archive/2011/01/06/138068.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chinloon/comments/commentRss/138068.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chinloon/services/trackbacks/138068.html</trackback:ping><description><![CDATA[这是从别人博客上摘的一段C嵌汇编码 <br>(&nbsp;http://www.cppblog.com/kevinlynx/archive/2011/01/02/137886.html
)<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; width: 98%; font-size: 13px; color: #220000;"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">__declspec(naked)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top">void&nbsp;caller(void*&nbsp;pfn,&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">)&nbsp;<br><img id="Codehighlighter1_45_172_Open_Image" onclick="this.style.display='none'; codehighlighter1_45_172_open_text.style.display=" none="" ;="" codehighlighter1_45_172_closed_image.style.display="'inline';" codehighlighter1_45_172_closed_text.style.display="'inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img style="display: none;" id="Codehighlighter1_45_172_Closed_Image" onclick="this.style.display='none'; codehighlighter1_45_172_closed_text.style.display=" none="" ;="" codehighlighter1_45_172_open_image.style.display="'inline';" codehighlighter1_45_172_open_text.style.display="'inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"><img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;__asm&nbsp;<br><img id="Codehighlighter1_62_170_Open_Image" onclick="this.style.display='none'; codehighlighter1_62_170_open_text.style.display=" none="" ;="" codehighlighter1_62_170_closed_image.style.display="'inline';" codehighlighter1_62_170_closed_text.style.display="'inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img style="display: none;" id="Codehighlighter1_62_170_Closed_Image" onclick="this.style.display='none'; codehighlighter1_62_170_closed_text.style.display=" none="" ;="" codehighlighter1_62_170_open_image.style.display="'inline';" codehighlighter1_62_170_open_text.style.display="'inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pop&nbsp;eax;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add&nbsp;eax,&nbsp;3;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xchg&nbsp;dword&nbsp;ptr[esp],&nbsp;eax;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;eax;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</div>
下面是调用方法<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; width: 98%; font-size: 13px;"><img style="color: #220000;" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><span style="color: #220000;">void&nbsp;print_str(&nbsp;const&nbsp;char&nbsp;*s&nbsp;)</span><br style="color: #220000;"><img style="color: #220000;" id="Codehighlighter1_32_60_Open_Image" onclick="this.style.display='none'; codehighlighter1_32_60_open_text.style.display=" none="" ;="" codehighlighter1_32_60_closed_image.style.display="'inline';" codehighlighter1_32_60_closed_text.style.display="'inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img style="display: none;" id="Codehighlighter1_32_60_Closed_Image" onclick="this.style.display='none'; codehighlighter1_32_60_closed_text.style.display=" none="" ;="" codehighlighter1_32_60_open_image.style.display="'inline';" codehighlighter1_32_60_open_text.style.display="'inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align="top"><img style="color: #220000;" src="http://www.cppblog.com/Images/dot.gif"><span style="color: #220000;">{</span><br style="color: #220000;"><img style="color: #220000;" src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align="top"><span style="color: #220000;">&nbsp;&nbsp;&nbsp;&nbsp;printf(&nbsp;"%s\n",&nbsp;s&nbsp;);</span><br style="color: #220000;"><img style="color: #220000;" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"><span style="color: #220000;">}</span><br style="color: #220000;"><br style="color: #220000;"><span style="color: #220000;">{</span><br style="color: #220000;"><span style="color: #220000;">&nbsp;&nbsp; ...</span><br style="color: #220000;"><img style="color: #220000;" src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align="top"><span style="color: #220000;">caller(&nbsp;print_str,&nbsp;"a&nbsp;string"&nbsp;);</span><br style="color: #220000;"><span style="color: #220000;">&nbsp;&nbsp; __asm&nbsp; add&nbsp;esp,&nbsp;4</span><br style="color: #220000;"><span style="color: #220000;">&nbsp;&nbsp;
...</span><br style="color: #220000;"><span style="color: #220000;">}</span><br></div>
<br>&nbsp; 原作者讲了一些基础，这里就不提了<br>看了一遍，发现 "ADD EAX, 3" 的用法有点奇怪（我相信搞破解的人一定比较熟悉，但正常的程序不会这么写。）<br>初看 EAX 是地址，+3是很危险的，但仔细一看，发现代码是为了从最外层主调函数一路穿越"caller" 直达 print_str，这里牵涉到一个重要问题，就是在CALL指令时，会有将&#8220;CALL指令下一条地址压栈&#8221;的操作，那么代码思路很明了了，就是为了要造出 调用print_str时，ESP(+0) 指向 caller(..)调用的下一个地址。<br>&nbsp; 第一关已经顺利搞定，但又碰到个问题，由于 print_str 的入参是可变的，所以必须用 cdecl调用，那RET之后 如何平栈呢？ 如果直接跳到 caller下一条地址，就丧失了平栈的机会，最终会在某个主调函数上被微软的 stack cookie捕获抛个SEH。<br>&nbsp; 这里就用到文章开头提到的 ADD EAX, 3。<br>&nbsp; 必须要造一个环境，让 caller 调用完成后，给个机会清理现场。于是乎，caller之后就有了 ADD ESP, 4。其实这里的4是与print_str的入参数目相关的，每个参数要多加 4字节，如此一来，整个代码就理顺了。<br>&nbsp; 那为什么 是 ADD EAX, 3呢？ 应该是预估出一条ADD指令占用多少长度，和具体的环境有关。因为没看INTEL手册，这里只能认为ADD 寄存器+WORD的长度是3个字节。我用VC试验了一下，的确是如此，我也尝试了ADD 寄存器+DWORD，长度变为了5个字节。<br>   <img src ="http://www.cppblog.com/chinloon/aggbug/138068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chinloon/" target="_blank">chinloon</a> 2011-01-06 12:48 <a href="http://www.cppblog.com/chinloon/archive/2011/01/06/138068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用C++对象模型通过父类调用子类特有的虚函数</title><link>http://www.cppblog.com/chinloon/archive/2010/10/18/130301.html</link><dc:creator>chinloon</dc:creator><author>chinloon</author><pubDate>Mon, 18 Oct 2010 10:07:00 GMT</pubDate><guid>http://www.cppblog.com/chinloon/archive/2010/10/18/130301.html</guid><wfw:comment>http://www.cppblog.com/chinloon/comments/130301.html</wfw:comment><comments>http://www.cppblog.com/chinloon/archive/2010/10/18/130301.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/chinloon/comments/commentRss/130301.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chinloon/services/trackbacks/130301.html</trackback:ping><description><![CDATA[&nbsp; 最近QQ游戏开发群里有一位朋友出了一道题，&#8220;如何在基类中调用子类独有的函数，而不调用强制转换&#8221;。这道题我一时间没做出来，但是如果放宽限制，其实可以玩一个有趣的游戏。<br>&nbsp; 如果题目改为&#8220;如何在基类中调用子类独有的虚函数，而不调用Class类型强制转换&#8221;，那就可以利用C++对象模型中的虚表的直接访问来实现父类调用子类的特有虚函数。（注意，这里特有是指子类有而基类没有。）<br>&nbsp; 以下是我的解法，也在QQ群里发了，想不到引起群成员小小的轰动，看来游戏开发还是有很多同学对底层不感兴趣啊。<br><br>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<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: #000000;">#include&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">stdio.h</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><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;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CFather{<br></span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:<br></span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">CFather(){}<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;"><br></span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CSon&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;CFather{<br></span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">CSon(){}<br></span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;DoSomething(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">){&nbsp;printf(</span><span style="color: #000000;">"</span><span style="color: #000000;">son&nbsp;is&nbsp;crying\n</span><span style="color: #000000;">"</span><span style="color: #000000;">);&nbsp;}<br></span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">};<br></span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;"></span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;_tmain(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;argv[])<br></span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">{<br></span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CFather</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;fa&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;CSon();<br></span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;DWORD&nbsp;dwDoSomething&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD</span><span style="color: #000000;">*</span><span style="color: #000000;">)(</span><span style="color: #000000;">*</span><span style="color: #000000;">(DWORD</span><span style="color: #000000;">*</span><span style="color: #000000;">)fa</span><span style="color: #000000;">+</span><span style="color: #000000;">4</span><span style="color: #000000;">));<br></span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;MOV&nbsp;ecx,&nbsp;fa<br></span><span style="color: #008080;">19</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;_asm&nbsp;CALL&nbsp;dwDoSomething<br></span><span style="color: #008080;">20</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">21</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;system(</span><span style="color: #000000;">"</span><span style="color: #000000;">pause</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br></span><span style="color: #008080;">22</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;<br></span><span style="color: #008080;">23</span>&nbsp;<span style="color: #000000;">}<br></span><span style="color: #008080;">24</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">25</span>&nbsp;<span style="color: #000000;"></span></div>
<br><br> <img src ="http://www.cppblog.com/chinloon/aggbug/130301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chinloon/" target="_blank">chinloon</a> 2010-10-18 18:07 <a href="http://www.cppblog.com/chinloon/archive/2010/10/18/130301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>伟大的pdb</title><link>http://www.cppblog.com/chinloon/archive/2010/07/22/121008.html</link><dc:creator>chinloon</dc:creator><author>chinloon</author><pubDate>Thu, 22 Jul 2010 00:26:00 GMT</pubDate><guid>http://www.cppblog.com/chinloon/archive/2010/07/22/121008.html</guid><wfw:comment>http://www.cppblog.com/chinloon/comments/121008.html</wfw:comment><comments>http://www.cppblog.com/chinloon/archive/2010/07/22/121008.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chinloon/comments/commentRss/121008.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chinloon/services/trackbacks/121008.html</trackback:ping><description><![CDATA[&nbsp; 昨晚有客户反应，产品中的某个进程启动后1分钟内会消失，看了log未发现异常。<br>&nbsp; 于是远程过去，想看本溃报告，很遗憾的是，没有生成任何本溃报告（我们用的是Debug系列的api写的Crash Reporter）。情急之下，唯有求助伟大的Windbg了。<br>&nbsp; attach，g，过一会儿，果然发现是有一处seh。但随即发现缺symbols，于是马上去发布服务器上找相应的pdb文件，放到远程上去，.reload，果然，未知地址被准确地翻译成代码中的标识符。<br>&nbsp; 原来，崩溃的地方是动态加载的一个dll中的一个回调函数，怪不得没捕获到Crash Report。<br>&nbsp; 总结下来，Release版本的PDB生成是个关键，单有Windbg仍旧是巧妇难为无米之炊啊。<br><br> <img src ="http://www.cppblog.com/chinloon/aggbug/121008.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chinloon/" target="_blank">chinloon</a> 2010-07-22 08:26 <a href="http://www.cppblog.com/chinloon/archive/2010/07/22/121008.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Windbg调试高CPU占用率的进程</title><link>http://www.cppblog.com/chinloon/archive/2010/07/12/120142.html</link><dc:creator>chinloon</dc:creator><author>chinloon</author><pubDate>Mon, 12 Jul 2010 11:17:00 GMT</pubDate><guid>http://www.cppblog.com/chinloon/archive/2010/07/12/120142.html</guid><wfw:comment>http://www.cppblog.com/chinloon/comments/120142.html</wfw:comment><comments>http://www.cppblog.com/chinloon/archive/2010/07/12/120142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chinloon/comments/commentRss/120142.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chinloon/services/trackbacks/120142.html</trackback:ping><description><![CDATA[&nbsp; 最近用户发现某个进程CPU占用率过高，导致服务器假死。<br>&nbsp; 于是想用Windbg尝试调试一下。幸好我们的软件发布时都会保留一份PDB文件。因此Windbg能够准确地找到Symbol，即使是Release Version。 <br>&nbsp; 打开Windbg帮助文档，搜索"CPU"关键字，随即找到了&#8220;Tracking Down a Processor Hog&#8221;。按照上面的方法试了一下，果然可以准确地定位到某个死锁的线程。<br>&nbsp; 现在在工作中，利用Olldbg和Windbg的机会越来越多，在解决问题的过程中，也越发有成就感了。<br><br><img src ="http://www.cppblog.com/chinloon/aggbug/120142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chinloon/" target="_blank">chinloon</a> 2010-07-12 19:17 <a href="http://www.cppblog.com/chinloon/archive/2010/07/12/120142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC Release Debugging</title><link>http://www.cppblog.com/chinloon/archive/2010/07/01/119060.html</link><dc:creator>chinloon</dc:creator><author>chinloon</author><pubDate>Thu, 01 Jul 2010 06:43:00 GMT</pubDate><guid>http://www.cppblog.com/chinloon/archive/2010/07/01/119060.html</guid><wfw:comment>http://www.cppblog.com/chinloon/comments/119060.html</wfw:comment><comments>http://www.cppblog.com/chinloon/archive/2010/07/01/119060.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chinloon/comments/commentRss/119060.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chinloon/services/trackbacks/119060.html</trackback:ping><description><![CDATA[&nbsp; 今天在Code Project最新更新中看到"XCrashReport : Exception Handling and Crash Reporting"一文，泛读之后，又读了其中引用的几篇文章。觉得挺不错。主要讲了VC Relase版本如何定位问题，主要思路是打开Link选项"Generate debug info"、添加参数"/OPT:REF"和/ignore:4089 "，用作Release版本产生PDF，且优化的时候能使产生的目标文件更小。效果比较明显。<br>&nbsp; 随便写了一个会崩溃的工程，崩溃后记录其崩溃位置，然后随便打开一款调试器（OD，WinDBG，VC都可）运行debug，然后改EIP到出错的位置下断，GO！ <br>&nbsp; 其实，在运行出错的位置，然后改EIP的方法，以前在用OD时会使用到（类似F4或VC调试时的移动EIP），一直觉得ESP和Call Stack应该是分析Crash的重点，有时忽略了EIP的重要性。<br> <img src ="http://www.cppblog.com/chinloon/aggbug/119060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chinloon/" target="_blank">chinloon</a> 2010-07-01 14:43 <a href="http://www.cppblog.com/chinloon/archive/2010/07/01/119060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ 与 Delphi交互的一个问题</title><link>http://www.cppblog.com/chinloon/archive/2010/06/20/118328.html</link><dc:creator>chinloon</dc:creator><author>chinloon</author><pubDate>Sun, 20 Jun 2010 15:34:00 GMT</pubDate><guid>http://www.cppblog.com/chinloon/archive/2010/06/20/118328.html</guid><wfw:comment>http://www.cppblog.com/chinloon/comments/118328.html</wfw:comment><comments>http://www.cppblog.com/chinloon/archive/2010/06/20/118328.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/chinloon/comments/commentRss/118328.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/chinloon/services/trackbacks/118328.html</trackback:ping><description><![CDATA[&nbsp; 最近拿到一个第三方厂家的库，由于Delphi的同事看不懂c++的例子，所以让我用C++封装一个简单的Wrapper给其调用。<br>&nbsp; 后来发现一个问题，由于原始的函数声明中的参数使用字符数组 (char szData[MAX_PATH])&nbsp; 而不是用常用的指针(char *)，给Delphi同事调用后，发现函数调用完退栈时候程序本溃，原因是访问违例，非法地址访问0x72。<br>&nbsp; 这么一来感觉比较奇怪，0x72 这个地址显然是个垃圾地址，一般如果是空指针的话因该是 0x00，如果是野指针，一般也不至于会那么小，0x72与程序加载地址都相去甚远。<br>&nbsp;
在vc6（公司只准用vc6）里跟了一下反汇编，感觉信息缺少比较多，能看到的地方已经堆栈被破坏了。于是用了OD跟一下。发现Delphi调用我封装的
函数时，明明2个入参，却传入了3个。多传了个260。260对于vc程序员应该比较熟悉了，就是MAX_PATH的值。于是乎，告知了Delphi程序
员，方才得知，原来Delphi是可以在声明时指定数组长度的，也就是说，函数的入参，数组和指针是两种声明，如此一来，水落石出了。 <img src ="http://www.cppblog.com/chinloon/aggbug/118328.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/chinloon/" target="_blank">chinloon</a> 2010-06-20 23:34 <a href="http://www.cppblog.com/chinloon/archive/2010/06/20/118328.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>