2010-05-12 11 views
5

Dans le cadre de la certification Vista, Microsoft veut vous assurer qu'une application se ferme sans se cramponner à une serrure (section critique):Delphi 2009: Comment empêcher une application réseau de fuir une section critique?

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

Comme il se trouve, les applications de réseau construit en utilisant Delphi 2009 ne se brise dans la débogueur, qui affiche un message inutile comme suit:

(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 

Après avoir frappé le bouton Go à plusieurs reprises, vous tombez sur l'erreur réelle:

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

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

Étant donné que mon code ne fuit pas TCriticalSection, comment puis-je empêcher Delphi de le faire.

Répondre

13

Indy10 fuit intentionnellement des sections critiques à la sortie.

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. Copiez ces deux fichiers de %delphi_home%\source\Indy\Indy10\System et %delphi_home%\source\Indy\Indy10\Core dans votre projet, ou les inclure dans le chemin de recherche. Recréez avec IDFREEONFINAL ou supprimez les directives IFDEF.
0

Comment savez-vous votre code ne fuit pas quoi que ce soit, sauf si vous avez exécuté avec ReportMemoryLeaksOnShutdown := True ou FastMM4 à FullDebugMode pour attraper TOUS memoryleaks (votre code et les bibliothèques Delphi)?
L'exécution de votre application dans FullDebugMode vous donnerait également le StackTrace des allocations de mémoire non gérées.
Vous trouverez probablement que, en effet, vous fuyez la section critique IdStack.

Vous pouvez jeter un oeil à cette session CodeRage 2: Fighting Memory Leaks for Dummies. Il montre principalement comment utiliser FastMM pour empêcher/détecter les fuites de mémoire dans Delphi. Était pour D2007 mais toujours pertinent pour D2009.