Comment les threads .NET peuvent-ils attendre un syncblk n’appartenant à aucun thread?

Un cliché sur les accidents de mon application affiche un groupe de threads en attente d’un syncblk, et le syncblk indique qu’il ne possède pas de thread propriétaire. Comment est-ce possible? J’essaie de reproduire le symptôme dans une application de test, et je ne peux pas comprendre ce qui pourrait arriver à ce résultat … avoir le thread propriétaire sortant ou mourant sans libérer le syncblk apparaît toujours comme propriétaire de l’object , juste le threadid est “XXX” …. J’ai testé l’utilisation de sorties gracieuses entièrement gérées et de terminaisons de threads via pinvoke …. j’ai testé différentes combinaisons d’attentes sans impulsions, d’entrées et de sorties incorrectes … rien ne produit un syncblk qui bloque les discussions et ne montre aucun propriétaire ….. je manque d’idées

Voici le résultat de mon crash que je tente de répliquer: (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 

SyncBlock 000000019f1ec5d8 est celui sans propriétaire. Est également le seul avec un nombre pair MonitorHeld . Étant donné que MonitorHeld incrémente de 1 pour le propriétaire et de 2 pour chaque serveur, je suppose qu’il s’agit d’une ressource publiée juste avant le dump et qu’un nouveau propriétaire n’a pas encore été atsortingbué. Des ressources inéquitables signalent tous les serveurs lors de leur libération et les serveurs s’empressent de l’acquérir (ce comportement injuste évite les verrous de convoi). Tant que les serveurs ne sont pas planifiés et exécutés, et que le premier serveur n’empoigne pas la ressource, il n’y aura pas de propriétaire.

Voir aussi Un grand nombre de serveurs sur une section critique libre peut indiquer un convoi de serrures :

Si vous déboguez un problème de performance dans votre application, vous risquez de rencontrer une section critique dans un état très étrange: de nombreux threads l’attendent, mais personne ne le possède!

Cet état signifie que l’ancien propriétaire de la section critique vient de la quitter et a signalé à un thread en attente de le prendre, mais ce fil n’a pas encore eu la chance de s’exécuter.

Ce que vous décrivez peut avoir plusieurs raisons:

  • Le fil propriétaire est devenu instable avec quelques violations d’access désagréables
  • Le fil propriétaire est devenu instable avec OutOfMemoryExceptions
  • Une partie du système (comme un pilote …) a provoqué une situation étrange
  • Certaines bibliothèques tierces utilisant du code natif ont rendu le processus instable
  • Une partie essentielle du cadre (comme la gestion de la mémoire / du GC / GC) est devenue instable et / ou est morte alors qu’elle était au milieu d’une opération importante.

Tout ce qui précède est plutôt difficile à reproduire …

Pour un résumé intéressant sur syncblk, voir http://blogs.msdn.com/b/tess/archive/2006/01/09/a-hang-scenario-locks-and-critical-sections.aspx

Possibilité 1: le syncblk est effacé et le prochain des 16 threads le récupérera dès qu’il sera à nouveau programmé. Possibilité 2: Vous avez une mémoire corrompue.