5

作为 Vista 认证的一部分,Microsoft 希望确保应用程序退出时不会保持锁定(关键部分):

测试用例 31. 使用指定的 AppVerifier 检查验证应用程序不会闯入调试器(要求:3.2)

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

(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,我该如何防止 Delphi 这样做。

4

2 回答 2

13

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 指令进行重建。
于 2010-05-12T12:51:14.473 回答
0

你怎么知道你的代码没有泄漏任何东西,除非你已经运行ReportMemoryLeaksOnShutdown := True或 FastMM4FullDebugMode来捕获所有内存泄漏(你的代码和 Delphi 库)?
在 FullDebugMode 下运行您的应用程序还会为您提供未释放内存分配的 StackTrace。
您可能会发现,确实,您正在泄漏 IdStack 关键部分。

您可能想看看这个 CodeRage 2 会议:为傻瓜而战的内存泄漏。它主要展示了如何使用 FastMM 来防止/检测 Delphi 中的内存泄漏。适用于 D2007,但仍适用于 D2009。

于 2010-05-12T17:09:41.627 回答