{"id":293,"date":"2014-08-08T07:00:00","date_gmt":"2014-08-08T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/08\/08\/the-case-of-the-orphaned-lpdrloaderlock-critical-section\/"},"modified":"2014-08-08T07:00:00","modified_gmt":"2014-08-08T07:00:00","slug":"the-case-of-the-orphaned-lpdrloaderlock-critical-section","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140808-00\/?p=293","title":{"rendered":"The case of the orphaned LpdrLoaderLock critical section"},"content":{"rendered":"<p>\nA customer found that under heavy load,\ntheir application would occasionally hang.\nDebugging the hang shows that everybody was waiting for the\n<code>Lpdr&shy;Loader&shy;Lock<\/code> critical section.\nThe catch was that the critical section was reported as locked,\nbut the owner thread did not exist.\n<\/p>\n<pre>\n0:000&gt; !critsec ntdll!LdrpLoaderLock\nCritSec ntdll!LdrpLoaderLock+0 at 7758c0a0\nWaiterWoken        No\nLockCount          4\nRecursionCount     2\nOwningThread       150c\nEntryCount         0\nContentionCount    4\n*** Locked\n0:000&gt; ~~[150c]k\n              ^ Illegal thread error in '~~[150c]k'\n<\/pre>\n<p>\nHow can a critical section be owned by thread that no longer exists?\n<\/p>\n<p>\nThere are two ways this can happen.\nOne is that there is a bug in the code that manages the critical\nsection such that there is some code path that takes the critical\nsection but forgets to release it.\nThis is unlikely to be the case for the loader lock\n(since a lot of really smart people are in charge of the loader lock),\nbut it&#8217;s a theoretical possibility.\nWe&#8217;ll keep that one in our pocket.\n<\/p>\n<p>\nAnother possibility is that the code to exit the critical section\nnever got a chance to run.\nFor example, somebody may have thrown an exception\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2012\/09\/10\/10347674.aspx\">\nacross the stack frames which manage the critical section<\/a>,\nor somebody may have tried to exit the thread from inside the\ncritical section,\nor (gasp) somebody may have called\n<code>Terminate&shy;Thread<\/code> to nuke the thread from orbit.\n<\/p>\n<p>\nI suggested that the\n<code>Terminate&shy;Thread<\/code> theory was a good one to start with,\nbecause even if it wasn&#8217;t the case,\nthe investigation should go quickly because\n<a HREF=\"http:\/\/c2.com\/cgi\/wiki?WhereTheLightIsBetter\">\nthe light is better<\/a>.\nYou&#8217;re not so much interested in finding it as you are in ruling it out\nquickly.&sup1;\n<\/p>\n<p>\nThe customer replied,\n&#8220;We had one call to <code>Terminate&shy;Thread<\/code> in our application,\nand we removed it,\nbut the problem still occurs.\nIs it worth also checking the source code of the DLLs our application\nlinks to?&#8221;\n<\/p>\n<p>\nOkay, the fact that they <i>found one at all<\/i> means that\nthere&#8217;s a good chance others are lurking.\n<\/p>\n<p>\nBefore we could say, &#8220;Yes, please continue your search,&#8221;\nthe customer followed up.\n&#8220;We found a call to\n<code>Terminate&shy;Thread<\/code> in a component provided by\nanother company.\nThe code created a worker thread, and decided to clean up the\nworker thread by terminating it.\nWe commented out the call just as a test,\nand it seems to fix the problem.\nSo at least now we know where the problem is and we can try to fix\nit properly.&#8221;\n<\/p>\n<p>\n&sup1; In the medical profession, there&#8217;s the term\nROMI, which stands for <i>rule out myocardial infarction<\/i>.\nIt says that if a patient comes to you with anything that could\npossibly remotely be the symptom of a heart attack,\nlike numbness in the arm or chest pain,\nyou should perform a test to make sure.\nEven though the test is probably going to come back negative,\nyou have to check just to be safe.\nHere, we&#8217;re ruling out <code>Terminate&shy;Thread<\/code>,\nwhich I guess could go by the dorky acronym ROTT.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer found that under heavy load, their application would occasionally hang. Debugging the hang shows that everybody was waiting for the Lpdr&shy;Loader&shy;Lock critical section. The catch was that the critical section was reported as locked, but the owner thread did not exist. 0:000&gt; !critsec ntdll!LdrpLoaderLock CritSec ntdll!LdrpLoaderLock+0 at 7758c0a0 WaiterWoken No LockCount 4 RecursionCount [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-293","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer found that under heavy load, their application would occasionally hang. Debugging the hang shows that everybody was waiting for the Lpdr&shy;Loader&shy;Lock critical section. The catch was that the critical section was reported as locked, but the owner thread did not exist. 0:000&gt; !critsec ntdll!LdrpLoaderLock CritSec ntdll!LdrpLoaderLock+0 at 7758c0a0 WaiterWoken No LockCount 4 RecursionCount [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/293","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=293"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/293\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}