Как часть сертификации Vista, Microsoft хочет удостовериться, что приложение выходит без того, чтобы держаться за блокировку (критический раздел):
ТЕСТ 31. Проверьте, что приложение не врывается в отладчик с указанными проверками AppVerifier (Req: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 делал так.
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}
% delphi_home% \ source \ Indy \ Indy10 \ System
и % delphi_home% \ source \ Indy \ Indy10 \ Core
в ваш проект или включите их в путь поиска. IDFREEONFINAL
или удалите директивы IFDEF. Откуда вы знаете, что ваш код ничего не утекает, если вы не запустили с ReportMemoryLeaksOnShutdown: = True
или FastMM4 в FullDebugMode
, чтобы отловить ВСЕ утечки памяти (ваш код и библиотеки Delphi)?
Запуск вашего приложения в FullDebugMode также даст вам StackTrace неиспользованных выделений памяти.
Вы, вероятно, обнаружите, что действительно происходит утечка критического раздела IdStack.
Вы можете взглянуть на этот сеанс CodeRage 2: Борьба с утечками памяти для чайников . В основном это показывает, как использовать FastMM для предотвращения / обнаружения утечек памяти в Delphi. Был для D2007, но все еще актуален для D2009.