Delphi 2009: Wie verhindere ich, Netzwerk-Anwendung von kritischen Abschnitt undicht?
-
26-09-2019 - |
Frage
Im Rahmen der Zertifizierung Vista, Microsoft will dafür sorgen, dass eine Anwendung beendet, ohne auf Halten zu einem Schloss (kritischer Abschnitt):
TEST CASE 31 Überprüfen Anwendung bricht nicht in einen Debugger mit den angegebenen AppVerifier Kontrollen (Anf: 3.2)
Wie sich herausstellt, Netzwerk-Anwendungen mit Delphi 2009 gebaut macht Pause in den Debugger, das zeigt nicht hilfreich Meldung wie folgt:
(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
Nach dem Drücken Go-Taste mehrmals, kommen Sie über den tatsächlichen Fehler:
=======================================
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.
=======================================
Da mein Code nicht undicht TCriticalSection
, wie verhindere ich, Delphi davon ab.
Lösung
Indy10 Lecks absichtlich kritische Abschnitte beim Austritt.
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}
- Kopieren dieser beiden Dateien aus
%delphi_home%\source\Indy\Indy10\System
und%delphi_home%\source\Indy\Indy10\Core
in Ihr Projekt oder sind sie in Suchpfad. - mit
IDFREEONFINAL
neu erstellen oder den IFDEF Richtlinien entfernen.
Andere Tipps
Wie wissen Sie, Ihr Code ist nichts undicht, wenn Sie mit ReportMemoryLeaksOnShutdown := True
oder FastMM4 in FullDebugMode
laufen haben alle memoryleaks (Code und Delphi-Bibliotheken) zu fangen?
Laufen Sie Ihre App in FullDebugMode würde Ihnen auch die Stacktrace der unfreed Speicherzuordnungen.
Sie werden wahrscheinlich feststellen, dass tatsächlich Sie die IdStack Critical Section sind undicht.
Sie können einen Blick auf diese Coderage 2 Sitzung geben möchten: Kampf Speicherverluste für Dummies . Es zeigt vor allem, wie FastMM verwenden, um Speicherlecks in Delphi zu verhindern / zu erkennen. War für D2007, aber immer noch relevant für D2009.