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

发布于 2024-09-01 10:34:57 字数 1291 浏览 7 评论 0原文

作为 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 这样做。

As part of Vista certification, Microsoft wants to make sure that an application exits without holding on to a lock (critical section):

TEST CASE 31. Verify application does not break into a debugger with the specified AppVerifier checks (Req:3.2)

As it turns out, network applications built using Delphi 2009 does break into the debugger, which displays unhelpful message as follows:

(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

After hitting Go button several times, you come across the actual error:

=======================================
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.

=======================================

Given that my code does not leak TCriticalSection, how do I prevent Delphi from doing so.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吃→可爱长大的 2024-09-08 10:34:57

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 指令。

Indy10 intentionally leaks critical sections upon exit.

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. Copy those two files from %delphi_home%\source\Indy\Indy10\System and %delphi_home%\source\Indy\Indy10\Core into your project, or include them in search path.
  2. Rebuild with IDFREEONFINAL or remove the IFDEF directives.
银河中√捞星星 2024-09-08 10:34:57

除非您在 FullDebugMode 中使用 ReportMemoryLeaksOnShutdown := True 或 FastMM4 运行来捕获所有内存泄漏(您的代码和 Delphi 库),否则您如何知道您的代码没有泄漏任何内容?< br>
在 FullDebugMode 下运行应用程序还会为您提供未释放内存分配的 StackTrace。
您可能会发现,确实,您正在泄漏 IdStack 关键部分。

您可能想看一下这个 CodeRage 2 会议:傻瓜式解决内存泄漏问题。主要展示了如何在Delphi中使用FastMM来预防/检测内存泄漏。适用于 D2007,但仍与 D2009 相关。

How do you know your code is not leaking anything unless you have run with ReportMemoryLeaksOnShutdown := True or FastMM4 in FullDebugMode to catch ALL memoryleaks (your code and Delphi libraries)?
Running your app in FullDebugMode would also give you the StackTrace of the unfreed memory allocations.
You will probably find that, indeed, you are leaking the IdStack Critical Section.

You may want to give a look at this CodeRage 2 session: Fighting Memory Leaks for Dummies. It mainly shows how to use FastMM to prevent/detect memory leaks in Delphi. Was for D2007 but still relevant for D2009.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文