<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>greggm's WebLog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/greggm/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/greggm/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 05:09:15 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Debugging a .NET Framework 2.0/3.0/3.5 class library with VS 2010</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/debugging-a-net-framework-2-03-03-5-class-library-with-vs-2010</link>
      <pubDate>Tue, 08 Jun 2010 09:07:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2010/06/08/debugging-a-net-framework-2-03-03-5-class-library-with-vs-2010/</guid>
      <description><![CDATA[A number of people have had difficulty debugging a .NET Framework 2.0/3.0/3.5 class library that...]]></description>
      <content:encoded><![CDATA[<p>A number of people have had difficulty debugging a .NET Framework 2.0/3.0/3.5 class library that loads into a native executable. The debugger will launch, and their code will run, but the debugger will not stop at breakpoints, detect that modules load, etc.</p>
<p>The problem is that the debugger is trying to determine what version of the .NET Framework your class library will load into, and the debugger has guessed incorrectly.</p>
<p>The work around for this is to add a config file next to the native executable to tell the debugger what version of the .NET Framework to debug. </p>
<p>So if you are trying to debug c:\proj\MyNativeProject\debug\MyNativeProject.exe, then create c:\proj\MyNativeProject\debug\MyNativeProject.exe.config with this content:</p>
<p>&lt;?xml version ="1.0"?&gt;<br />&lt;configuration&gt;<br />&nbsp;&nbsp;&nbsp; &lt;startup&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;supportedRuntime version="v2.0.50727" /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/startup&gt;<br />&lt;/configuration&gt;</p>]]></content:encoded>
    </item>
    <item>
      <title>Notes from debugging a managed memory leak</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/notes-from-debugging-a-managed-memory-leak</link>
      <pubDate>Thu, 29 Oct 2009 17:49:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2009/10/29/notes-from-debugging-a-managed-memory-leak/</guid>
      <description><![CDATA[Recently, I spent a while digging into a managed memory leak. This is a pretty well-worn blog topic,...]]></description>
      <content:encoded><![CDATA[<P>Recently, I spent a while digging into a managed memory leak. This is a pretty well-worn blog topic, but I figured I would add my two cents to it anyway, as I found a few things that I didn't notice in the existing blogs.</P>
<P>First, Rico wrote up the basic approach back in 2004, so you should start by reading this - <A href="https://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx" mce_href="https://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx">https://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx</A>. This will give you an intro to using sos.dll in WinDbg.</P>
<P>What I would like to add:</P>
<H3>#1: How to decide if you have a leak in the first place. </H3>
<P>Since GC's happen non-deterministically, it can be hard to know if you actually have a managed leak. For example, if you look at memory usage at the end of a user scenario, you will likely see memory usage all over the map based on when the last GC happened. The best technique I found for this is to stop after gen-2 collections. This isn't perfect since gen-2 collections can still happen at any time in your code, but it still gives you a better estimate then stopping after user scenarios.</P>
<P>To stop after the next gen-2 GC: !findroots -gen 2</P>
<P>Note that this command is new for the CLRv4 version of sos.dll (also available in Silverlight). I am assuming that you could achieve similar functionality with a well-placed breakpoint in older CLRs, but I am not familiar enough with the inner workings of the GC to tell you where.</P>
<H3>#2: Use CLRProfiler to visualize the leaks</H3>
<P>This may have been specific to my scenario, but I didn't have a lot of success with !gcroot. I had more success understanding the problem by loading up a .log file in CLRProfiler (<A href="https://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&amp;DisplayLang=en" mce_href="https://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&amp;DisplayLang=en">https://www.microsoft.com/downloads/details.aspx?FamilyID=a362781c-3870-43be-8926-862b40aa0cd0&amp;DisplayLang=en</A>). One note that I found here was to _not_ use '-xml' when saving out the log as CLRProfiler doesn't understand the XML format.</P>
<P>To save the log out: !TraverseHeap c:\users\greggm\desktop\myheap.log</P>
<H3>#3: !gcroot doesn't show roots in CCW's</H3>
<P>When native code calls into managed code from COM, native code gets a CCW (COM callable wrapper). If native code leak's its CCW, the managed object will be leaked, but !gcroot will not tell you why.<BR></P>]]></content:encoded>
    </item>
    <item>
      <title>Tracing calls to QueryInterface on a managed object</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/tracing-calls-to-queryinterface-on-a-managed-object</link>
      <pubDate>Thu, 23 Jul 2009 17:31:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2009/07/23/tracing-calls-to-queryinterface-on-a-managed-object/</guid>
      <description><![CDATA[To date, one difficulty with implementing COM interfaces in managed code is that until now there has...]]></description>
      <content:encoded><![CDATA[<P>To date, one difficulty with implementing COM interfaces in managed code is that until now there has been know way to debug into QueryInterface. With CLR v4, its now possible to modify your object to trace calls to QueryInterface using the new ICusomQueryInterface interface (see <A href="https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustomqueryinterface.getinterface(VS.100).aspx" mce_href="https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustomqueryinterface.getinterface(VS.100).aspx">MSDN</A>).</P>
<P>Example:<BR><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>[<SPAN style="COLOR: #2b91af">ComVisible</SPAN>(<SPAN style="COLOR: blue">true</SPAN>)]<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">sealed</SPAN> <SPAN style="COLOR: blue">class</SPAN> <SPAN style="COLOR: #2b91af">MyObject</SPAN> : IMyInterface, ICustomQueryInterface<o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(<SPAN style="COLOR: blue">ref</SPAN> <SPAN style="COLOR: #2b91af">Guid</SPAN> iid, <SPAN style="COLOR: blue">out</SPAN> <SPAN style="COLOR: #2b91af">IntPtr</SPAN> ppv)<o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Debugger</SPAN>.Log(1, <SPAN style="COLOR: #a31515">"MyObject"</SPAN>, <SPAN style="COLOR: #a31515">"MyObject: QI'ed for "</SPAN> + iid.ToString() + <SPAN style="COLOR: #a31515">"\n"</SPAN>);<o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>ppv = <SPAN style="COLOR: #2b91af">IntPtr</SPAN>.Zero;<o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">return</SPAN> CustomQueryInterfaceResult.NotHandled;<o:p></o:p></SPAN></P>
<P style="LINE-HEIGHT: normal; MARGIN: 0in 0in 0pt; mso-layout-grid-align: none" class=MsoNormal><SPAN style="FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P style="MARGIN: 0in 0in 10pt" class=MsoNormal><SPAN style="LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; FONT-SIZE: 10pt; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>};</SPAN><o:p></o:p></P>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>What to do with a machine that doesn't support Hyper-V...</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/what-to-do-with-a-machine-that-doesnt-support-hyper-v</link>
      <pubDate>Tue, 12 May 2009 12:41:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2009/05/12/what-to-do-with-a-machine-that-doesnt-support-hyper-v/</guid>
      <description><![CDATA[In my little corner of the world, during the last year (give or take) Hyper-V went from something...]]></description>
      <content:encoded><![CDATA[<P>In my little corner of the world, during the last year (give or take) Hyper-V went from something that a few people were playing with to something that every single person couldn't live without. The huge benefit to us is the 'snapshot' feature, which allows us to instantaneously get a test machine back to clean state.</P>
<P>This left me with one problem&nbsp;- what to do with my old test machine which was too old to support Hyper-V, but too new to just throw away. Fortunately, Win7 came to my rescue by adding support for booting off a VHD (virtual hard disk). Now I can use <A href="https://technet.microsoft.com/en-us/library/cc720381.aspx" mce_href="https://technet.microsoft.com/en-us/library/cc720381.aspx">differencing virtual hard disks</A>, as a poor-man's Hyper-V and still get some millage out of my old test boxes.</P>
<P>Basic reimaging procedure:</P>
<OL>
<LI>Boot to my physical hard drive</LI>
<LI>Delete the current differencing disk</LI>
<LI>Create a new differencing disk</LI>
<LI>Boot back to my differencing disk</LI>
<LI>Rejoin the domain and install my test software (Visual Studio in my case)</LI></OL>
<P>Here is how I set this up:</P>
<OL>
<LI>Installed Win7 to my physical hard drive</LI>
<LI>After that install completed, I created a new Virtual Hard disk from the Disk Management MMC tool (Computer Management-&gt;Storage-&gt;Disk Management). I created a fixed Virtual Hard drive but I actually think that I dynamic disk would have been better since most of the parent virtual hard disk will remain empty. I named this file c:\windows7.vhd.</LI>
<LI>Boot to the Win7 installer again to install a second partition of Win7 on the VHD</LI>
<LI>After the installer finishes initializing, go to the repair tools and open a command prompt</LI>
<UL>
<LI>Run 'diskpart'</LI>
<LI>select vdisk file=c:\windows7.vhd.</LI>
<LI>attach vdisk</LI>
<LI>exit</LI></UL>
<LI>Now continue the Win7 installer, select the virtual disk as the partition to install to. Note that in RC builds, Win7 will warn you that Windows cannot install to this partition, but this warning appears to be ignorable.</LI>
<LI>After the install completes, install anything else to that parent partition that you need (ex: development tools, baseline libraries, etc).</LI>
<LI>Boot back to the physical hard drive.</LI>
<LI>Create a new differing vhd using the 'diskpart' tool (create vdisk file=c:\windows7.diff.vhd parent=c:\windows7.vhd)</LI>
<LI>Add a new boot menu entry for the differencing vhd, and set it as the default:</LI>
<UL>
<LI>bcdedit /copy {guid_of_vdisk} /d "Win7 (Diff VHD)" this will create a new boot entry and assign a Guid to it</LI>
<LI>bcdedit /set {guid_of_copy} device vhd=[C:]\windows7.diff.vhd</LI>
<LI>bcdedit /set {guid_of_copy} osdevice vhd=[C:]\windows7.diff.vhd</LI>
<LI>bcdedit /default {guid_of_copy}</LI></UL>
<LI>Boot to your new diff vhd and test away</LI></OL>
<P mce_keep="true">&nbsp;</P>]]></content:encoded>
    </item>
    <item>
      <title>Disabling script debugging in VS 2008 + IE8</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/disabling-script-debugging-in-vs-2008-ie8</link>
      <pubDate>Mon, 06 Apr 2009 20:11:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2009/04/06/disabling-script-debugging-in-vs-2008-ie8/</guid>
      <description><![CDATA[Visual Studio 2008 shipped with a feature to automatically enable script debugging when starting IE8...]]></description>
      <content:encoded><![CDATA[<P>Visual Studio 2008 shipped with a feature to automatically enable script debugging when starting IE8 from Visual Studio. In other words, if you are using VS 2008 and IE8, there is no longer a need to tweak IE options to debug your site.</P>
<P>However, this feature unfortunately created a problem which we didn't notice before VS 2008 shipped - web sites which create a large number of dynamic documents can perform quite poorly under the debugger, and now there is no option to run your site outside the debugger. If you open solution explorer and see the document list under 'Script Documents' dance up and down, you are running into this problem.</P>
<H3>Work around:</H3>
<OL>
<LI>This work around requires the Silverlight 2 Tools for Visual Studio 2008 SP1 to be installed. So if you don't have these tools installed, you can download them from Microsoft (<A href="https://www.microsoft.com/downloads/details.aspx?familyid=C22D6A7B-546F-4407-8EF6-D60C8EE221ED&amp;displaylang=en" mce_href="https://www.microsoft.com/downloads/details.aspx?familyid=C22D6A7B-546F-4407-8EF6-D60C8EE221ED&amp;displaylang=en">https://www.microsoft.com/downloads/details.aspx?familyid=C22D6A7B-546F-4407-8EF6-D60C8EE221ED&amp;displaylang=en</A>). If this is not an option for you, there is some alternative work arounds at the bottom of this blog post.</LI>
<LI>Right click on your project and open up project properties</LI>
<LI>Go to the 'Start Options' sheet, and click the 'Silverlight' button at the bottom of the screen. Because the debugger cannot debug both Silverlight code and Script code at the same time, this will disable Script debugging and therefore avoid the problem.</LI></OL>
<H3>Request for feedback:</H3>
<P>If you want to disable script debugging, I would love to hear about your scenario. We are aware of the performance issues with applications that create many documents. We hope to address this in a future version of Visual Studio.</P>
<H3>Alternative work around – disable all script debugging:</H3>
<UL>
<LI>Open a new command prompt (start-&gt;run, cmd.exe). If you are on a 64-bit computer this needs to be a 32-bit prompt (start-&gt;run, c:\windows\syswow64\cmd.exe)</LI>
<LI>reg add HKLM\SOFTWARE\Microsoft\VisualStudio\9.0\AD7Metrics\Engine\{F200A7E7-DEA5-11D0-B854-00A0244A1DE2} /v ProgramProvider /d {4FF9DEF4-8922-4D02-9379-3FFA64D1D639} /f</LI></UL>
<P>If you are using Visual Web Developer Express, replace 'VisualStudio' with 'VWDExpress':</P>
<UL>
<LI>reg add HKLM\SOFTWARE\Microsoft\VWDExpress\9.0\AD7Metrics\Engine\{F200A7E7-DEA5-11D0-B854-00A0244A1DE2} /v ProgramProvider /d {4FF9DEF4-8922-4D02-9379-3FFA64D1D639} /f</LI></UL>
<P>If you want to restore your computer so that you can debug scripts again:</P>
<UL>
<LI>reg add HKLM\SOFTWARE\Microsoft\VisualStudio\9.0\AD7Metrics\Engine\{F200A7E7-DEA5-11D0-B854-00A0244A1DE2} /v ProgramProvider /d {170EC3FC-4E80-40AB-A85A-55900C7C70DE} /f</LI></UL>
<H3>Work around for performance problems caused by 'anonymous code' nodes:</H3>
<P>Some sites run into problems being debugged due to numerous "anonymous code" nodes in solution explorer. For these sites, instead of disabling script debugging completely, it's possible to disable just the 'anonymous code' nodes. This requires Visual Studio 2008 SP1. To do so:</P>
<UL>
<LI>reg add HKCU\Software\Microsoft\VisualStudio\9.0\Debugger /v HideAnonymousScriptCodeNodes /t REG_DWORD /d 1 /f</LI></UL>]]></content:encoded>
    </item>
    <item>
      <title>Script debugging broken in VS 2005 after installing IE8</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/script-debugging-broken-in-vs-2005-after-installing-ie8</link>
      <pubDate>Wed, 01 Apr 2009 13:16:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2009/04/01/script-debugging-broken-in-vs-2005-after-installing-ie8/</guid>
      <description><![CDATA[[Note: This post has been updated&nbsp;with new information]
There is currently an issue in VS 2005...]]></description>
      <content:encoded><![CDATA[<P><EM>[Note: This post has been updated&nbsp;with new information]</EM></P>
<P>There is currently an issue in VS 2005 after you install IE8 where script debugging is broken. If you are using VS 2008, this will not be a problem.</P>
<P>Brad Sullivan posted the work around in the debugger <A href="https://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/e2c795cd-b7a0-4fad-b7c9-b1ca40d7302e/" mce_href="https://social.msdn.microsoft.com/Forums/en-US/vsdebug/thread/e2c795cd-b7a0-4fad-b7c9-b1ca40d7302e/">forum</A>. Here is what he said:</P>
<BLOCKQUOTE>
<P>IE 8 has a feature called Loosely-Coupled Internet Explorer (LCIE) which results in IE running across multiple processes. <BR><A href="https://www.microsoft.com/windows/internet-explorer/beta/readiness/developers-existing.aspx#lcie">https://www.microsoft.com/windows/internet-explorer/beta/readiness/developers-existing.aspx#lcie</A></P>
<P>Older versions of the Visual Studio Debugger get confused by this and cannot figure out how to attach to the correct process.&nbsp; You can work around this by disabling the process growth feature of LCIE.&nbsp; Here's how:</P>
<P>1)&nbsp; Open RegEdit<BR>2)&nbsp; Browse to HKEY_LOCALMACHINE -&gt; SOFTWARE -&gt; Microsoft -&gt; Internet Explorer -&gt; Main<BR>3)&nbsp; Add a dword under this key called TabProcGrowth<BR>4)&nbsp; Set TabProcGrowth to 0</P>
<P>Note that If you are using a 64-bit computer, you want to edit the 32-bit registry.</P></BLOCKQUOTE>
<P>In addition to this,&nbsp;IE's installer will re-disable script debugging. So you will need to reenable it:</P>
<OL>
<LI>Open Internet Explorer </LI>
<LI>Go to Tools-&gt;Internet Options</LI>
<LI>Switch to the Advanced tab</LI>
<LI>Uncheck 'Disable script debugging (internet explorer)'</LI></OL>
<P>One finial note&nbsp;- if you are attempting to debug a browser extension or ActiveX control written in native or managed code, you may experience the same problem. This will happen on all OSs with VS 2005, and on XP/Server 2003 with VS 2008. In this situation, you need to follow Brad’s work around.<BR><STRONG>&nbsp;</STRONG></P>
<P><STRONG>[July 10th Update]</STRONG>: We recently discovered another issue with Script Debugging after installing IE8. The issue does not always repro, which is how we missed it, but there is a workaround. To work around:</P>
<OL>
<LI>Install Visual Web Developer 2008 Express Edition, which is a free download from <A href="https://www.microsoft.com/express/vwd/Default.aspx">https://www.microsoft.com/express/vwd/Default.aspx</A>.</LI>
<LI>Optional step: Uninstall Visual Web Developer express</LI></OL>
<P>This will update the Visual Studio shared script debugging files (the files shared between every version of Visual Studio to enable script debugging) from the Visual Studio 2005 version to the 2008 version, and will thus work around the issue.</P>]]></content:encoded>
    </item>
    <item>
      <title>Exceptions Dialog explained (or what does 'User-Unhandled' mean)</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/exceptions-dialog-explained-or-what-does-user-unhandled-mean</link>
      <pubDate>Wed, 31 Dec 2008 13:38:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2008/12/31/exceptions-dialog-explained-or-what-does-user-unhandled-mean/</guid>
      <description><![CDATA[We recently had some questions on our internal Visual Studio Debugger forum about the exceptions...]]></description>
      <content:encoded><![CDATA[<P>We recently had some questions on our internal Visual Studio Debugger forum about the exceptions dialog. So I decided to take a stab at explaining it.</P>
<P>&nbsp;<IMG title="Exceptions dialog" style="WIDTH: 725px; HEIGHT: 360px" height=360 alt="Exceptions dialog" src="https://www.danfernandez.com/view/view.aspx?ID=193" width=725 mce_src="https://www.danfernandez.com/view/view.aspx?ID=193"></P><BR>
<H3>Just My Code</H3>
<P>The first step to understanding this dialog is to understand a feature called 'Just My Code' (enabled/disabled with 'Tools-&gt;Options-&gt;Debugging-&gt;Enable Just My Code'). Just My Code is currently a managed-only debugging feature. When enabled, the debugger divides up all the code running in the debugged process into two groups&nbsp;- your code, and non-user code (system code). It then tries to hide the details of system code from you so that you can concentrate on looking at your own code.</P>
<H3>User-Unhandled Defined</H3>
<P>Next concept to explain: 'User-Unhandled' exceptions. An exception becomes 'User-Unhandled' after:</P>
<OL>
<LI>An exception travels through your code&nbsp; (your code either throws the exception or calls into system code which throws an exception back to you)<BR>-and-</LI>
<LI>Your code doesn't catch the exception<BR>-and-</LI>
<LI>The exception is caught by system code</LI></OL>
<P>In other words: 'User-unhandled' does not necessarily mean that your app is actually crashing. The debugger is trying to tell you about an exception which is probably interesting before this exception is swallowed up by the system. After catching the exception, the system might fall over and die, or it might be totally expected (in which case you should go to Debug-&gt;Exceptions and turn off stopping on 'User Unhandled' exceptions for your app).</P>
<P>Example: You are building a WinForms app which has a bug in its handler for some button which will cause it to deref null. If you run this app outside of a debugger, and then attach the debugger, WinForms will quietly swallow the exception. But if you have 'User unhandled' exceptions enabled, the debugger will stop and you can easily find out what went wrong.</P>
<H3>Now to the dialog</H3>
<P>Now that we have the concepts, let's explain how they are expressed in the dialog.</P>
<P><STRONG>For exceptions that don't support Just My Code</STRONG> (C++ Exceptions, Managed Debug Assistants, Win32 Exceptions, Common Language Runtime Exceptions if Just My Code is disabled) – the debugger will show the 'User-Unhandled' checkbox as checked and disabled. What this is trying to tell you is that this setting is 'N/A'. For this type of code, the debugger doesn't divide the world up into user code and non-user code. So an exception could never go user-unhandled.</P>
<P>For these exceptions, the 'Thrown' column has the same meaning that it does in other debuggers (WinDbg calls this 'first chance', VS 2002/3 referred to this as 'Break' instead of 'Continue').</P>
<P><STRONG>For exceptions Common Language Runtime Exceptions</STRONG> (with Just My Code enabled): Both the 'Thrown' and 'User-Unhandled' column can be checked. 'User-unhandled' has the meaning discussed above. Checking 'Thrown' will cause the debugger to stop when either user code throws the exception, or when system code throws the exception back to user code. In other words, the debugger will not stop for internal exceptions within the system code.</P>
<P mce_keep="true"><STRONG>What about unhandled exceptions? </STRONG>The debugger always stops on unhandled exceptions since the process will otherwise exit. Since the debugger always stops, there doesn't need to be a checkbox for this one.</P>]]></content:encoded>
    </item>
    <item>
      <title>Attaching a debugger at startup</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/attaching-a-debugger-at-startup</link>
      <pubDate>Fri, 12 Sep 2008 15:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2008/09/12/attaching-a-debugger-at-startup/</guid>
      <description><![CDATA[Sometimes you need to debug a process, and you need to attach the debugger right away, but you...]]></description>
      <content:encoded><![CDATA[<P>Sometimes you need to debug a process, and you need to attach the debugger right away, but you cannot launch the process under the debugger. For example, if the process you need to debug is a Windows Service, the Windows Service Manager must launch the process. How can you debug it?</P>
<P>Here are the two easiest solutions:</P>
<P>#1: Windows includes registry settings under the ‘Image File Execution Options’ key that can help you debug this. I blogged about this before back in February of 2005 (<A href="https://blogs.msdn.com/greggm/archive/2005/02/21/377663.aspx" mce_href="https://blogs.msdn.com/greggm/archive/2005/02/21/377663.aspx">https://blogs.msdn.com/greggm/archive/2005/02/21/377663.aspx</A>). Most of the information is that blog is still correct. A few updates worth mentioning though:</P>
<UL>
<LI>Visual Studio 2008 can support session 0 processes on Vista or Server 2008.</LI>
<LI>Visual Studio 2008 can support 64-bit operating systems. The only remaining 64-bit restriction is that 64-bit managed processes cannot be debugged this way since the .NET Framework does not support managed+native debugging of 64-bit processes.</LI>
<LI>Visual Studio 2005 does not support this feature on Windows Vista or Server 2008. You will need to upgrade to 2008 for these operating systems.</LI></UL>
<P><BR>#2: You can add code to your app to cause it to pause waiting for a debugger to attach. I am attaching an example header file for making this work. We ship several executables that embed similar code for this reason. Just call ‘RuntimeDiagnostics::CheckPauseOnStartupOption()’ as the first line of code in your main routine. You can do something verify similar for managed code as well. Just call ‘System.Diagnostics.Debugger.IsAttached’ instead of IsDebuggerPresent.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes">int</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"> _tmain(<SPAN style="COLOR: blue">int</SPAN> argc, _TCHAR* argv[])<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>RuntimeDiagnostics::CheckPauseOnStartupOption();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">return</SPAN> 0;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes">}<o:p></o:p></SPAN></P>
<P>Then set this registy key if you need your app to pause:</P><FONT face="Courier New">
<P>Windows Registry Editor Version 5.00</P>
<P>[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sample.exe]<BR>"PauseOnStartup"=dword:00000001</P></FONT>
<P mce_keep="true">&nbsp;</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/08/94/80/27/RuntimeDiagnostics.h" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-94-80-27/RuntimeDiagnostics.h">RuntimeDiagnostics.h</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Writing a script debugger without using the MDM</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/writing-a-script-debugger-without-using-the-mdm</link>
      <pubDate>Mon, 09 Jun 2008 14:21:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2008/06/09/writing-a-script-debugger-without-using-the-mdm/</guid>
      <description><![CDATA[Today’s blog is about writing your own script debugger.
Visual Studio has provided ‘Script’...]]></description>
      <content:encoded><![CDATA[<P>Today’s blog is about writing your own script debugger.</P>
<P>Visual Studio has provided ‘Script’ debugging for a long time. In this context, ‘Script’ refers to script run by jscript.dll or vbscript.dll such as the script code in Internet Explorer, classic ASP scripting, or the cscript/wscript programs. Long long ago, someone provided a sample for creating your own script debugging utilizing the active script debugging interfaces (ex: <A class="" href="https://msdn.microsoft.com/en-us/library/7173hc80(VS.85).aspx" mce_href="https://msdn.microsoft.com/en-us/library/7173hc80(VS.85).aspx">IRemoteDebugApplication</A>).</P>
<P>However, this sample relied on a Microsoft executable called mdm.exe (IMachineDebugManager/CLSID_MachineDebugManager). After Visual Studio 2003, Visual Studio stopped shipping mdm.exe. So today, I wanted to provide a brief summary of how one could port an mdm.exe-based script debugger to the newer interfaces. Mdm.exe provided essentially two related features&nbsp;-- it allowed a debugger determine what script applications where currently running, and there was an eventing interface that let a debugger be informed when a new script application started. These features worked because the debugger component inside of the target process (pdm.dll) would connect to mdm.exe whenever a new script application was created.</P>
<P>Today, these features have been moved to&nbsp;pdm.dll. So now, pdm.dll is loaded in both the debugger and in the target process. In the target process pdm.dll still continues to do the same work as it has always done. However, now one can also load pdm.dll into the debugger process to obtain the old MDM features.</P>
<P>PDM now has a new CLSID for the work that it does in the debugger process – CLSID_MsProgramProvider. It exposes an AD7 interface for obtaining this information: <A class="" href="https://msdn.microsoft.com/en-us/library/bb161298.aspx" mce_href="https://msdn.microsoft.com/en-us/library/bb161298.aspx">IDebugProgramProvider2</A>.</P>
<P>There is sample code attached to this blog which demonstrates how to launch or attach to a program using these new interfaces.</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/08/58/68/72/ScriptWithoutMdm.cpp" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-58-68-72/ScriptWithoutMdm.cpp">ScriptWithoutMdm.cpp</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Reporting a Visual Studio crash to Microsoft</title>
      <link>https://docs.microsoft.com/archive/blogs/greggm/reporting-a-visual-studio-crash-to-microsoft</link>
      <pubDate>Thu, 22 May 2008 14:47:00 GMT</pubDate>
      <dc:creator><![CDATA[Gregg Miskelly]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/greggm/2008/05/22/reporting-a-visual-studio-crash-to-microsoft/</guid>
      <description><![CDATA[Background
Sometimes Visual Studio crashes. It would be nice if this wasn’t the case, but...]]></description>
      <content:encoded><![CDATA[<H2>Background</H2>
<P>Sometimes Visual Studio crashes. It would be nice if this wasn’t the case, but unfortunately it happens. However, like many Microsoft applications, Visual Studio has Error Reporting so that when a problem happens, you can tell us about it in one click. However, sometimes you would like to actually tell a live human about your crash. There are a number of advantages to doing so:</P>
<OL>
<LI>A human might be able to tell you about a work around that Windows Error reporting doesn’t know about.</LI>
<LI>A human can tell you if this crash was something that we could diagnose.</LI>
<LI>It helps to make sure your issue is really fixed. When a developer at Microsoft looks at a Windows Error report, all we see is where the crash happened and some local variables. Sometimes we can figure out what was happening and create a repro to confirm our fix. This is the best case, but it often doesn’t happen this way. More often we need to either guess what a fix is but not test the fix, or we are unable to even guess what a correct fix might be.</LI></OL>
<P>For these reasons you might want to also report the issue through the Visual Studio product feedback center.<BR></P>
<H2>What to do</H2>
<P>Step #1: Go to <A href="https://connect.microsoft.com/site/sitehome.aspx?SiteID=210" mce_href="https://connect.microsoft.com/site/sitehome.aspx?SiteID=210">https://connect.microsoft.com/site/sitehome.aspx?SiteID=210</A> and enter a bug.</P>
<P>Step #2: In the bug, include the ‘bucketing information’. You can find this information by:</P>
<UL>
<LI>Open the event viewer (Right click on Computer and go to ‘Manage’; click on the ‘Event Viewer’ tree item).</LI>
<LI>Open the ‘Application’ section</LI>
<LI>Look for the entry that happened about the correct time and had the source set to ‘Application Error’</LI>
<LI>Copy the content and paste it into the bug, it should look something like:</LI></UL>
<P>Faulting application devenv.exe, version 9.0.30428.1, time stamp 0x4815597f, faulting module scriptle2.dll, version 9.0.21022.8, time stamp 0x47317e18, exception code 0xc0000005, fault offset 0x0000328c, process id 0xfbc, application start time 0x01c8bc39887cac69.<BR>&nbsp;</P>]]></content:encoded>
    </item>
  </channel>
</rss>