5

我正在使用 Windbg 分析在用 delphi 编写的数据快照应用程序服务器中发生的死锁。

当我跑

!analyze -hang -v

我明白了

:000:x86> !analyze -hang -v
****************************************************** *****************************
* *
* 异常分析 *
* *
****************************************************** *****************************

GetPageUrlData 失败,服务器返回 HTTP 状态 404
请求的 URL:http://watson.microsoft.com/00000000.htm?Retriage=1

FAULTING_IP:
+6ced240
00000000 ?? ???

EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff)
异常地址:0000000000000000
   ExceptionCode:80000003(Break指令异常)
  异常标志:00000000
编号参数:0

FAULTING_THREAD:0000000000000000

BUGCHECK_STR:挂起

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 临界区       

WAIT_CHAIN_COMMAND: ~0s;k;;

BLOCKING_THREAD:0000000000002634

PRIMARY_PROBLEM_CLASS:APPLICATION_HANG

LAST_CONTROL_TRANSFER:从 0000000077138df4 到 000000007711f8b1

堆栈文本:  
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
警告:堆栈展开信息不可用。以下框架可能是错误的。
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:机器所有者

模块名称:C:\Windows\System32\mswsock

IMAGE_NAME:lld

DEBUG_FLR_IMAGE_TIMESTAMP:4ce7c83d

STACK_COMMAND: ~0s ; KB

FAILURE_BUCKET_ID:APPLICATION_HANG_cfffffff_lld!卸载

BUCKET_ID: X64_HANG_mswsock!GetLspGuid+19af

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

跟进:MachineOwner
---------

然后我做了

!locks -V

查看它在等待哪个锁,令我惊讶的是它返回了这个,

0:000:x86> !locks -V

CritSec ntdll!RtlCriticalSectionLock+0 在 0000000077057060
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec ntdll!LdrpLoaderLock+0 at 0000000077057490
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec ntdll!RtlpDynamicFunctionTableLock+0 at 0000000077057468
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec ntdll!FastPebLock+0 在 000000007705a900
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec ntdll!RtlpProcessHeapsListLock+0 at 000000007705a240
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec +270208 在 0000000000270208
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 1

CritSec ntdll!EtwProvCritSect+0 在 000000007705a120
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec ntdll!EtwPrivSessionCritSect+0 在 000000007705a1e0
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec +10208 在 0000000000010208
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

CritSec +276f40 在 0000000000276f40
LockCount 未锁定
递归计数 0
拥有线程 0
条目数 0
争用计数 0

扫描了 10 个关键部分

从查看调用堆栈

堆栈文本:  
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
警告:堆栈展开信息不可用。以下框架可能是错误的。
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

我确定它正在等待地址 0x736a3134 的关键部分(传递给 RtlEnterCriticalSection 的第一个参数)所以我运行了这个

!critsec 736a3134

这给了我这个输出

0:000:x86> !critsec 736a3134

位于 00000000736a3134 的 CritSec 的 DebugInfo 未指向临界区
不是初始化的临界区。

CritSec mswsock!WSPStartup+6f64 at 00000000736a3134
服务员醒来 是的
锁定计数 -1
递归计数 11028
拥有线程 c6c
条目计数 1f49dad6
争用计数 88000000
*** 锁定

现在一分钱掉了,指向临界区的指针已经损坏,可能是由于并发线程访问和代码中其他地方缺乏同步

我的问题是我如何追踪它在哪里或找出它是否是另一个问题?

PS:此错误仅在应用程序负载过重且可能连接了 700 个客户端时出现

(每个连接使用一个线程,我知道 32 位应用程序将被限制为默认线程堆栈大小的大约 2000 个线程,这不是最好的方法)

PPS:我有多个故障转储,其中应用程序挂起等待不同的关键部分,在每种情况下,关键部分的指针似乎都没有指向关键部分。

4

2 回答 2

2

查看 !analyze -hang -v 的输出,您似乎没有使用 Application Verifier。我建议您在启用应用程序验证程序“锁定”选项后收集挂起转储。它肯定会为您提供更多故障排除信息。

您可以从此处下载应用程序验证程序:

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

更多信息:

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

于 2012-09-11T20:22:45.557 回答
1

只是为了让您知道我们放弃了试图找出造成这种情况的原因。因为它只发生在程序接近其最大虚拟内存空间(2.1GB 32 位应用程序)时,因为我们使用的每个连接方法一个线程。

最后,我们重新设计了客户端,因此他们不再使用这个服务器应用程序,而是现在使用 SOAP 服务器。

SOAP 服务器的扩展性比我们使用的 datasnap/Midas 好得多,尽管我们仍要在出现初始问题的客户端站点对其进行测试。

于 2012-09-24T15:31:32.727 回答