<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET Security Blog : Debugging</title><link>http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx</link><description>Tags: Debugging</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>CLR Security Team CodePlex Site</title><link>http://blogs.msdn.com/shawnfa/archive/2008/07/10/clr-security-team-codeplex-site.aspx</link><pubDate>Thu, 10 Jul 2008 22:20:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8718287</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/8718287.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=8718287</wfw:commentRss><description>&lt;p&gt;The CLR Security Team just launched our CodePlex site: &lt;a href="http://www.codeplex.com/clrsecurity"&gt;http://www.codeplex.com/clrsecurity&lt;/a&gt;.&amp;#160; Currently, it contains two assemblies that provide additional functionality to the security APIs shipped in v3.5 of the .NET Framework.&lt;/p&gt;  &lt;p&gt;We'd love your feedback on the currently offered libraries, and also welcome ideas for other libraries you'd like to see on our CodePlex site.&amp;#160; &lt;/p&gt;  &lt;p&gt;From the description page on the site, the two current libraries are:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.codeplex.com/clrsecurity/Wiki/View.aspx?title=Security.Cryptography.dll&amp;amp;referringTitle=Home"&gt;&lt;strong&gt;Security.Cryptography.dll&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Security.Cryptography.dll provides a new set of algorithm implementations to augment the built in .NET framework supported algorithms. It also provides some APIs to extend the existing framework cryptography APIs. Within this project you will find:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A CNG implementation of the AES, RSA, and TripleDES encryption algorithms &lt;/li&gt;    &lt;li&gt;A CNG implementation of a random number generator &lt;/li&gt;    &lt;li&gt;A class that allows dynamically creating algorithms both from this library as well as all of the algorithms that ship with .NET 3.5 &lt;/li&gt;    &lt;li&gt;An enumerator over all of the installed CNG providers on the current machine &lt;/li&gt;    &lt;li&gt;Extension methods that allow access to all of the keys installed in a CNG provider, as well as all of the algorithms the provider supports &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.codeplex.com/clrsecurity/Wiki/View.aspx?title=Security.Cryptography.Debug.dll&amp;amp;referringTitle=Home"&gt;&lt;strong&gt;Security.Cryptography.Debug.dll&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Have you ever run into an indecipherable cryptographic exception complaining about &amp;quot;Padding is invalid and cannot be removed&amp;quot; when using the .NET Framework's symmetric algorithms? Since nearly all bugs relating to symmetric algorithms tend to result in this same exception, it can be incredibly difficult to track down exactly what went wrong to cause the exception. Security.Cryptography.Debug.dll is a tool that can be used in these circumstances in order to help you figure out the root cause of your cryptographic exception.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8718287" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>FxCop Transparency Rules</title><link>http://blogs.msdn.com/shawnfa/archive/2006/04/04/567753.aspx</link><pubDate>Tue, 04 Apr 2006 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:567753</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/567753.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=567753</wfw:commentRss><description>&lt;P&gt;The &lt;A href="http://www.gotdotnet.com/team/fxcop/"&gt;FxCop team&lt;/A&gt; has just announced the availability of &lt;A HREF="/fxcop/archive/2006/04/04/567743.aspx"&gt;RC 1 of FxCop 1.35&lt;/A&gt;.&amp;nbsp; Notable in this release is the introduction of the first three rules around &lt;A HREF="/shawnfa/archive/2005/09/09/462975.aspx#567744"&gt;security transparency&lt;/A&gt;.&amp;nbsp; Namely, you'll see:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;SecurityTransparentAssembliesShouldNotContainSecurityCriticalCode&lt;/EM&gt; - fires when an assembly which is marked transparent contains any code which is marked critical.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;SecurityTransparentCodeShouldNotAssert&lt;/EM&gt; - fires when a block of transparent code attempts to execute a CAS Assert.&lt;/LI&gt;
&lt;LI&gt;&lt;EM&gt;SecurityTransparentCodeShouldNotReferenceNonpublicSecurityCriticalCode&lt;/EM&gt; - fires when transparent code attempts to use critical code which is not public or TreatAsSafe.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=567753" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Other/default.aspx">Other</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Debugging a Partial Trust ClickOnce Application</title><link>http://blogs.msdn.com/shawnfa/archive/2006/03/28/563188.aspx</link><pubDate>Tue, 28 Mar 2006 20:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:563188</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/563188.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=563188</wfw:commentRss><description>&lt;P&gt;Although the theory is that by the time we deploy a finished application it's already fully debugged we all know that in&amp;nbsp;practice things rarely go that smoothly.&amp;nbsp; So what happens if you deploy a partial trust ClickOnce application that starts to crash when it's run?&amp;nbsp; Well, if you're lucky enough to have the problematic application&amp;nbsp;stay alive&amp;nbsp;for as long as it takes&amp;nbsp;you to attach a debugger you're golden.&lt;/P&gt;
&lt;P&gt;However if the crash occurs somewhere along the startup path, or if the debugger shows that something went wrong and got you into a bad state before you could attach it you might want to have the debugger run before the process even starts.&lt;/P&gt;
&lt;P&gt;That's where things start to get tricky -- since ClickOnce is responsible for starting up your application, you can't just tell it to run the debugger for you.&amp;nbsp; Instead, you can use the gflags tool from the &lt;A href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Debugging Tools for Windows&lt;/A&gt; to intercept the start of your process.&amp;nbsp; &lt;A HREF="/shawnfa/archive/2005/11/30/498610.aspx"&gt;For a partial trust application, AppLaunch will be the real entry point&lt;/A&gt;, so you'll want to launch your debugger when AppLaunch starts.&lt;/P&gt;
&lt;P&gt;In the gflags Image File section, set AppLaunch.exe as the image, check the debugger box, and put the full path to your debugger in the debugger field.&amp;nbsp; I tend to use either &lt;A HREF="/jmstall/archive/2005/11/08/mdbg_linkfest.aspx"&gt;Mdbg&lt;/A&gt; or WinDbg for this, depending on what kind of error I'm debugging.&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="Setting up a debugger for AppLaunch" src="/photos/shawnfa/images/563181/original.aspx" border=0&gt;&lt;/P&gt;
&lt;P&gt;Once you've got that setup you can launch your ClickOnce application normally and the debugger will start ready to run the application.&amp;nbsp; If your app no longer starts up, make sure that the full path to the debugger is correct, since if Windows fails to find it, it will fail the CreateProcess for AppLaunch as well.&lt;/P&gt;
&lt;P&gt;Finally, when you've solved the problem, you'll probably want to go back to gflags and uncheck the debugger box so that your partial trust applications no longer run under the debugger.&lt;/P&gt;
&lt;P&gt;A couple of quick notes on this -- since all partial trust code runs through the same AppLaunch entry point, setting this up will cause all partial trust ClickOnce apps to run under the debugger, not just the one you're debugging.&amp;nbsp; The same technique can be used for a FullTrust ClickOnce application as well; in that case you'd use the name of your application's .exe file instead of AppLaunch.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=563188" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/ClickOnce/default.aspx">ClickOnce</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Debugging ADMHost</title><link>http://blogs.msdn.com/shawnfa/archive/2006/01/05/509440.aspx</link><pubDate>Thu, 05 Jan 2006 18:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:509440</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/509440.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=509440</wfw:commentRss><description>&lt;P&gt;A few people have noticed that the &lt;a href="http://blogs.msdn.com/shawnfa/archive/2005/10/06/478009.aspx"&gt;ADMHost sample&lt;/A&gt; is not set up to do mixed mode debugging by default.&amp;nbsp; If you're working with this sample and you'd like to debug through both halves of the host, you'll need to enable this mode.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Right click on the ADMHost project and open the properties window&lt;/LI&gt;
&lt;LI&gt;Set Configuration Properties \ Debugging \ Debugger Type to be Mixed rather than Auto&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;That should enable a better debugging experience on the sample code.&lt;/P&gt;
&lt;P&gt;Incidentally, Gregg explains why Auto won't work in this case &lt;a href="http://blogs.msdn.com/greggm/archive/2004/07/08/177774.aspx"&gt;here&lt;/A&gt;.&amp;nbsp; Since the ADMHost.exe is native, the Visual Studio debugger doesn't know that it will have to do managed debugging when it gets to the ManagedHost.dll library and so it chooses native debugging instead -- causing any breakpoints set in the managed side to be ignored.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=509440" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Finding the Source Code for an Assembly</title><link>http://blogs.msdn.com/shawnfa/archive/2005/11/22/495948.aspx</link><pubDate>Wed, 23 Nov 2005 00:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:495948</guid><dc:creator>shawnfa</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/495948.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=495948</wfw:commentRss><description>&lt;P&gt;Sometimes, especially when working on large projects (such as, I don't know, say ... the CLR), you find yourself debugging a problem where you don't know where a component is built from.&amp;nbsp; Depending on the problem, it might be useful to get to the sources of the assembly to help diagnose what the issue is (or to look up in the source control system who the owner of the code is so you can contact them).&amp;nbsp; I ran into this problem recently, and using the &lt;a href="http://blogs.msdn.com/jmstall/archive/2005/08/31/Mdbg_Python_ext.aspx"&gt;IronPython MDbg extension&lt;/A&gt; was able to whip up a quick method that will dump the path to the source files that make up an assembly that you have symbols for:&lt;/P&gt;
&lt;P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;def&lt;/FONT&gt;&lt;/SPAN&gt; &lt;SPAN&gt;&lt;FONT color=#000000&gt;ShowAssemblySources&lt;/FONT&gt;&lt;/SPAN&gt;(assembly):&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;for&lt;/FONT&gt;&lt;/SPAN&gt; module &lt;SPAN&gt;&lt;FONT color=#0000ff&gt;in&lt;/FONT&gt;&lt;/SPAN&gt; Shell.Debugger.Processes.Active.Modules:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt;&lt;/SPAN&gt; module.CorModule.Assembly.Name.Contains(assembly):&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;print&lt;/FONT&gt;&lt;/SPAN&gt; module.CorModule.Name&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt;&lt;/SPAN&gt; module.SymReader != None:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;for&lt;/FONT&gt;&lt;/SPAN&gt; document &lt;SPAN&gt;&lt;FONT color=#0000ff&gt;in&lt;/FONT&gt;&lt;/SPAN&gt; module.SymReader.GetDocuments():&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;print&lt;/FONT&gt;&lt;/SPAN&gt; &lt;SPAN&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT color=#000080&gt;&amp;nbsp;&amp;nbsp;%s&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;/SPAN&gt; % document.URL&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;else&lt;/FONT&gt;&lt;/SPAN&gt;:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN&gt;&lt;FONT color=#0000ff&gt;print&lt;/FONT&gt;&lt;/SPAN&gt; &lt;SPAN&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT color=#000080&gt;&amp;nbsp;&amp;nbsp;module does not have symbols, skipping&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT color=#000000&gt;"&lt;/FONT&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Using this method is pretty straight forward:&lt;/P&gt;
&lt;P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;[p#:0, t#:0] mdbg&amp;gt; ShowAssemblySources("caspol")&lt;BR&gt;c:\WINDOWS\Microsoft.NET\Framework64\v2.0.AMD64chk\caspol.exe&lt;BR&gt;&amp;nbsp;&amp;nbsp;d:\vbl\lab21s\ndp\clr\src\ToolBox\caspol\obj1c\amd64\CommonResStrings.cspp&lt;BR&gt;&amp;nbsp;&amp;nbsp;d:\vbl\lab21s\ndp\clr\src\ToolBox\caspol\obj1c\amd64\CommonResStrings.cs&lt;BR&gt;&amp;nbsp;&amp;nbsp;d:\vbl\lab21s\ndp\clr\src\ToolBox\caspol\caspol.cs&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;It's definately not an every-day debugging tool, which again makes it nice that IronPython makes extending the MDbg command set so easy since&amp;nbsp;I wouldn't have wanted to spend more than a few minutes working this code out.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=495948" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Debugging Lightweight CodeGen in VS</title><link>http://blogs.msdn.com/shawnfa/archive/2005/10/25/484875.aspx</link><pubDate>Wed, 26 Oct 2005 01:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:484875</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/484875.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=484875</wfw:commentRss><description>Haibo just &lt;a href="http://blogs.msdn.com/haibo_luo/archive/2005/10/25/484861.aspx"&gt;posted&lt;/A&gt; about his &lt;A href="http://gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=22BA8210-B3A0-4580-B362-ABC7C1A59C65"&gt;debugger visualizer for dynamic methods&lt;/A&gt;.&amp;nbsp; This is a pretty sweet piece of code for anyone who uses lightweight code generation and needs to debug the code they've emitted.&amp;nbsp; Basically it adds a visualizer to DynamicMethod objects that enables you to dump out the IL of that method.&amp;nbsp; (He also &lt;a href="http://blogs.msdn.com/haibo_luo/archive/2005/10/02/476242.aspx"&gt;explains the code he uses to convert from IL bytes to ILDasm style representation&lt;/A&gt;, which can be used with the new &lt;A href="http://msdn2.microsoft.com/en-us/library/system.reflection.methodbody"&gt;MethodBody&lt;/A&gt;&amp;nbsp;class that reflection exposes) 
&lt;P&gt;&lt;IMG alt="Lightweight CodeGen Visualizer" src="http://static.flickr.com/33/51647547_d174fdba98_o.gif"&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=484875" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>IronPython + MDbg = good times</title><link>http://blogs.msdn.com/shawnfa/archive/2005/09/02/460216.aspx</link><pubDate>Sat, 03 Sep 2005 00:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:460216</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/460216.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=460216</wfw:commentRss><description>&lt;P&gt;&lt;a href="http://blogs.msdn.com/jmstall"&gt;Mike Stall&lt;/A&gt; recently &lt;a href="http://blogs.msdn.com/jmstall/archive/2005/08/31/Mdbg_Python_ext.aspx"&gt;completed a project&lt;/A&gt; to embed &lt;A href="http://www.gotdotnet.com/workspaces/workspace.aspx?id=ad7acff7-ab1e-4bcb-99c0-57ac5a3a9742"&gt;IronPython&lt;/A&gt; into the &lt;A href="http://www.microsoft.com/downloads/details.aspx?familyid=38449a42-6b7a-4e28-80ce-c55645ab1310&amp;amp;displaylang=en"&gt;MDbg debugger&lt;/A&gt; as an MDbg extension.&amp;nbsp; IronPython's hosting interface is pretty slick, in fact it took Mike only &lt;a href="http://blogs.msdn.com/jmstall/archive/2005/09/01/Howto_embed_ironpython.aspx"&gt;10 steps&lt;/A&gt; to get IronPython running inside MDbg and expose the debugger functionality to Python scripts via a variable named Shell.&lt;/P&gt;
&lt;P&gt;After playing with Mike's extension for a few hours, I'm absolutely amazed by not only how easy it is to use, but how seamless the integration is.&amp;nbsp; For instance, I haven't used Python since college, and have never written an MDbg extension before.&amp;nbsp; However, less than an hour&amp;nbsp;after I sat down to play with this I was able to &lt;a href="http://blogs.msdn.com/shawnfa/articles/StateWindow_py.aspx"&gt;write a script&lt;/A&gt; (which is less than 125 lines of code) that pops up a tree view displaying the processes being debugged, its AppDomains (and the assemblies loaded into them), and the threads with call stacks and locals:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://shawnmsdn.members.winisp.net/images/StateWindow.png"&gt;&lt;IMG style="WIDTH: 85%; HEIGHT: auto" alt="PythonExt State Window" src="http://shawnmsdn.members.winisp.net/images/StateWindow.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;It took only about 10-15 minutes to &lt;a href="http://blogs.msdn.com/shawnfa/articles/OptionsGui_py.aspx"&gt;write a quick script&lt;/A&gt; that enables you to set the debugger options via a GUI, which should cut down on the amount of time I spend trying to remember which letter combinations I want to type after "catch" :-)&lt;/P&gt;
&lt;P&gt;&lt;IMG alt="PythonExt Options GUI" src="http://shawnmsdn.members.winisp.net/images/OptionsGUI.png"&gt;&lt;/P&gt;
&lt;P&gt;Since IronPython allows you to use most managed code, including the majority of the frameworks themselves from within your scripts, I used the System.Diagnostics.Process class to kick off a native debugger in order to snap a minidump of the process being debugged:&lt;/P&gt;
&lt;P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;&lt;SPAN style="COLOR: blue"&gt;def&lt;/SPAN&gt;&amp;nbsp;MiniDump(path&amp;nbsp;=&amp;nbsp;"%TEMP%\\mdbg.dmp.cab",&amp;nbsp;options&amp;nbsp;=&amp;nbsp;"/ma&amp;nbsp;/ba",&amp;nbsp;symbols&amp;nbsp;=&amp;nbsp;"srv**http://msdl.microsoft.com/download/symbols",&amp;nbsp;debugger&amp;nbsp;=&amp;nbsp;"%WINDIR%\\System32\\ntsd.exe"):&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pid&amp;nbsp;=&amp;nbsp;Shell.Debugger.Processes.Active.CorProcess.Id&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;path&amp;nbsp;=&amp;nbsp;Environment.ExpandEnvironmentVariables(path)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;executeString&amp;nbsp;=&amp;nbsp;".dump&amp;nbsp;%s&amp;nbsp;%s;&amp;nbsp;.detach;&amp;nbsp;q"&amp;nbsp;%&amp;nbsp;(options,&amp;nbsp;path)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;commandLine&amp;nbsp;=&amp;nbsp;'-c&amp;nbsp;"%s"&amp;nbsp;-pv&amp;nbsp;-y&amp;nbsp;%s&amp;nbsp;-p&amp;nbsp;%d'&amp;nbsp;%&amp;nbsp;(executeString,&amp;nbsp;symbols,&amp;nbsp;pid)&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;print&lt;/SPAN&gt;&amp;nbsp;"Writing&amp;nbsp;minidump&amp;nbsp;%s"&amp;nbsp;%&amp;nbsp;path&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;debugger&amp;nbsp;=&amp;nbsp;Process.Start(Environment.ExpandEnvironmentVariables(debugger),&amp;nbsp;commandLine)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;debugger.WaitForExit()&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Of course not wanting to leave well enough alone, I made a couple of modifications to the extension (&lt;a href="http://blogs.msdn.com/jmstall/articles/Sample_Mdbg_IronPython.aspx"&gt;original source code here&lt;/A&gt;).&amp;nbsp;First, I added some new paths to the Python path:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;%AllUsersProfile%\ApplicationData\MDbg\Scripts 
&lt;LI&gt;%AppData%\MDbg\Scripts 
&lt;LI&gt;The path the MDbg.exe is running in&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;&lt;SPAN style="COLOR: green"&gt;// Add the all user app data\mdbg\scripts, appdata\mdbg\scripts, mdbg.exe path, and current directory&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: green"&gt;// to the python engine search path.&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: green"&gt;// @todo - could add the symbol path Debugger.Options.SymbolPath here too.&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;nbsp;scriptPathSuffix&amp;nbsp;=&amp;nbsp;Path.DirectorySeparatorChar&amp;nbsp;+&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Assembly.GetEntryAssembly().GetName().Name&amp;nbsp;+&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Path.DirectorySeparatorChar&amp;nbsp;+&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;"Scripts";&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;[]&amp;nbsp;pythonPath&amp;nbsp;=&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;[]&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)&amp;nbsp;+&amp;nbsp;scriptPathSuffix,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)&amp;nbsp;+&amp;nbsp;scriptPathSuffix,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&amp;nbsp;FileInfo(Assembly.GetEntryAssembly().Location).DirectoryName,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Environment.CurrentDirectory&lt;BR&gt;};&lt;BR&gt;m_python.AddToPath(Environment.CurrentDirectory);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;nbsp;path&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt;&amp;nbsp;pythonPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_python.AddToPath(path);&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;After that, I added the ability to have an autorun script, Startup.py.&amp;nbsp; As the last step of initialization, I simply look for a Startup.py in each of the directories on the path, and if I find it kick it off:&lt;/P&gt;
&lt;P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: green"&gt;// Finally, run each Startup.py&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WriteOutput("Running startup scripts");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;foreach&lt;/SPAN&gt;(&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;nbsp;path&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;in&lt;/SPAN&gt;&amp;nbsp;pythonPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&amp;nbsp;startup&amp;nbsp;=&amp;nbsp;path&amp;nbsp;+&amp;nbsp;Path.DirectorySeparatorChar&amp;nbsp;+&amp;nbsp;"Startup.py";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;(File.Exists(startup))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_python.ExecuteFile(startup);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&amp;nbsp;&lt;SPAN style="COLOR: green"&gt;// end of PythonExt::LoadExtension&lt;/SPAN&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Finally, I added a PythonExtVersion property to the MDbgUtil variable, which allows a script to find out what version of the MDbg python extension it's running under.&lt;/P&gt;
&lt;P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;&amp;nbsp;Util&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt;&amp;nbsp;Version&amp;nbsp;version&amp;nbsp;=&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&amp;nbsp;Version(1,&amp;nbsp;1,&amp;nbsp;0,&amp;nbsp;0);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&amp;nbsp;Version&amp;nbsp;PythonExtVersion&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;get&amp;nbsp;{&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt;&amp;nbsp;version;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;This is&amp;nbsp;pretty powerful stuff -- I can easily see not wanting to run MDbg without the ability to &lt;EM&gt;lo PythonExt &lt;/EM&gt;for anything but trivial debugging.&amp;nbsp; Considering how easy it was to get this up and running, if you've got a decent object model to expose to users, embedding IronPython into your application really opens up new doors for your users to use your application in ways you might not have thought of (or didn't have time to implement yourself) --&amp;nbsp;yet makes their experience much better.&lt;/P&gt;
&lt;DIV&gt;&lt;EM&gt;Updated 4:06pm: Added links to &lt;a href="http://blogs.msdn.com/shawnfa/articles/StateWindow_py.aspx"&gt;StateWindow.py&lt;/A&gt; and &lt;a href="http://blogs.msdn.com/shawnfa/articles/OptionsGui_py.aspx"&gt;OptionsGui.py&lt;/A&gt;&lt;/EM&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=460216" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Viewing IL at Debug Time</title><link>http://blogs.msdn.com/shawnfa/archive/2005/06/08/426811.aspx</link><pubDate>Wed, 08 Jun 2005 18:55:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:426811</guid><dc:creator>shawnfa</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/426811.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=426811</wfw:commentRss><description>&lt;p&gt;Last week, &lt;a href="http://blogs.msdn.com/shawnfa/archive/2005/05/27/422715.aspx"&gt;I mentioned&lt;/a&gt; Yiru&amp;rsquo;s post on using SOS to see the IL of a dynamically generated method.&amp;nbsp; Yiru&amp;rsquo;s post is about lightweight code gen, but the technique she shows is useful for more general purpose managed debugging .&amp;nbsp; Let&amp;rsquo;s work through debugging a program that&amp;rsquo;s supposed to display the number of days between two dates.&amp;nbsp; The problem is that the author of this program didn&amp;rsquo;t seem to test it before releasing it, and currently it only says that it cannot calculate the date difference.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll start by firing up &lt;a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx"&gt;WinDbg&lt;/a&gt;&amp;nbsp;and requesting that I break on any first chance managed exceptions. (Throughout this post, I&amp;rsquo;ll be italicising command I type and highlighting in bold and maroon debugger output that&amp;rsquo;s important for use later on):&lt;/p&gt;
&lt;blockquote dir="ltr"&gt;
&lt;p&gt;&lt;em&gt;0:000&amp;gt; sxe clr&lt;/em&gt;&lt;br /&gt;&lt;em&gt;0:000&amp;gt; g&lt;br /&gt;&lt;/em&gt;&amp;hellip;&lt;br /&gt;ModLoad: 5b0c0000 5b1c0000&amp;nbsp;&amp;nbsp; C:\WINNT\Microsoft.NET\Framework\v2.0.50607\mscorjit.dll&lt;br /&gt;(960.860): CLR exception - code e0434f4d (first chance)&lt;br /&gt;First chance exceptions are reported before any exception handling.&lt;br /&gt;This exception may be expected and handled.&lt;br /&gt;eax=0012e6e0 ebx=00000001 ecx=00000000 edx=00000006 esi=0012e7dc edi=0012e7d8&lt;br /&gt;eip=77e55dea esp=0012e6dc ebp=0012e730 iopl=0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nv up ei pl nz na pe nc&lt;br /&gt;cs=001b&amp;nbsp; ss=0023&amp;nbsp; ds=0023&amp;nbsp; es=0023&amp;nbsp; fs=003b&amp;nbsp; gs=0000&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; efl=00000202&lt;br /&gt;KERNEL32!RaiseException+0x53:&lt;br /&gt;77e55dea 5e&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; esi&lt;/p&gt;&lt;/blockquote&gt;
&lt;p dir="ltr"&gt;Once I&amp;rsquo;ve gotten the exception, I&amp;rsquo;ll load up SOS and see if displaying the exception gives any clue to what the problem might be:&lt;/p&gt;
&lt;blockquote dir="ltr"&gt;
&lt;p dir="ltr"&gt;&lt;em&gt;0:000&amp;gt; !load sos&lt;br /&gt;0:000&amp;gt; !pe&lt;br /&gt;&lt;/em&gt;Exception object: 014628a4&lt;br /&gt;Exception type: System.InvalidOperationException&lt;br /&gt;Message: Operation is not valid due to the current state of the object.&lt;br /&gt;InnerException: &amp;lt;none&amp;gt;&lt;br /&gt;StackTrace (generated):&lt;br /&gt;&amp;lt;none&amp;gt;&lt;br /&gt;StackTraceString: &amp;lt;none&amp;gt;&lt;br /&gt;HResult: 80131509&lt;/p&gt;&lt;/blockquote&gt;
&lt;p dir="ltr"&gt;Huh, well that&amp;rsquo;s not very useful at all.&amp;nbsp; It appears that the author of this program didn&amp;rsquo;t supply an exception message, so InvalidOperationException just used its default exception.&amp;nbsp; In order to figure out why this exception was thrown, I&amp;rsquo;m going to look at the IL of the method that threw.&amp;nbsp; Why look at the IL, instead of just using .frame or the call stack window to pull up the source for the method?&amp;nbsp; Well, in this case I don&amp;rsquo;t have access to source code or symbols for the program.&lt;/p&gt;
&lt;p dir="ltr"&gt;In order to do that, I&amp;rsquo;ll have to first take a look at the call stack:&lt;/p&gt;
&lt;blockquote dir="ltr"&gt;
&lt;p dir="ltr"&gt;&lt;em&gt;0:000&amp;gt; !CLRStack -p&lt;/em&gt;&lt;br /&gt;OS Thread Id: 0x860 (0)&lt;br /&gt;ESP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; EIP&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;0012e914 77e55dea [HelperMethodFrame: 0012e914] &lt;br /&gt;0012e98c &lt;strong&gt;&lt;font color="#800000"&gt;00f10164&lt;/font&gt;&lt;/strong&gt; Test.DaysBetween(System.DateTime, System.DateTime)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; PARAMETERS:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; start = &amp;lt;no data&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end = &amp;lt;no data&amp;gt;&lt;/p&gt;
&lt;p dir="ltr"&gt;0012e9c0 00f100bd Test.Main()&lt;br /&gt;0012f450 5d57671d [GCFrame: 0012f450] &lt;/p&gt;&lt;/blockquote&gt;
&lt;p dir="ltr"&gt;I can see that the DaysBetween method is responsible for throwing the exception, since it&amp;rsquo;s at the top of the call stack.&amp;nbsp; I also notice that it&amp;rsquo;s a static method (since there is no this parameter given), and that the IP of the throw was 0x00f10164.&amp;nbsp; The SOS DumpIL command requires a MethodDesc as a parameter, so I&amp;rsquo;ll first use the ip2md command to get the MethodDesc that covers that IP, and then dump it&amp;rsquo;s IL:&lt;/p&gt;
&lt;blockquote dir="ltr"&gt;
&lt;p&gt;&lt;em&gt;0:000&amp;gt; !ip2md 00f10164&lt;/em&gt; &lt;br /&gt;MethodDesc: &lt;strong&gt;&lt;font color="#800000"&gt;00ee0d38&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;Method Name: Test.DaysBetween(System.DateTime, System.DateTime)&lt;br /&gt;Class: 00ef12c0&lt;br /&gt;MethodTable: 00ee0d9c&lt;br /&gt;mdToken: 06000002&lt;br /&gt;Module: 001e0d40&lt;br /&gt;IsJitted: yes&lt;br /&gt;m_CodeOrIL: 00f10100&lt;br /&gt;&lt;em&gt;0:000&amp;gt; !dumpil 00ee0d38&lt;/em&gt;&lt;br /&gt;ilAddr = 004020a4&lt;br /&gt;IL_0000: nop &lt;br /&gt;IL_0001: ldarg.1 &lt;br /&gt;IL_0002: ldarg.0 &lt;br /&gt;IL_0003: call System.DateTime::op_LessThan &lt;br /&gt;IL_0008: ldc.i4.0 &lt;br /&gt;IL_0009: ceq &lt;br /&gt;IL_000b: stloc.1 &lt;br /&gt;IL_000c: ldloc.1 &lt;br /&gt;IL_000d: brtrue.s IL_0015&lt;br /&gt;IL_000f: newobj System.InvalidOperationException::.ctor &lt;br /&gt;IL_0014: throw &lt;br /&gt;IL_0015: ldarg.1 &lt;br /&gt;IL_0016: ldarg.0 &lt;br /&gt;IL_0017: call System.DateTime::op_Subtraction &lt;br /&gt;IL_001c: stloc.2 &lt;br /&gt;IL_001d: ldloca.s VAR OR ARG 2&lt;br /&gt;IL_001f: call System.TimeSpan::get_Days &lt;br /&gt;IL_0024: stloc.0 &lt;br /&gt;IL_0025: br.s IL_0027&lt;br /&gt;IL_0027: ldloc.0 &lt;br /&gt;IL_0028: ret &lt;/p&gt;&lt;/blockquote&gt;
&lt;p dir="ltr"&gt;From looking at the IL of the throwing method, it appears that between IL_0000 and IL_000d we check to see if the&amp;nbsp;second parameter is less than the first parameter (remember ldarg.0 gets the first parameter in this method since the method is static).&amp;nbsp; If it is, then we jump to IL_0015,&amp;nbsp;however if is&amp;nbsp;not then between IL_000f and IL_0014 we use the default InvalidOperationException constructor and throw.&lt;/p&gt;
&lt;p dir="ltr"&gt;That analysis leads me to believe that the second parameter was in fact not less than the first parameter.&amp;nbsp; Lets take a look at the calling method to try to figure out what the parameters were.&amp;nbsp; From the call stack above, we know that the calling method is Main, and the IP where the call was made is 0x00f100bd.&amp;nbsp; Following the same !ip2md, !dumpil sequence we see:&lt;/p&gt;
&lt;blockquote dir="ltr"&gt;
&lt;p dir="ltr"&gt;&lt;em&gt;0:000&amp;gt; !ip2md 00f100bd&lt;/em&gt; &lt;br /&gt;MethodDesc: &lt;strong&gt;00ee0d10&lt;/strong&gt;&lt;br /&gt;Method Name: Test.Main()&lt;br /&gt;Class: 00ef12c0&lt;br /&gt;MethodTable: 00ee0d9c&lt;br /&gt;mdToken: 06000001&lt;br /&gt;Module: 001e0d40&lt;br /&gt;IsJitted: yes&lt;br /&gt;m_CodeOrIL: 00f10070&lt;br /&gt;&lt;em&gt;0:000&amp;gt; !DumpIL 00ee0d10&lt;/em&gt;&lt;br /&gt;ilAddr = 00402050&lt;br /&gt;IL_0000: nop &lt;br /&gt;.try&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; IL_0001: nop &lt;br /&gt;&amp;nbsp; IL_0002: call System.DateTime::get_Now &lt;br /&gt;&amp;nbsp; IL_0007: ldc.i4 1980&lt;br /&gt;&amp;nbsp; IL_000c: ldc.i4.s 9&lt;br /&gt;&amp;nbsp; IL_000e: ldc.i4.s 15&lt;br /&gt;&amp;nbsp; IL_0010: newobj System.DateTime::.ctor &lt;br /&gt;&amp;nbsp; IL_0015: call Test::DaysBetween&lt;br /&gt;&amp;nbsp; IL_001a: call System.Console::WriteLine &lt;br /&gt;&amp;nbsp; IL_001f: nop &lt;br /&gt;&amp;nbsp; IL_0020: nop &lt;br /&gt;&amp;nbsp; IL_0021: leave.s IL_0033&lt;br /&gt;} // end .try&lt;br /&gt;.catch&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; IL_0023: pop &lt;br /&gt;&amp;nbsp; IL_0024: nop &lt;br /&gt;&amp;nbsp; IL_0025: ldstr "Could not calculate days between"&lt;br /&gt;&amp;nbsp; IL_002a: call System.Console::WriteLine &lt;br /&gt;&amp;nbsp; IL_002f: nop &lt;br /&gt;&amp;nbsp; IL_0030: nop &lt;br /&gt;&amp;nbsp; IL_0031: leave.s IL_0033&lt;br /&gt;} // end .catch&lt;br /&gt;IL_0033: nop &lt;br /&gt;IL_0034: ret &lt;/p&gt;&lt;/blockquote&gt;
&lt;p dir="ltr"&gt;The call to DaysBetween is on line IL_0015, and looking just above the call site we see that at the time of the call the parameters on the IL stack are September 15, 1980 and the current date.&amp;nbsp; Clearly the current date is not less than a date in 1980, so it appears that the bug is in the order these parameters are given to DaysBetween.&lt;/p&gt;
&lt;p dir="ltr"&gt;In fact, with a little ildasm / ilasm magic, we can test that theory.&amp;nbsp; Moving IL_0002&amp;nbsp; to appear between IL_00010 and IL_0015 will reverse the order of the parameters to the method call, and result in the program running and telling me that it&amp;rsquo;s been 9,032 days since 9/15/1980.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=426811" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Yiru on Debugging LCG</title><link>http://blogs.msdn.com/shawnfa/archive/2005/05/27/422715.aspx</link><pubDate>Sat, 28 May 2005 00:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:422715</guid><dc:creator>shawnfa</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/422715.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=422715</wfw:commentRss><description>&lt;P&gt;&lt;a href="http://blogs.msdn.com/YiruTang"&gt;Yiru's&lt;/A&gt; got a great piece up on &lt;a href="http://blogs.msdn.com/yirutang/archive/2005/05/26/422373.aspx"&gt;using SOS to debug code that was emitted using Whidbey's new Lightweight CodeGen&lt;/A&gt; feature.&amp;nbsp; Debugging any code written at the IL level can be tricky for anyone who doesn't have Partition III of ECMA committed to mind.&amp;nbsp; LCG makes it even more fun since the code is generated dynamically, so there's generally not any source to look at when figuring out the problem.&amp;nbsp; Yiru shows how to use the the SOS commands&amp;nbsp;!DumpMD, !DumpIL and friends to help figure out what is wrong with the emitted method.&lt;/P&gt;
&lt;P&gt;As I've mentioned a few times before in this blog WinDBG is my debugger of choice, and working with managed code all the time means knowing SOS is a must.&amp;nbsp; I'm always glad to learn a new trick or two about that particular extension.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=422715" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Whidbey's Security Off Model</title><link>http://blogs.msdn.com/shawnfa/archive/2005/04/28/412998.aspx</link><pubDate>Thu, 28 Apr 2005 17:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:412998</guid><dc:creator>shawnfa</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/412998.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=412998</wfw:commentRss><description>&lt;P&gt;Although the v1.0 and v1.1 versions of CasPol provided a switch to disable the CLR's security system, running without CAS enforcement on was never a scenario that we encouraged for obvious reasons.&amp;nbsp; The choice to disable security was a system wide switch that affected any managed application on any version of the runtime, and made running managed code incredibly unsafe.&lt;/P&gt;
&lt;P&gt;As of Whidbey, you'll find that the switch to turn security off no longer works as it used to.&amp;nbsp; If you run caspol -s off with beta 2 or later of Whidbey installed, you'll see:&lt;/P&gt;
&lt;P&gt;
&lt;DIV&gt;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50215&amp;gt;CasPol.exe -s off&lt;BR&gt;Microsoft (R) .NET Framework CasPol 2.0.50215.44&lt;BR&gt;Copyright (C) Microsoft Corporation. All rights reserved.&lt;BR&gt;&lt;BR&gt;CAS enforcement is being turned off temporarily. Press &amp;lt;ENTER&amp;gt; when you want to&lt;BR&gt;restore the setting back on.&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;Security will then be disabled as long as the CasPol process remains active.&amp;nbsp; When CasPol is terminated, it returns security to the on state.&amp;nbsp; Even abruptly terminating the CasPol process will still return security to its on state.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;This works because the implementation of the internal security off flag has changed.&amp;nbsp; Instead of using a registry key to indicate the status of CLR security, we now use a named mutex which CasPol holds to&amp;nbsp;indicate to the CLR that it should disable security.&amp;nbsp; Examining the the handles held by the&amp;nbsp;CasPol process&amp;nbsp;in a debugger will enable you to quickly identify this mutex: 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;
&lt;DIV&gt;0:000&amp;gt;!handle 0 4 Mutant&lt;BR&gt;Handle&amp;nbsp;4c&lt;BR&gt;&amp;nbsp;&amp;nbsp;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\BaseNamedObjects\CLR_CASOFF_MUTEX&lt;BR&gt;Handle&amp;nbsp;428&lt;BR&gt;&amp;nbsp;&amp;nbsp;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;none&amp;gt;&lt;BR&gt;Handle&amp;nbsp;4a8&lt;BR&gt;&amp;nbsp;&amp;nbsp;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\BaseNamedObjects\ShimCacheMutex&lt;BR&gt;Handle&amp;nbsp;624&lt;BR&gt;&amp;nbsp;&amp;nbsp;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;none&amp;gt;&lt;BR&gt;4 handles of type Mutant&lt;/DIV&gt;
&lt;P&gt;Since security is being disabled by this mutex, the CasPol process is resilient to being terminated unexpectedly, because Windows will just clean up the handle for CasPol when cleaning up the process.&amp;nbsp; Another side effect is that if the machine is rebooted, the security state will revert to on.&lt;/P&gt;
&lt;P&gt;If we fire up the kernel debugger, we can take a look at the ACL of the mutex:&lt;/P&gt;
&lt;P&gt;
&lt;DIV&gt;lkd&amp;gt;&amp;nbsp;!object&amp;nbsp;\BaseNamedObjects\CLR_CASOFF_MUTEX&lt;BR&gt;Object:&amp;nbsp;85088d88&amp;nbsp;&amp;nbsp;Type:&amp;nbsp;(8679f040)&amp;nbsp;Mutant&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ObjectHeader:&amp;nbsp;&lt;B&gt;85088d70&lt;/B&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HandleCount:&amp;nbsp;1&amp;nbsp;&amp;nbsp;PointerCount:&amp;nbsp;2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Directory&amp;nbsp;Object:&amp;nbsp;e179f980&amp;nbsp;&amp;nbsp;Name:&amp;nbsp;CLR_CASOFF_MUTEX&lt;BR&gt;&lt;BR&gt;lkd&amp;gt;&amp;nbsp;dt&amp;nbsp;nt!_OBJECT_HEADER&amp;nbsp;85088d70&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x000&amp;nbsp;PointerCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x004&amp;nbsp;HandleCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;1&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x004&amp;nbsp;NextToFree&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x00000001&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x008&amp;nbsp;Type&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x8679f040&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x00c&amp;nbsp;NameInfoOffset&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x10&amp;nbsp;''&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x00d&amp;nbsp;HandleInfoOffset&amp;nbsp;:&amp;nbsp;0&amp;nbsp;''&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x00e&amp;nbsp;QuotaInfoOffset&amp;nbsp;&amp;nbsp;:&amp;nbsp;0&amp;nbsp;''&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x00f&amp;nbsp;Flags&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x20&amp;nbsp;'&amp;nbsp;'&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x010&amp;nbsp;ObjectCreateInfo&amp;nbsp;:&amp;nbsp;0x853e3678&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x010&amp;nbsp;QuotaBlockCharged&amp;nbsp;:&amp;nbsp;0x853e3678&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x014&amp;nbsp;SecurityDescriptor&amp;nbsp;:&amp;nbsp;&lt;B&gt;0xe2c57b2c&lt;/B&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;+0x018&amp;nbsp;Body&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;_QUAD&lt;BR&gt;&lt;BR&gt;lkd&amp;gt;&amp;nbsp;??&amp;nbsp;0xe2c57b2c&amp;nbsp;&amp;amp;&amp;nbsp;~0x7&lt;BR&gt;unsigned&amp;nbsp;int&amp;nbsp;0xe2c57b28&lt;BR&gt;&lt;BR&gt;lkd&amp;gt;&amp;nbsp;!sd&amp;nbsp;e2c57b28 1&lt;BR&gt;-&amp;gt;Revision:&amp;nbsp;0x1&lt;BR&gt;-&amp;gt;Sbz1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x0&lt;BR&gt;-&amp;gt;Control&amp;nbsp;:&amp;nbsp;0x8004&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SE_DACL_PRESENT&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SE_SELF_RELATIVE&lt;BR&gt;-&amp;gt;Owner&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;S-1-5-32-544&amp;nbsp;(Alias:&amp;nbsp;BUILTIN\Administrators)&lt;BR&gt;-&amp;gt;Group&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;S-1-5-21-2127521184-1604012920-1887927527-513&amp;nbsp;(Group:&amp;nbsp;REDMOND\Domain&amp;nbsp;Users)&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;AclRevision:&amp;nbsp;0x2&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Sbz1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x0&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;AclSize&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x34&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;AceCount&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x2&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Sbz2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;0x0&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[0]:&amp;nbsp;-&amp;gt;AceType:&amp;nbsp;ACCESS_ALLOWED_ACE_TYPE&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[0]:&amp;nbsp;-&amp;gt;AceFlags:&amp;nbsp;0x0&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[0]:&amp;nbsp;-&amp;gt;AceSize:&amp;nbsp;0x18&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[0]:&amp;nbsp;-&amp;gt;Mask&amp;nbsp;:&amp;nbsp;0x001f0001&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[0]:&amp;nbsp;-&amp;gt;SID:&amp;nbsp;S-1-5-32-544&amp;nbsp;(Alias:&amp;nbsp;BUILTIN\Administrators)&lt;BR&gt;&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[1]:&amp;nbsp;-&amp;gt;AceType:&amp;nbsp;ACCESS_ALLOWED_ACE_TYPE&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[1]:&amp;nbsp;-&amp;gt;AceFlags:&amp;nbsp;0x0&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[1]:&amp;nbsp;-&amp;gt;AceSize:&amp;nbsp;0x14&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[1]:&amp;nbsp;-&amp;gt;Mask&amp;nbsp;:&amp;nbsp;0x001f0001&lt;BR&gt;-&amp;gt;Dacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;-&amp;gt;Ace[1]:&amp;nbsp;-&amp;gt;SID:&amp;nbsp;S-1-5-18&amp;nbsp;(Well&amp;nbsp;Known&amp;nbsp;Group:&amp;nbsp;NT&amp;nbsp;AUTHORITY\SYSTEM)&lt;BR&gt;&lt;BR&gt;-&amp;gt;Sacl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;&amp;nbsp;is&amp;nbsp;NULL&lt;BR&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;That shows that the mutex is created with an ACL that prevents anyone who isn't an administrator from owning it.&amp;nbsp; And although Windows does not provide a way to prevent non-administrators from creating this mutex, internally the CLR will not respect the existence of the named mutex if it is abandoned or not owned by the BUILTIN\Administrators group.&amp;nbsp; This prevents a squatting attack where a malicious user could turn off security simply by creating this mutex himself.&lt;/P&gt;
&lt;P&gt;One of the more interesting&amp;nbsp;effects&amp;nbsp;to note&amp;nbsp;of disabling security with this mutex is that the v2.0 CLR will no longer respect the registry key used by older versions of the runtime, and those versions will not have their security disabled by the new CasPol switch.&lt;/P&gt;
&lt;P&gt;Although there still is the ability to turn off security, the ability to turn it off permanently has been removed.&amp;nbsp; The new switch is useful mostly for debugging purposes, to establish if a problem you're diagnosing is related to the security system or not.&amp;nbsp; The recommendation is still to avoid using this mechanism if at all possible.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=412998" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Windows/default.aspx">Windows</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category></item><item><title>Mike Stall on Finding the Real Exception Call stack</title><link>http://blogs.msdn.com/shawnfa/archive/2005/01/19/356376.aspx</link><pubDate>Wed, 19 Jan 2005 22:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:356376</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/356376.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=356376</wfw:commentRss><description>Mike's got an interesting piece up today about &lt;A href="http://blogs.msdn.com/jmstall/archive/2005/01/18/355697.aspx"&gt;using WinDbg to find the actual call stack of an unmanaged (or managed for that matter) exception&lt;/a&gt;.&amp;nbsp; It's this kind of power debugging technique that makes WinDbg my all time favorite debugger.&amp;nbsp;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=356376" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Mike Stall's (Relatively)New Debugger Blog</title><link>http://blogs.msdn.com/shawnfa/archive/2004/10/05/238256.aspx</link><pubDate>Tue, 05 Oct 2004 21:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:238256</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/238256.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=238256</wfw:commentRss><description>&lt;p&gt;&lt;A href="http://blogs.msdn.com/jmstall"&gt;Mike Stall&lt;/a&gt; is one of the devs on our&lt;strong&gt; &lt;/strong&gt;base services team, and his focus is on managed debugging.&amp;nbsp;I played football with Mike 4 flag football seasons back, but generally don't need to work directly with him since the debugger and security don't have very much interaction.&amp;nbsp; However, Mike is always the guy to go to whenever there's a debugging question, so I'll definitely be reading his blog with interest.&lt;/p&gt; &lt;p&gt;Some of the topics he's already covered are &lt;A href="http://blogs.msdn.com/jmstall/archive/2004/09/30/236281.aspx"&gt;mdbg&lt;/a&gt;&amp;nbsp;and the &lt;A href="http://blogs.msdn.com/jmstall/archive/2004/10/02/237005.aspx"&gt;ICorDebug&lt;/a&gt; &lt;A href="http://blogs.msdn.com/jmstall/archive/2004/10/05/237954.aspx"&gt;interface&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=238256" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category></item><item><title>Finding Out The Current User in the Debugger</title><link>http://blogs.msdn.com/shawnfa/archive/2004/09/23/233665.aspx</link><pubDate>Fri, 24 Sep 2004 01:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:233665</guid><dc:creator>shawnfa</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/233665.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=233665</wfw:commentRss><description>&lt;p&gt;Every once in a while, while debugging multi-threaded applications that do impersonation, it becomes useful to figure out the context that the current thread is running under.&amp;nbsp; This is especially useful when debugging server scenarios where connections are farmed out to worker threads which begin their work by impersonating the user logging in.&amp;nbsp; Before Whidbey finding this information wasn't very straightforward, and even when you found out the current user, it was difficult to find out any other security token information.&lt;/p&gt; &lt;p&gt;Thankfully the VS Whidbey debugger team has stepped up with a nice solution to this problem.&amp;nbsp; You can now evaluate the $user pseudo-register in the debugger, and find out all about the context that the current process and thread are running under.&amp;nbsp; In addition to the user name, this variable also shows their SID, session id, login id, impersonation level, and active privileges.&amp;nbsp; In addition to this, information on all the groups that the active user is a member of is listed.&lt;/p&gt; &lt;p&gt;If the current thread is impersonating, then information on the user the thread is impersonating as is also available.&amp;nbsp; Here's what this might look like on a thread that is not impersonating:&lt;/p&gt; &lt;p&gt;&lt;img alt="Evaluating the $user pseudo-register in the VS Whidbey QuickWatch window" src="http://www.sfarkas.net/images/blog/UserVar.png" /&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=233665" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Whidbey's New SecurityException</title><link>http://blogs.msdn.com/shawnfa/archive/2004/07/30/202468.aspx</link><pubDate>Fri, 30 Jul 2004 19:24:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:202468</guid><dc:creator>shawnfa</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/202468.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=202468</wfw:commentRss><description>&lt;P&gt;One of the more difficult things to debug with .NET 1.0 and 1.1 is the security exception.&amp;nbsp; With these frameworks generally the only information that you got was the state of the failed permission.&amp;nbsp; Due to the complexity of debugging security problems, most people just gave up and required that their code run in a fully trusted environment.&amp;nbsp; With Whidbey we've done a lot of work to beef up the security exception, and make debugging security issues even easier, in the process making it easier for developers to figure out the minimum set of permissions that their application needs to run under.&lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Limitations of the Current&amp;nbsp;Implementation&lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Currently, the SecurityException contains four security specific properties.&lt;BR&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemsecuritysecurityexceptionclassgrantedsettopic.asp"&gt;GrantedSet&lt;/A&gt;&amp;nbsp;provides the set of permissions that are granted to the assembly that failed.&amp;nbsp; This property does not get filled out every time an exception is thrown however. 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSecuritySecurityExceptionClassPermissionStateTopic.asp"&gt;PermissionState&lt;/A&gt; has the permission or permission set that caused the exception to be thrown 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSecuritySecurityExceptionClassPermissionTypeTopic.asp"&gt;PermissionType&lt;/A&gt; is also not always filled out, when it is, it should contain if PermissionState is a permission, permission set, or permission set collection 
&lt;LI&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSecuritySecurityExceptionClassRefusedSetTopic.asp"&gt;RefusedSet&lt;/A&gt; contains the set of permissions that were refused by by the assembly that caused the security exception to be thrown&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Generally, PermissionState is the only property that can be depended upon to always have a value.&amp;nbsp; This does not provide for a good user experience.&lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;The Whidbey SecurityException&lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;The Whidbey SecurityException adds several more properties, which together allow developers to figure out what code was causing a security problem.&amp;nbsp; The new properties are:&lt;/P&gt;
&lt;TABLE border=2&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;B&gt;Name&lt;/B&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;B&gt;Type&lt;/B&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;B&gt;Description&lt;/B&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Action &lt;/TD&gt;
&lt;TD&gt;SecurityAction&lt;/TD&gt;
&lt;TD&gt;the SecurityAction that failed the security check&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Demanded &lt;/TD&gt;
&lt;TD&gt;object&lt;/TD&gt;
&lt;TD&gt;the permission, permission set, or permission sets that were demanded and triggered the exception&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;DenySetInstance &lt;/TD&gt;
&lt;TD&gt;object&lt;/TD&gt;
&lt;TD&gt;if&amp;nbsp;a Deny&amp;nbsp;stack frame caused the security exception to fail, then this property will contain that set, otherwise it will be null.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;FailedAssemblyInfo &lt;/TD&gt;
&lt;TD&gt;AssemblyName&lt;/TD&gt;
&lt;TD&gt;AssemblyName of the assembly that caused the security check to fail&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;FirstPermissionThatFailed &lt;/TD&gt;
&lt;TD&gt;IPermission&lt;/TD&gt;
&lt;TD&gt;the first permission in failing PermissionSet (or PermissionSetCollection) that did not pass the security check&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Method&lt;/TD&gt;
&lt;TD&gt;MethodInfo&lt;/TD&gt;
&lt;TD&gt;the method that the failed assembly was in when it encountered the security check that triggered the exception.&amp;nbsp; If a PermitOnly or Deny stack frame failed, this will contain the method that put the PermitOnly or Deny frame on the stack.&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;PermitOnlySetInstance&lt;/TD&gt;
&lt;TD&gt;object&lt;/TD&gt;
&lt;TD&gt;if the stack frame that caused the security exception had a PermitOnly permission set, this property will contain it, otherwise it will be null&amp;nbsp;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Url &lt;/TD&gt;
&lt;TD&gt;string&lt;/TD&gt;
&lt;TD&gt;URL of the assembly that failed the security check&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;Zone &lt;/TD&gt;
&lt;TD&gt;SecurityZone&lt;/TD&gt;
&lt;TD&gt;Zone of the assembly that failed the security check&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;As you can see, there's a ton more data available about the cause of the security exception in Whidbey.&amp;nbsp; However, as I noted above, even the current SecurityException properties don't get filled out properly all the time.&amp;nbsp; As part of the SecurityException enhancement work, we've gone through all the places in the BCL that throw exceptions and ensured that they've filled out as much of the SecurityException data as possible.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;So What Does a New Security Exception Look Like?&lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;All of these extra properties provide a lot of information for developers to work with if they catch the SecurityException in their code.&amp;nbsp; But what happens if the exception goes unhandled?&amp;nbsp; The default behavior of spewing exception information to the screen will still provide a lot more information than was provided before.&amp;nbsp; For instance, if I tried to run my &lt;A href="http://blogs.msdn.com/shawnfa/archive/2004/05/05/126825.aspx"&gt;ProtectedData sample &lt;/A&gt;off a network share, with default policy in place, I'd end up with a SecurityException.&amp;nbsp; The debug spew for that exception would look similar to the following. 
&lt;P&gt;
&lt;P&gt;First comes the standard stack trace and exception type that failed.&lt;BR&gt;
&lt;DIV class=codeblock&gt;Unhandled Exception: System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.DataProtectionPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.&lt;BR&gt;at System.Security.CodeAccessSecurityEngine.Check(PermissionToken permToken,CodeAccessPermission demand, StackCrawlMark&amp;amp; stackMark, Int32 checkFrames, Int32 unrestrictedOverride)&lt;BR&gt;at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark&amp;amp; stackMark)&lt;BR&gt;at System.Security.CodeAccessPermission.Demand()&lt;BR&gt;at System.Security.Cryptography.ProtectedData.Protect(Byte[] userData, Byte[] optionalEntropy, DataProtectionScope scope)&lt;BR&gt;at CPD.Main() in \\shawnfa-build\c$\blog\ManagedDPAPI\CryptProtectData.cs:line 12&lt;BR&gt;&lt;/DIV&gt;&lt;BR&gt;&lt;BR&gt;This is followed up by the SecurityAction that failed, the first failed permission, and the details of the demanded permissions. (From now on, I'm going to abbreviate the full assembly names.)&lt;BR&gt;
&lt;DIV class=codeblock&gt;The action that failed was:&lt;BR&gt;Demand&lt;BR&gt;The type of the first permission that failed was:&lt;BR&gt;System.Security.Permissions.DataProtectionPermission&lt;BR&gt;The first permission that failed was:&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.DataProtectionPermission, mscorlib ... "&lt;BR&gt;version="1"&lt;BR&gt;Flags="ProtectData"/&amp;gt;&lt;BR&gt;&lt;BR&gt;The demand was for:&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.DataProtectionPermission, mscorlib ..."&lt;BR&gt;version="1"&lt;BR&gt;Flags="ProtectData"/&amp;gt;&lt;BR&gt;&lt;BR&gt;&lt;/DIV&gt;&lt;BR&gt;&lt;BR&gt;Next is a list of all the permissions granted to the assembly that failed the demand:&lt;BR&gt;
&lt;DIV class=codeblock&gt;The granted set of the failing assembly was:&lt;BR&gt;&amp;lt;PermissionSet class="System.Security.PermissionSet"&lt;BR&gt;version="1"&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib ..."&lt;BR&gt;version="1"&lt;BR&gt;Read="USERNAME"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.FileDialogPermission, mscorlib ..."&lt;BR&gt;version="1"&lt;BR&gt;Unrestricted="true"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.FileIOPermission, mscorlib ..."&lt;BR&gt;version="1"&lt;BR&gt;Read="\\SHAWNFA-BUILD\C$\blog\ManagedDPAPI\"&lt;BR&gt;PathDiscovery="\\SHAWNFA-BUILD\C$\blog\ManagedDPAPI\"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.IsolatedStorageFilePermission, mscorlib ..."&lt;BR&gt;version="1"&lt;BR&gt;Allowed="AssemblyIsolationByUser"&lt;BR&gt;UserQuota="9223372036854775807"&lt;BR&gt;Expiry="9223372036854775807"&lt;BR&gt;Permanent="True"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.ReflectionPermission, mscorlib ..."&lt;BR&gt;version="1"&lt;BR&gt;Flags="ReflectionEmit"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, ..."&lt;BR&gt;version="1"&lt;BR&gt;Flags="Assertion, Execution, BindingRedirects"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.UIPermission, mscorlib, ..."&lt;BR&gt;version="1"&lt;BR&gt;Unrestricted="true"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.UrlIdentityPermission, mscorlib, ..."&lt;BR&gt;version="1"&lt;BR&gt;Url="file://shawnfa-build/c$/blog/ManagedDPAPI/CryptProtectData.exe"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Security.Permissions.ZoneIdentityPermission, mscorlib, ..."&lt;BR&gt;version="1"&lt;BR&gt;Zone="Intranet"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Net.DnsPermission, System ..."&lt;BR&gt;version="1"&lt;BR&gt;Unrestricted="true"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Windows.Forms.WebBrowserPermission, System ..."&lt;BR&gt;version="1"&lt;BR&gt;Level="Restricted"/&amp;gt;&lt;BR&gt;&amp;lt;IPermission class="System.Drawing.Printing.PrintingPermission, System.Drawing ..."&lt;BR&gt;version="1"&lt;BR&gt;Level="DefaultPrinting"/&amp;gt;&lt;BR&gt;&amp;lt;/PermissionSet&amp;gt;&lt;BR&gt;&lt;BR&gt;&lt;/DIV&gt;&lt;BR&gt;&lt;BR&gt;Finally, the assembly that failed the permission demand is listed along with the method that called into the demanding code, and the Zone and URL evidence for that assembly.&lt;BR&gt;
&lt;DIV class=codeblock&gt;The assembly that failed was:&lt;BR&gt;CryptProtectData, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null&lt;BR&gt;The method that caused the failure was:&lt;BR&gt;Void Main()&lt;BR&gt;The Zone of the assembly that failed was:&lt;BR&gt;Intranet&lt;BR&gt;The Url of the assembly that failed was:&lt;BR&gt;file://shawnfa-build/c$/blog/ManagedDPAPI/CryptProtectData.exe&lt;BR&gt;&lt;BR&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Visual Studio Gets In On The Action&lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;In addition to all the work done in the CLR to make debugging security exceptions easier, Visual Studio 2005 has done quite a bit of work as well.&amp;nbsp; When an unhandled&amp;nbsp;SecurityException is thrown under the VS debugger, Visual Studio will look at all of the extra properties that are populated on that exception, and provide you with context sensitive help to solve the problem.&lt;/P&gt;
&lt;P&gt;&lt;IMG height=545 alt="Visual Studio 2005 Security Exception Handler" src="http://www.sfarkas.net/images/blog/VSSecurityException.png" width=788 border=2&gt;&lt;/P&gt;
&lt;P&gt;As you can see in the screen shot, VS will highlight the line that caused the SecurityException, and shows a pop up dialog that tells you the permission that failed and provides several possible solutions for the problem.&amp;nbsp; In this case, there's not a lot of ways to get around the DataProtectionPermission demand, so the options that VS presents include turning this into a ClickOnce application or installing locally.&amp;nbsp; This help is based around the failing permission, so if a FileIOPermission failed, VS might suggest using IsolatedStorage instead.&lt;/P&gt;
&lt;P&gt;The View Details link will, oddly enough, open up the View Detail dialog where you can inspect each property of the Security Exception yourself, in order to help you further track down security issues.&lt;/P&gt;
&lt;P&gt;
&lt;H2&gt;Debug-In-Zone&lt;/H2&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;All that's fine and good, but when you develop on your local machine, you end up with FullTrust by default.&amp;nbsp; Forcing developers to modify their security policy to debug is not a good user experience, so again Visual Studio steps up to the plate, this time with a feature called Debug In Zone.&lt;/P&gt;
&lt;P&gt;&lt;IMG height=488 alt="Debug In Zone Settings" src="http://www.sfarkas.net/images/blog/DebugInZone.png" width=591 border=2&gt;&lt;/P&gt;
&lt;P&gt;By going to your project properties, and accessing the security tab, you can specify the set of permissions that you'd like to debug your application with.&amp;nbsp; For instance, if your goal is to have your application run with Internet permissions, then just select Internet from the drop down list.&amp;nbsp; You can also create a custom permission set that reduces down to the exact set of permissions that your app needs;&amp;nbsp;the Calculate Permissions button, which will interface with PermCalc will help you with this goal.&lt;/P&gt;
&lt;P&gt;With the changes to the SecurityException&amp;nbsp;class and enhancements to the Visual Studio debugger, figuring out the cause of those hard to diagnose SecurityExceptions.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=202468" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/ClickOnce/default.aspx">ClickOnce</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CAS/default.aspx">CAS</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>What Happens When My Application Throws An Unhandled Exception</title><link>http://blogs.msdn.com/shawnfa/archive/2004/07/15/184490.aspx</link><pubDate>Thu, 15 Jul 2004 21:26:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:184490</guid><dc:creator>shawnfa</dc:creator><slash:comments>6</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/184490.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=184490</wfw:commentRss><description>&lt;P&gt;There are several different behaviors that can occur when a managed application throws an unhandled exception.&amp;nbsp; The two most common are to bring up an error dialog box, or to pop up the Visual Studio Just In Time Debugger dialog box.&lt;/P&gt;
&lt;P&gt;The first behavior is the default when you install the CLR, but don't install Visual Studio.&amp;nbsp; Installing VS modifies the default to pop up the select-a-debugger dialog.&amp;nbsp; How does the CLR figure out what behavior to use?&amp;nbsp; It checks a registry key, located at HKLM\Software\Microsoft\.NetFramework\DbgJITDebugLaunchSetting.&amp;nbsp; The value of this key lets the CLR know what to do when it encounters an unhandled exception.&amp;nbsp; Possible values are:&lt;/P&gt;
&lt;TABLE border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;&lt;B&gt;Value&lt;/B&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;B&gt;Action&lt;/B&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;0&lt;/TD&gt;
&lt;TD&gt;Bring up the unhandled exception dialog box. (Click OK to terminate ...)&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;Print out the stack trace of the exception and terminate the application&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;TD&gt;Invoke the default managed debugger&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;If the value is set to 2, then the CLR consults HKLM\Software\Microsoft\.NetFramework\DbgManagedDebugger to determine which debugger to launch.&amp;nbsp; This debugger is expected to be a managed debugger, that uses the CLR debugging interface.&amp;nbsp; The debugger listed in this key will get four parameters, specified using printf style % format characters.&amp;nbsp; The parameters are:&lt;/P&gt;
&lt;TABLE border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD&gt;Parameter number&lt;/TD&gt;
&lt;TD&gt;Meaning&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;1&lt;/TD&gt;
&lt;TD&gt;PID of the process&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;2&lt;/TD&gt;
&lt;TD&gt;ID of the AppDomain&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;3&lt;/TD&gt;
&lt;TD&gt;Exception string ("System.OutOfMemoryException"), as a wide character string&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;4&lt;/TD&gt;
&lt;TD&gt;Event handle to signal when aborting the attach operation&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;By default, Visual Studio registers the VSJITDebugger.exe program as the debugger, which is what is responsible for displaying the familiar choose-a-debugger dialog box.&amp;nbsp; The default registration for this debugger in Visual Studio 2003 is:&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=codeblock&gt;"C:\Program Files\Common Files\Microsoft Shared\VS7Debug\VsJITDebugger.exe" PID %d APPDOM %d EXTEXT "%s" EVTHDL %d&lt;/DIV&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=184490" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Under+the+Hood/default.aspx">Under the Hood</category></item></channel></rss>