Delphi 2009: Как предотвратить утечку критически важной информации из сетевого приложения? - PullRequest
5 голосов
/ 12 мая 2010

В рамках сертификации 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.

Ответы [ 2 ]

13 голосов
/ 12 мая 2010

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.
0 голосов
/ 12 мая 2010

Откуда вы знаете, что ваш код ничего не пропускает, если вы не запустили ReportMemoryLeaksOnShutdown := True или FastMM4 в FullDebugMode, чтобы перехватить ВСЕ утечки памяти (ваш код и библиотеки Delphi)? Запуск вашего приложения в FullDebugMode также даст вам StackTrace несвободных выделений памяти.
Скорее всего, вы обнаружите, что действительно пропускаете критический раздел IdStack.

Возможно, вы захотите взглянуть на этот сеанс CodeRage 2: Борьба с утечками памяти для чайников . В основном показано, как использовать FastMM для предотвращения / обнаружения утечек памяти в Delphi. Был для D2007, но все еще актуален для D2009.

...