2012-09-03 22 views
5

Ich verwende Windbg, um einen Deadlock zu analysieren, der in einem in Delphi geschriebenen Daten-Snap-Anwendungsserver auftritt."DebugInfo für CritSec verweist nicht auf den kritischen Abschnitt" beim Analysieren von Deadlock

Als ich

!analyze -hang -v 

laufe ich dieses

 
:000:x86> !analyze -hang -v 
******************************************************************************* 
*                    * 
*      Exception Analysis         * 
*                    * 
******************************************************************************* 

GetPageUrlData failed, server returned HTTP status 404 
URL requested: http://watson.microsoft.com/00000000.htm?Retriage=1 

FAULTING_IP: 
+6ced240 
00000000 ??    ??? 

EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff) 
ExceptionAddress: 0000000000000000 
    ExceptionCode: 80000003 (Break instruction exception) 
    ExceptionFlags: 00000000 
NumberParameters: 0 

FAULTING_THREAD: 0000000000000000 

BUGCHECK_STR: HANG 

DEFAULT_BUCKET_ID: APPLICATION_HANG 

PROCESS_NAME: ********.exe 

ERROR_CODE: (NTSTATUS) 0xcfffffff - 

EXCEPTION_CODE: (NTSTATUS) 0xcfffffff - 

MOD_LIST: 

NTGLOBALFLAG: 0 

APPLICATION_VERIFIER_FLAGS: 0 

DERIVED_WAIT_CHAIN: 

Dl Eid Cid  WaitType 
-- --- ------- -------------------------- 
    0 c7c.2634 Critical Section  

WAIT_CHAIN_COMMAND: ~0s;k;; 

BLOCKING_THREAD: 0000000000002634 

PRIMARY_PROBLEM_CLASS: APPLICATION_HANG 

LAST_CONTROL_TRANSFER: from 0000000077138df4 to 000000007711f8b1 

STACK_TEXT: 
0018fc50 77138df4 00000c6c 00000000 00000000 ntdll_77100000!NtWaitForSingleObject+0x15 
0018fcb4 77138cd8 00000000 00000000 03fe0940 ntdll_77100000!RtlpWaitOnCriticalSection+0x13e 
0018fcdc 7369324f 736a3134 00000000 03fe0940 ntdll_77100000!RtlEnterCriticalSection+0x150 
WARNING: Stack unwind information not available. Following frames may be wrong. 
0018fcec 7369af5f 00000388 00000000 003d1e00 mswsock!GetLspGuid+0x19af 
0018fd08 76366958 00000388 0018fd84 0018fd9c mswsock!GetLspGuid+0x96bf 
0018fd38 0018fd58 763668cd 00000388 0018fd84 ws2_32!WSAAccept+0x84 
00000000 00000000 00000000 00000000 00000000 0x18fd58 


FOLLOWUP_IP: 
mswsock!GetLspGuid+19af 
7369324f 33db   xor  ebx,ebx 

SYMBOL_STACK_INDEX: 3 

SYMBOL_NAME: mswsock!GetLspGuid+19af 

FOLLOWUP_NAME: MachineOwner 

MODULE_NAME: C:\Windows\System32\mswsock 

IMAGE_NAME: lld 

DEBUG_FLR_IMAGE_TIMESTAMP: 4ce7c83d 

STACK_COMMAND: ~0s ; kb 

FAILURE_BUCKET_ID: APPLICATION_HANG_cfffffff_lld!Unloaded 

BUCKET_ID: X64_HANG_mswsock!GetLspGuid+19af 

WATSON_STAGEONE_URL: http://watson.microsoft.com/00000000.htm?Retriage=1 

Followup: MachineOwner 
--------- 

Ich habe dann

!locks -V 

zu sehen, welche es Sperre wartet auf und zu meiner Überraschung es diese zurückkehrte,

 
0:000:x86> !locks -V 

CritSec ntdll!RtlCriticalSectionLock+0 at 0000000077057060 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec ntdll!LdrpLoaderLock+0 at 0000000077057490 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec ntdll!RtlpDynamicFunctionTableLock+0 at 0000000077057468 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec ntdll!FastPebLock+0 at 000000007705a900 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec ntdll!RtlpProcessHeapsListLock+0 at 000000007705a240 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec +270208 at 0000000000270208 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 1 

CritSec ntdll!EtwProvCritSect+0 at 000000007705a120 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec ntdll!EtwPrivSessionCritSect+0 at 000000007705a1e0 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec +10208 at 0000000000010208 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

CritSec +276f40 at 0000000000276f40 
LockCount   NOT LOCKED 
RecursionCount  0 
OwningThread  0 
EntryCount   0 
ContentionCount 0 

Scanned 10 critical sections 

Von

 
STACK_TEXT: 
0018fc50 77138df4 00000c6c 00000000 00000000 ntdll_77100000!NtWaitForSingleObject+0x15 
0018fcb4 77138cd8 00000000 00000000 03fe0940 ntdll_77100000!RtlpWaitOnCriticalSection+0x13e 
0018fcdc 7369324f 736a3134 00000000 03fe0940 ntdll_77100000!RtlEnterCriticalSection+0x150 
WARNING: Stack unwind information not available. Following frames may be wrong. 
0018fcec 7369af5f 00000388 00000000 003d1e00 mswsock!GetLspGuid+0x19af 
0018fd08 76366958 00000388 0018fd84 0018fd9c mswsock!GetLspGuid+0x96bf 
0018fd38 0018fd58 763668cd 00000388 0018fd84 ws2_32!WSAAccept+0x84 
00000000 00000000 00000000 00000000 00000000 0x18fd58 

ich bestimmt bei den Call-Stack sucht es 0x736a3134 (Erste Parameter RtlEnterCriticalSection bestanden), so lief ich diese

!critsec 736a3134 

auf einem kritischen Abschnitt an der Adresse wartete mir dies gab

Ausgang
 
0:000:x86> !critsec 736a3134 

DebugInfo for CritSec at 00000000736a3134 does not point back to the critical section 
NOT an initialized critical section. 

CritSec mswsock!WSPStartup+6f64 at 00000000736a3134 
WaiterWoken  Yes 
LockCount   -1 
RecursionCount  11028 
OwningThread  c6c 
EntryCount   1f49dad6 
ContentionCount 88000000 
*** Locked 

Jetzt fiel der Groschen, der Zeiger auf den kritischen Abschnitt geworden corru pted, möglicherweise wegen gleichzeitigem Thread-Zugriff und fehlender Synchronisation an anderer Stelle im Code

Meine Frage ist, wie finde ich heraus, wo das ist oder herausfinden, ob es ein anderes Problem ist?

PS: Dieser Fehler wird nur angezeigt, wenn die Anwendung mit vielleicht 700 Kunden verbunden

(es wird mit einem Thread pro Verbindung unter hohen Last ist und ich weiß, 32-Bit-Anwendungen werden auf dem Standard-Thread auf ca. 2000 Fäden begrenzt Stackgröße und das ist nicht der beste Ansatz)

PPS: Ich habe mehrere Crash-Dumps, wo die Anwendung hängt auf verschiedene kritische Abschnitte warten, in jedem Fall scheint der Zeiger für den kritischen Abschnitt nicht auf einen kritischen Abschnitt zu zeigen.

+0

Können Sie den Fehler reproduzieren, während Sie den Delphi-Debugger angeschlossen haben? Wenn ja, können Sie die Callstacks überprüfen und ich denke in späteren Delphi-Versionen sogar einige Deadlock-Informationen innerhalb der IDE. Eine andere Sache zu erwähnen ist, dass kritische Abschnitte sehr sinnvoll sind, wenn falsche Initialisierungen, z. ein Code snipplet wie: critSect.Leave; critSect.Enter; kann sehr schlechte Nebenwirkungen haben. Wenn nichts hilft, schlage ich vor, Sie versuchen, zwei Dinge: 1.) FastMM im vollen Debug-Modus (Heap Korruption) 2.) fahren Sie Ihre eigenen kritischen Abschnitt Klasse und zählen für alle eingeben und verlassen Anrufe (schließlich plus einen Anruf param). – mrabat

+0

Wir haben versucht, im Delphi-Debugger und nur Standalone zu reproduzieren, kann aber nicht, daher der Grund für die Verwendung von Windbg und Crash-Dumps. Wir vermuten, dass wir, um den Fehler zu bekommen, eine große Last auf dem Server erzeugen müssen und es auch zeitkritisch ist. Wir haben den gesamten Code überprüft und können einen Fehler mit der Sperrreihenfolge oder an einem anderen Ort, an dem wir eine Sperre oder Notwendigkeit für die Synchronisation verpasst haben, leicht erkennen, aber denken, dass wir etwas übersehen haben müssen. – MikeT

+1

Es ist unwahrscheinlich, dass der Zeiger, den Sie identifiziert haben, ein Zeiger auf den kritischen Abschnitt ist. Verlassen Sie sich nicht darauf, dass Parameter im Stack korrekt bleiben, da sie überschrieben und wiederverwendet werden können. Zum einen ist der Zeiger 736a3134 in msswock dem Code-Segment sehr nahe, so dass er wahrscheinlich einer der Rückkehrzeiger ist. –

Antwort

1

Nur, damit Sie wissen, dass wir versuchen, aufgeben, um herauszufinden, was dies verursacht wurde. Wie es nur passierte, wenn das Programm nah an seinem maximalen virtuellen Speicherraum (2.1GB 32bit app) war, wegen des Ansatzes mit einem Thread pro Verbindung, den wir benutzten.

Am Ende haben wir die Clients neu entworfen, damit sie diese Serveranwendung nicht mehr verwenden, sondern stattdessen einen SOAP-Server verwenden.

Der SOAP-Server scheint viel besser zu skalieren als die Datasnap/Midas, die wir verwenden, obwohl wir es immer noch auf der Client-Seite testen müssen, wo das anfängliche Problem auftauchte.

+0

Wir haben diese Lösung nun 3 Monate lang auf dem Kundenstandort laufen lassen. Es läuft ohne Probleme und wir haben eine Laufzeit von mehr als 60 Tagen gesehen (musste den Server für Windows-Updates neu starten). – MikeT

+0

Haben Sie den Rückgabewert von InitializeCriticalSection() überprüft. Diese Funktion kann nicht garantiert erfolgreich ausgeführt werden und kann aufgrund von Speichermangelbedingungen fehlschlagen. Diese letztere Tatsache scheint relevant zu sein, da Sie angegeben haben, dass Sie dem maximalen Gedächtnis nahe sind. –

+0

Sie haben wahrscheinlich hier den Nagel auf den Kopf getroffen, ich vermute, der kritische Abschnitt wurde nicht korrekt initialisiert und eine Ausnahme STATUS_NO_MEMORY ausgelöst. Wenn wir also versuchen, es einzugeben, überprüfen wir einen zufälligen Speicherbereich und interpretieren ihn als bereits von einem anderen Thread gesperrt. – MikeT

1

Wenn Sie die Ausgabe von! Analyze -hang -v betrachten, scheint es, dass Sie Application Verifier nicht verwenden. Ich würde Ihnen empfehlen, einen Hang Dump zu sammeln, nachdem Sie die Option "Locks" für den Anwendungsverifizierer aktiviert haben. Es würde Ihnen sicherlich mehr Informationen zur Fehlersuche geben.

Sie können Application Verifier von hier herunterladen:

http://www.microsoft.com/en-us/download/details.aspx?id=20028

Weitere Informationen:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd371695(v=vs.85).aspx

+0

Was passiert, wenn ich es im Debuger nicht zum Stillstand bringen kann? aber ich habe die Crash-Dumps mit Process Explorer erstellt. – MikeT