新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     >>计算机科学论坛<<     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → [转]DEBUG和RELEASE 版本差异及调试相关问题 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 5800 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: [转]DEBUG和RELEASE 版本差异及调试相关问题 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     longshentailang 帅哥哟,离线,有人找我吗?
      
      
      威望:1
      等级:计算机学士学位
      文章:325
      积分:2990
      门派:XML.ORG.CN
      注册:2006/6/20

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给longshentailang发送一个短消息 把longshentailang加入好友 查看longshentailang的个人资料 搜索longshentailang在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看longshentailang的博客楼主
    发贴心情 [转]DEBUG和RELEASE 版本差异及调试相关问题

    DEBUG和RELEASE 版本差异及调试相关问题


    I. 内存分配问题

    1. 变量未初始化。下面的程序在debug中运行的很好。

    thing * search(thing * something)
    BOOL found;
    for(int i = 0; i < whatever.GetSize(); i++)
    {
    if(whatever[i]->field == something->field)
    { /* found it */
    found = TRUE;
    break;
    } /* found it */
    }
    if(found)
    return whatever[i];
    else
    return NULL;
    而在release中却不行,因为debug中会自动给变量初始化found=FALSE,而在release版中则不会。所以尽可能的给变量、类或结构初始化。

    2. 数据溢出的问题

    如:char buffer[10];
    int counter;

    lstrcpy(buffer, "abcdefghik");

    在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没有。但是在release版中,counter可能被放在寄存器中,这样NULL就覆盖了buffer下面的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。

    3. DEBUG版和RELEASE版的内存分配方式是不同的 。如果你在DEBUG版中申请 ele 为 6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes为单位分配), 而在release版,分配给你的就是24bytes(release版以8bytes为单位),所以在debug版中如果你写ele[6],可能不会有什么问题,而在release版中,就有ACCESS VIOLATE。

    II. ASSERT和VERIFY

    1. ASSERT在Release版本中是不会被编译的。

    ASSERT宏是这样定义的

    #ifdef _DEBUG
    #define ASSERT(x) if( (x) == 0) report_assert_failure()
    #else
    #define ASSERT(x)
    #endif
    实际上复杂一些,但无关紧要。假如你在这些语句中加了程序中必须要有的代码
    比如

    ASSERT(pNewObj = new CMyClass);

    pNewObj->MyFunction();

    这种时候Release版本中的pNewObj不会分配到空间

    所以执行到下一个语句的时候程序会报该程序执行了非法操作的错误。这时可以用VERIFY :

    #ifdef _DEBUG
    #define VERIFY(x) if( (x) == 0) report_assert_failure()
    #else
    #define VERIFY(x) (x)
    #endif
    这样的话,代码在release版中就可以执行了。

    III. 参数问题:

    自定义消息的处理函数,必须定义如下:

    afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);

    返回值必须是HRESULT型,否则Debug会过,而Release出错

    IV. 内存分配

    保证数据创建和清除的统一性:如果一个DLL提供一个能够创建数据的函数,那么这个DLL同时应该提供一个函数销毁这些数据。数据的创建和清除应该在同一个层次上。

    V. DLL的灾难

    人们将不同版本DLL混合造成的不一致性形象的称为 “动态连接库的地狱“(DLL Hell) ,甚至微软自己也这么说http://msdn.microsoft.com/library/techart/dlldanger1.htm)。

    如果你的程序使用你自己的DLL时请注意:

    1. 不能将debug和release版的DLL混合在一起使用。debug都是debug版,release版都是release版。

    解决办法是将debug和release的程序分别放在主程序的debug和release目录下


    2. 千万不要以为静态连接库会解决问题,那只会使情况更糟糕。

    VI. RELEASE板中的调试 :

    1. 将ASSERT() 改为 VERIFY() 。找出定义在"#ifdef _DEBUG"中的代码,如果在RELEASE版本中需要这些代码请将他们移到定义外。查找TRACE(...)中代码,因为这些代码在RELEASE中也不被编译。 请认真检查那些在RELEASE中需要的代码是否并没有被便宜。

    2. 变量的初始化所带来的不同,在不同的系统,或是在DEBUG/RELEASE版本间都存在这样的差异,所以请对变量进行初始化。

    3. 是否在编译时已经有了警告?请将警告级别设置为3或4,然后保证在编译时没有警告出现.

    VII. 将Project Settings" 中 "C++/C " 项目下优化选项改为Disbale(Debug)。编译器的优化可能导致许多意想不到的错误,请参http://www.pgh.net/~newcomer/debug_release.htm

    1. 此外对RELEASE版本的软件也可以进行调试,请做如下改动:

    在"Project Settings" 中 "C++/C " 项目下设置 "category" 为 "General" 并且将"Debug Info"设置为 "Program Database"。

    在"Link"项目下选中"Generate Debug Info"检查框。

    "Rebuild All"

    如此做法会产生的一些限制:

    无法获得在MFC DLL中的变量的值。

    必须对该软件所使用的所有DLL工程都进行改动。

    另:

    MS BUG:MS的一份技术文档中表明,在VC5中对于DLL的"Maximize Speed"优化选项并未被完全支持,因此这将会引起内存错误并导致程序崩溃。

    2. www.sysinternals.com有一个程序DebugView,用来捕捉OutputDebugString的输出,运行起来后(估计是自设为system debugger)就可以观看所有程序的OutputDebugString的输出。此后,你可以脱离VC来运行你的程序并观看调试信息。

    3. 有一个叫Gimpel Lint的静态代码检查工具,据说比较好用http://www.gimpel.com 不过要化$的。

    参考文献:

    1) http://www.cygnus-software.com/papers/release_debugging.html

    2) http://www.pgh.net/~newcomer/debug_release.htm


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/10/14 22:12:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/12 7:42:02

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    46.875ms