{"id":21403,"date":"2008-07-31T10:00:00","date_gmt":"2008-07-31T10:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2008\/07\/31\/dont-be-helpless-you-can-put-things-together-it-doesnt-have-to-be-a-single-command\/"},"modified":"2008-07-31T10:00:00","modified_gmt":"2008-07-31T10:00:00","slug":"dont-be-helpless-you-can-put-things-together-it-doesnt-have-to-be-a-single-command","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080731-00\/?p=21403","title":{"rendered":"Don&#8217;t be helpless: You can put things together, it doesn&#8217;t have to be a single command"},"content":{"rendered":"<p><P>\nHumans are distinguished among all animal species by their advanced\ndevelopment of and heavy reliance on tools.\nDon&#8217;t betray your ancestors.\nUse those tools you have.\n<\/P>\n<P>\nFor example, during the debugging of a thread pool problem,\nit looked like somebody did a <CODE>PostThreadMessage<\/CODE>\nto a thread pool thread and left the message unprocessed after\nthe thread pool function returned.\nWho could it have been?\nWell, one idea was to see if there were any DLLs in the system\nwhich called both <CODE>QueueUserWorkItem<\/CODE> and\n<CODE>PostThreadMessage<\/CODE>.\n<\/P>\n<P>\nI did a little legwork and contributed the following analysis\nto the mail thread:\n<\/P>\n<BLOCKQUOTE CLASS=\"m\">\n<P>\nOf all the DLLs loaded into the process,\nthe following call <CODE>PostThreadMessage<\/CODE>:\n<\/P>\n<P>\nSHLWAPI.dll       77D72436    221 PostThreadMessageA<BR>\nSHELL32.dll       77D78596    222 PostThreadMessageW<BR>\nole32.dll       77D78596    222 PostThreadMessageW<BR>\n&#8230; (list trimmed; you get the idea) &#8230;\n<\/P>\n<P>\nOf those DLLs, these also call <CODE>QueueUserWorkItem<\/CODE>:\n<\/P>\n<P>\nshlwapi.dll<BR>\nshell32.dll<BR>\n&#8230; (list trimmed; you get the idea) &#8230;\n<\/P>\n<\/BLOCKQUOTE>\n<P>\nAstounded, somebody wanted to know how I came up with that list.\n<\/P>\n<P>\nNothing magic.\nYou have the tools,\nyou have a brain,\nso connect the dots.\n<\/P>\n<P>\nThe <CODE>lm<\/CODE> debugger command lists all the DLLs loaded into\nthe process.\nCopy the output from the debugger window and paste it into a text\nfile.\nNow write a little script that takes each line of the text file\nand does a <CODE>link \/dump \/imports<\/CODE> on the corresponding DLL.\nI happen to prefer perl for this sort of thing, but you can use\na boring batch file if you like.\n<\/P>\n<PRE>\nfor \/f %i in (dlls.txt) do ^\n@echo %i &amp; link \/dump \/imports %i | findstr PostThreadMessage\n<\/PRE>\n<P>\nScrape the results off the screen, prune out the misses,\nand there you have it.\n<\/P>\n<P>\n&#8220;I tried that, but the result wasn&#8217;t in the same format as what you posted.&#8221;\n<\/P>\n<P>\nWell, yeah.\nThere&#8217;s no law that says that I can&#8217;t manually reformat the data\nbefore presenting it in an email message.\nSince there were only a dozen hits,\nit&#8217;s not worth writing a script\nto do that type of data munging.\nTyping &#8220;backspace, home, up-arrow&#8221; twelve times\nis a lot faster than writing a script to take the output of\nthe above batch file and turn it into the output I used in the\nemail message.\n<\/P>\n<P>\nAnother boring batch file filters the list to those DLLs that\nalso call <CODE>QueueUserWorkItem<\/CODE>.\nWriting it (or a script in your favorite language) is left\nas an exercise.\n<\/P>\n<P>\nNo rocket science here.\nJust taking a bunch of tools and putting them together to solve\na problem.\nThat&#8217;s what your brain is for, after all.\n<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Humans are distinguished among all animal species by their advanced development of and heavy reliance on tools. Don&#8217;t betray your ancestors. Use those tools you have. For example, during the debugging of a thread pool problem, it looked like somebody did a PostThreadMessage to a thread pool thread and left the message unprocessed after the [&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-21403","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-other"],"acf":[],"blog_post_summary":"<p>Humans are distinguished among all animal species by their advanced development of and heavy reliance on tools. Don&#8217;t betray your ancestors. Use those tools you have. For example, during the debugging of a thread pool problem, it looked like somebody did a PostThreadMessage to a thread pool thread and left the message unprocessed after the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21403","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=21403"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/21403\/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=21403"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=21403"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=21403"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}