How can .NET threads be waiting on a syncblk which is not owned by any thread?

老子叫甜甜 提交于 2019-12-19 14:27:12

问题


I have a crash dump from my app showing a bunch of threads waiting on a syncblk, and the syncblk shows that it has no owning thread. How is that possible? I'm trying to reproduce the symptom in a test app, and I can't figure out what could possibly happen to produce that result....having the owning thread exit or die without releasing the syncblk still shows up as owning the object, just the threadid is "XXX"....I've tested using fully managed graceful exit and hard thread termination via pinvoke....I tested a bunch of different combinations of waits without pulses, mismatched enters and exits...nothing produces a syncblk which blocks threads and shows no owner.....I'm running out of ideas

Here is the output from my crashdump that I'm trying to replicate: (Note index #1236)

0:000> !syncblk
Index         SyncBlock MonitorHeld Recursion Owning Thread Info          SyncBlock Owner
 784 0000000004f12eb0            3         1 000000000508a460  32a8  68   00000001a0a20510
 966 0000000004f06928            1         1 00000000052c5da0  2380 114   00000001df3080f8
1085 0000000004f23088            1         1 00000000052c8080  496c 120   00000001a0325238
1144 0000000005160d20            1         1 00000000050968b0   d74  56   00000000ff61b570
1151 0000000004f0c2c8            1         1 000000000508d8b0  3f64  77   000000017f66dc20
1236 0000000004f0b4f8           16         0 0000000000000000     none    000000019f1ec5d8
1261 0000000004f0ffe8            1         1 0000000008f18fc0  446c  94   000000013f8e70b0
1306 0000000004f0e918            1         1 00000000052c91f0  406c 123   000000011f5936f8
1318 0000000004f0e528            3         1 0000000008f1d580  24d8 106   000000015fc73f28
1329 0000000004f0cc58            1         1 0000000005095740  2fbc  53   000000011f36d320
1332 0000000004f15b38            1         1 0000000008f16710  3804  87   000000019f964728
1387 0000000004f22350            1         1 0000000008f18420  5180  92   00000001a008ab08
1515 0000000004f1d5d0            1         1 00000000052c4c30  2b5c 111   00000000ffd3c068
1594 0000000004f19bc0            1         1 000000000508ea20  188c  80   000000012012c538
1660 0000000004f13608            1         1 00000000050892f0  32fc  65   00000001df800940
1682 00000000051608a0            1         1 000000000508c740  1d58  74   00000001bfa03d20
1746 0000000004f14e88            1         1 0000000008f1c9e0   e88 104   000000015f6fcd10
1883 0000000004f19938            1         1 0000000005092e90  27c4  46   00000000ff76d2b0
1886 0000000004f1b760            1         1 0000000008f19b60  2dd4  96   000000019fc07030
2036 0000000004f1ae10            1         1 0000000008f1be40  4f58 102   00000001dfcb9da8
2042 0000000004f12e68            1         1 00000000052c8c20  2300 122   000000015f6aaa98
2049 0000000004f1cda0            1         1 00000000052c9d90  1948 126   00000001df6fd688
2153 0000000004f16d88            1         1 0000000005094ba0  3f04  51   00000000ff677eb8
2262 0000000004f13de8            3         1 00000000052ca360   6fc 127   000000011fd7a450
2358 00000000050fc390            1         1 0000000009221280  3ca0 130   0000000120055ca0
-----------------------------
Total           2553
CCW             3
RCW             2
ComClassFactory 0
Free            1212

回答1:


SyncBlock 000000019f1ec5d8 is the one with no owner. Is also the only one with an even MonitorHeld count. Since the MonitorHeld increments with 1 for the owner and 2 for each waiter my guess would be that this is a resource that was released just before the dump was taken, and there was not yet granted a new owner. Unfair resources signal all waiters on release and the waiters rush to acquire it (this unfair behavior avoid convoy locks). Until the waiters are scheduled and run, and the first waiter grabs the resource, there will be no owner.

See also A high waiter count on a free critical section may indicate a lock convoy:

If you're debugging a performance problem in your application, you may run across a critical section in a very strange state: A lot of threads are waiting for it, but nobody owns it!

...

This state means that the previous owner of the critical section has just exited it and signalled a waiting thread to take it, but that thread hasn't yet gotten a chance to run yet




回答2:


What you describe might have several reasons:

  • Owning thread got unstable with some nasty access violations
  • Owning thread got unstable with OutOfMemoryExceptions
  • Some part of the system (like a driver...) caused a strange situation
  • Some 3rd-party library using native code caused the process to become unstable
  • Some essential part of the framework (like GC/memory management/thread management) got unstable and/or died while in the middle of some important operation

Any of the above is rather hard to reproduce...

For a nice summary on syncblk see http://blogs.msdn.com/b/tess/archive/2006/01/09/a-hang-scenario-locks-and-critical-sections.aspx




回答3:


Possibility 1: The syncblk is cleared and the next of the 16 threads will grab it as soon as it is scheduled again. Possibility 2: You have corrupt memory.



来源:https://stackoverflow.com/questions/7825477/how-can-net-threads-be-waiting-on-a-syncblk-which-is-not-owned-by-any-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!