{"id":27103,"date":"2007-04-26T10:00:00","date_gmt":"2007-04-26T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2007\/04\/26\/using-the-gu-debugger-command-to-find-the-infinite-loop\/"},"modified":"2007-04-26T10:00:00","modified_gmt":"2007-04-26T10:00:00","slug":"using-the-gu-debugger-command-to-find-the-infinite-loop","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20070426-00\/?p=27103","title":{"rendered":"Using the &#034;gu&#034; debugger command to find the infinite loop"},"content":{"rendered":"<p>\nSomebody says, &#8220;Your program is consuming 100% CPU&#8221;\nand hands you a debug session.\nUsually, this happens because one thread has gotten stuck\nin an infinite loop.\nAnd if you&#8217;re lucky it&#8217;s the type of infinite loop that&#8217;s\neasy to diagnose because it&#8217;s just one function that isn&#8217;t\nreturning.\n(The more complicated types are where a function does some work\nand then returns, and then some of that work has a delayed effect\nthat causes the function to run again, and so on.)\nLet&#8217;s assume we&#8217;re lucky because, well,\n<!-- backref: assume code is mostly good -->\ndebugging is an exercise in optimism<\/a>.\n<\/p>\n<p>\nThe first step is to find the thread that is using all the CPU.\nThat&#8217;s actually pretty easy with the help of the\n<code>!runaway<\/code> debugger extension.\n<\/p>\n<pre>\n0:011&gt; !runaway\n User Mode Time\n Thread    Time\n 192c      0 days 0:05:22.457\n 1384      0 days 0:00:16.063\n 14ac      0 days 0:00:08.392\n 48c       0 days 0:00:03.955\n 1db0      0 days 0:00:00.010\n 1888      0 days 0:00:00.010\n 1078      0 days 0:00:00.000\n 1470      0 days 0:00:00.000\n 1f84      0 days 0:00:00.000\n 1d60      0 days 0:00:00.000\n 1850      0 days 0:00:00.000\n 134c      0 days 0:00:00.000\n 19fc      0 days 0:00:00.000\n 1b4       0 days 0:00:00.000\n<\/pre>\n<p>\nWow, thread 0x192c has sure used a lot of CPU time,\nbut that doesn&#8217;t mean that it&#8217;s the thread that is in a 100% CPU loop,\nbecause the CPU time is cumulative over the lifetime of the thread.\nMaybe that thread has a lot of CPU time because it&#8217;s been around\nthe longest.\nWhat you need to do is resume execution for a little while, then\nbreak in again and see whose CPU time has <strong>increased<\/strong>.\n<\/p>\n<pre>\n0:011&gt; g\n^C\n(1928.1d34): Break instruction exception - code 80000003 (first chance)\neax=7ffd9000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005\neip=7c901230 esp=0124ffcc ebp=0124fff4 iopl=0         nv up ei pl zr na po nc\ncs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246\nntdll!DbgBreakPoint:\n7c901230 cc               int     3\n0:011&gt; !runaway\n User Mode Time\n Thread    Time\n 192c      0 days 0:05:23.679\n 1384      0 days 0:00:16.063\n 14ac      0 days 0:00:08.392\n 48c       0 days 0:00:03.955\n 1db0      0 days 0:00:00.010\n 1888      0 days 0:00:00.010\n 1078      0 days 0:00:00.000\n 1470      0 days 0:00:00.000\n 1ea4      0 days 0:00:00.000\n 1d60      0 days 0:00:00.000\n 1850      0 days 0:00:00.000\n 134c      0 days 0:00:00.000\n 19fc      0 days 0:00:00.000\n 1b4       0 days 0:00:00.000\n<\/pre>\n<p>\nAha, we see that thread 0x192c is the only one who gained\nany noticeable amount of CPU time.\nThat&#8217;s probably the one that&#8217;s responsible for the 100% CPU usage.\n<\/p>\n<pre>\n0:011&gt; ~~[192c]s\neax=00000000 ebx=77d5e581 ecx=0012daa0 edx=0000000c esi=01d18140 edi=00000000\neip=77d5e590 esp=0012da78 ebp=0012da88 iopl=0         nv up ei pl zr na po nc\ncs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246\nUSER32!FindWindowA+0xf:\n77d5e590 50               push    eax\nChildEBP RetAddr\n0012da88 1000714b USER32!FindWindowA+0xf\n0012dbc8 100061f3 ABC!CAlpha::FindTarget+0x27f\n0012dbf4 603517e8 ABC!CBeta::TransferData+0x18a\n0012dc28 10002d9d DEF!CGamma:TransferData+0xc\n0012dc48 00505303 ABC!CBeta::BeginAsync+0x51\n0012dc5c 0090a21a GHI!CPrintSession::Open+0x2a51\n0012dd20 009099d8 GHI!CPrintSession::Init+0x252\n0012e060 009097e6 GHI!CPrintOptions::GetSettings+0x24a\n0012e0a4 0090973d GHI!CPrintOptions::OpenSettings+0x248\n0012e130 00909664 GHI!CDocumentMenu::OnInvoke+0x24\n...\n<\/pre>\n<p>\nNow this is where\n<a HREF=\"http:\/\/blogs.msdn.com\/doronh\/archive\/2006\/05\/05\/591195.aspx\">\nthe magical &#8220;gu&#8221; command<\/a>\ncomes in.\nYou type &#8220;gu&#8221; to run the current function until it returns.\nIf you get another prompt back, then type &#8220;gu&#8221; again,\nto run <strong>that<\/strong> function until it returns.\nAnd so on, until you find the function that doesn&#8217;t return.\n<\/p>\n<p>\nThat&#8217;s the one with the infinite loop.\n<\/p>\n<p>\nNow you can start investigating why that function is stuck.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Somebody says, &#8220;Your program is consuming 100% CPU&#8221; and hands you a debug session. Usually, this happens because one thread has gotten stuck in an infinite loop. And if you&#8217;re lucky it&#8217;s the type of infinite loop that&#8217;s easy to diagnose because it&#8217;s just one function that isn&#8217;t returning. (The more complicated types are where [&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":[26],"class_list":["post-27103","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Somebody says, &#8220;Your program is consuming 100% CPU&#8221; and hands you a debug session. Usually, this happens because one thread has gotten stuck in an infinite loop. And if you&#8217;re lucky it&#8217;s the type of infinite loop that&#8217;s easy to diagnose because it&#8217;s just one function that isn&#8217;t returning. (The more complicated types are where [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27103","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=27103"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/27103\/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=27103"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=27103"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=27103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}