zoukankan      html  css  js  c++  java
  • 关于C++ Builder Codegurad 问题的排查。

       关于C++ BUILDER6 我目前不知道有什么特别好的内存排查工具。尤其为了对付memory leak, (Eurekalog 这个工具内存泄漏主要针对delphi,BCB配置比较繁琐)。 除了BCB6 自带的Codeguard。codeguard 在90%的情况还是很给力的。

         但是实际项目中codegurad却会因为各种各样的原因罢工。下面是记录codeguard 被修复的2个案例

    • 加载CG后,程序运行起来后报内存错误。

              这个问题困扰了我很久,最后不得不关闭codeguard ,直到有一天,我下定决定把这个问题解决。我认为这不是BCB的问题,为什么呢,因为新建的任何工程CG工作都很正常。我当时的排查方式是这样的。用tdump 查看了exe 引用的库 (直觉告诉我的),结果发现了工程中引用了VCL50.bpl. 而我的工程是bcb6 构建的。

             于是我找到了使用VCL50.BPL 的这个模块,是一个Lib ,引用的第三方的一个库。我砍掉了这个库。运行CG。REBUILD, 修复了。程序可以正常运行。而且能识别到内存泄漏。

    • CG加载成功,但是CG不能识别到内存泄漏。

             这个问题比较怪异。程序能够正常的运行,也能够加载CG。但是,你在程序中故意引发一个内存泄漏,CG居然没有任何反应。我坚持认为不是BCB 的问题。理由还是,新建工程能正常的识别内存泄漏问题。我是这么排查的。

            在winmain 函数入口处,引发内存泄漏,然后 直接return 0

    1 int WINAPI WinMain(....)
    2 {
    3 char* ch = new char[10];
    4 return 0;
    5 }

    CG 识别出了内存泄漏。于是我判断,是执行了某一段代码之后,引发了CG 不能够正常工作。

    于是,我不停的挪动 return 0 的位置。 直到找到CG不报内存泄漏的那个段代码。

    int WINAPI winMain(.....)
    {
    char* ch = new char[10];
    
    代码1
    
    代码2
    
    代码3  //<- 执行了代码3之后,CG就不报内存错误了。
    
    return 0
    
    }

    继续排查代码3中内部的问题。

    最后定位到在代码中有一段非常退出进程的代码。导致了CG无法识别。用过一个简单的例子来模拟就是这样的。

    新建一个工程,然后开启CG,拖一个按钮Button1,代码如下。

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    #include "tlhelp32.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
        char* ch = new char[100];
    }
    //---------------------------------------------------------------------------
    
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        
        HANDLE hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,GetCurrentProcessId());
        TerminateProcess(hProcess,0);
     
    }

    你会发现,点了Button1 ,CG不会报任何内存泄漏。很好理解,这个动作相当于在进程管理器中杀进程了。CG自然不会报任何错误。

    也就是说,如果你的CG 能正常编译,但不报错。那么检查一下,你的程序结束的时候,是从WinMain 正常return 的吗。

  • 相关阅读:
    诺基亚为 Qt 增添 LGPL 授权选择
    Web Beans (JSR299): Q&amp;A with Specification Lead Gavin King
    Web Beans (JSR299): Q&amp;A with Specification Lead Gavin King
    诺基亚为 Qt 增添 LGPL 授权选择
    使用 Hibernate 进行大数据量的性能测试
    略谈如何在对话框创建视图类画图
    JBoss Seam 框架下的单元测试
    领域模型设计讨论与研究
    JBoss Seam 框架下的单元测试
    The use of FS/GS registers
  • 原文地址:https://www.cnblogs.com/songr/p/4759295.html
Copyright © 2011-2022 走看看