代码之家  ›  专栏  ›  技术社区  ›  Eugene Yokota

Delphi2009:如何防止网络应用程序泄漏关键部分?

  •  5
  • Eugene Yokota  · 技术社区  · 14 年前

    作为Vista认证的一部分,Microsoft希望确保应用程序在不持有锁的情况下退出(关键部分):

    测试用例31。验证应用程序没有通过指定的AppVerifier检查进入调试器(req:3.2)

    事实证明,使用Delphi2009构建的网络应用程序确实闯入了调试器,它显示了以下无用消息:

    (1214.1f10): Break instruction exception - code 80000003 (first chance)
    eax=00000001 ebx=07b64ff8 ecx=a6450000 edx=0007e578 esi=0017f7e0 edi=80000003
    eip=77280004 esp=0017f780 ebp=0017f7ac iopl=0         nv up ei pl zr na pe nc
    cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
    *** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Windows\SysWOW64\ntdll.dll - 
    ntdll!DbgBreakPoint:
    77280004 cc              int     3
    

    点击Go按钮几次后,您会遇到实际错误:

    =======================================
    VERIFIER STOP 00000212: pid 0x18A4: Freeing virtual memory containing an active critical section. 
    
        076CC5DC : Critical section address.
        01D0191C : Critical section initialization stack trace.
        075D0000 : Memory block address.
        00140000 : Memory block size.
    
    
    =======================================
    This verifier stop is continuable.
    After debugging it use `go' to continue.
    
    =======================================
    

    因为我的代码不会泄露 TCriticalSection 我该如何阻止德尔福这样做呢?

    2 回复  |  直到 14 年前
        1
  •  13
  •   Eugene Yokota    14 年前

    INDY10出口时故意泄漏关键部位。

    IdStack.pas:

    finalization
      // Dont Free. If shutdown is from another Init section, it can cause GPF when stack
      // tries to access it. App will kill it off anyways, so just let it leak
      {$IFDEF IDFREEONFINAL}
      FreeAndNil(GStackCriticalSection);
      {$ENDIF}
    

    IdThread.pas:

    finalization
      // This call hangs if not all threads have been properly destroyed.
      // But without this, bad threads can often have worse results. Catch 22.
    //  TIdThread.WaitAllThreadsTerminated;
    
      {$IFDEF IDFREEONFINAL}
      //only enable this if you know your code exits thread-clean
      FreeAndNil(GThreadCount);
      {$ENDIF}
    
    1. 复制这两个文件 %delphi_home%\source\Indy\Indy10\System %delphi_home%\source\Indy\Indy10\Core 或者将它们包含在搜索路径中。
    2. 重建与 IDFREEONFINAL 或者删除ifdef指令。
        2
  •  0
  •   Francesca    14 年前

    你怎么知道你的代码没有泄漏任何东西,除非你用 ReportMemoryLeaksOnShutdown := True 或FASMM4 FullDebugMode 要捕获所有的内存条(您的代码和Delphi库)?
    在fulldebugmode中运行应用程序还将提供未释放内存分配的stacktrace。
    您可能会发现,实际上,您正在泄漏IDStack关键部分。

    您可能想看一下此coderage 2会话: Fighting Memory Leaks for Dummies . 主要介绍了如何在Delphi中使用fastmm来防止/检测内存泄漏。适用于D2007,但仍适用于D2009。