<?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>Iron Curt : Guts</title><link>http://blogs.msdn.com/curth/archive/tags/Guts/default.aspx</link><description>Tags: Guts</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Viewing Emitted IL</title><link>http://blogs.msdn.com/curth/archive/2008/08/12/viewing-emitted-il.aspx</link><pubDate>Wed, 13 Aug 2008 06:28:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8855634</guid><dc:creator>curth</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/curth/comments/8855634.aspx</comments><wfw:commentRss>http://blogs.msdn.com/curth/commentrss.aspx?PostID=8855634</wfw:commentRss><description>&lt;p&gt;Let's say you're working on a project such as &lt;a href="http://www.codeplex.com/IronPython"&gt;IronPython&lt;/a&gt; or &lt;a href="http://www.ironruby.net/"&gt;IronRuby&lt;/a&gt; that makes use of Reflection.Emit to generate code at runtime.&amp;nbsp; You're probably used to seeing a stack trace in Visual Studio that looks something like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/curth/WindowsLiveWriter/ViewingEmittedIL_11275/Callstack_1_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="278" alt="Call stack from Visual Studio" src="http://blogs.msdn.com/blogfiles/curth/WindowsLiveWriter/ViewingEmittedIL_11275/Callstack_1_thumb.png" width="626" border="0"&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Visual Studio will do its best to prevent you from viewing any part of that [Lightweight Function].&amp;nbsp; It won't let you trace into those methods, even while viewing from assembly language. If you're feeling clever, you can use the registers view and the and memory view to identify the return address on the stack, but there's no way of knowing for sure whether or not the caller is actual code or just a &lt;a href="http://en.wikipedia.org/wiki/Thunk"&gt;thunk&lt;/a&gt; of some kind.&lt;/p&gt; &lt;p&gt;But it turns out that there's another way of doing this that's fairly straightforward.&lt;/p&gt; &lt;h3&gt;Enter &lt;strike&gt;Sand&lt;/strike&gt;Windbag&lt;/h3&gt; &lt;p&gt;The managed debugger operates at a fairly high level of abstraction (as far as debuggers go).&amp;nbsp; So when the going gets tough, the tough resort to windbg.exe (or its command-line cousin cdb.exe).&amp;nbsp; These are part of the Debugging Tools for Windows, which can be downloaded from &lt;a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx"&gt;http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Here's what you need to do.&lt;/p&gt; &lt;p&gt;1. If you're not viewing it in Visual Studio already, bring up the Debug Location toolbar, which looks like this:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/curth/WindowsLiveWriter/ViewingEmittedIL_11275/thread_1_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="43" alt="Process: [7172] ipy.vshost.exe    Thread: [1440] Main Thread" src="http://blogs.msdn.com/blogfiles/curth/WindowsLiveWriter/ViewingEmittedIL_11275/thread_1_thumb.png" width="534" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;This will tell us the name and id of the process and thread that we need to connect to from windbg.&lt;/p&gt; &lt;p&gt;2. If you haven't already, start windbg.&amp;nbsp; From the File menu, select Attach to a Process -- or hit F6.&lt;/p&gt; &lt;p&gt;Here's the key part.&amp;nbsp; When you select the process for connecting, you want to specify that it's a noninvasive attach:&lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/curth/WindowsLiveWriter/ViewingEmittedIL_11275/windbg_1_2.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="285" alt="Screenshot from windbg.exe" src="http://blogs.msdn.com/blogfiles/curth/WindowsLiveWriter/ViewingEmittedIL_11275/windbg_1_thumb.png" width="369" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;In Windows, only a single process can connect to any given other process as the debugger.&amp;nbsp; Visual Studio is already the registered debugger for this instance of IronPython, so windbg cannot establish the same relationship with it.&amp;nbsp; What "Noninvasive" debugging does is to use SuspendThread to suspend all the threads in the target process and then use ReadProcessMemory to access its internals.&amp;nbsp; At that point, it's not unlike debugging a core dump; you have the entire memory image to look at, but you can't actually set breakpoints or execute any code inside that process.&lt;/p&gt; &lt;p&gt;There's plenty of information about &lt;a href="http://msdn.microsoft.com/en-us/library/cc266358.aspx"&gt;noninvasive debugging&lt;/a&gt; at various locations on the net.&lt;/p&gt; &lt;p&gt;For our needs -- looking at the MSIL and the native machine code for methods generated through Reflection.Emit -- this turns out to be good enough.&lt;/p&gt; &lt;p&gt;3. Now we'll want to load the &lt;a href="http://msdn.microsoft.com/en-us/library/bb190764.aspx"&gt;SOS Debugging Extension&lt;/a&gt;.&amp;nbsp; This actually ships with the .NET runtime now, so there should be nothing for you to load.&amp;nbsp; Unfortunately, the ".loadby" windbg command doesn't seem to work when we do a noninvasive connect, so you'll have to type a full path in the command to load the extension.&amp;nbsp; With a default installation of Windows, this will probably be&lt;/p&gt; &lt;p&gt;.load C:\Windows\Microsoft.NET\Framework\v2.0.50727\SOS.dll (for a 32-bit process), and&lt;br&gt;.load C:\Windows\Microsoft.NET\Framework64\v2.0.50727\SOS.dll (for a 64-bit process).&lt;/p&gt; &lt;p&gt;4. Let's make sure that we're looking at the right thread.&amp;nbsp; You can get a list of threads by using the "~" command, or you can choose "Processes and Threads" from the View menu.&amp;nbsp; The thread identifiers here are expressed in hexadecimal, so you'll need to do a quick conversion from the "1440" in Visual Studio to 5a0.&amp;nbsp; Here's the output from the "~" command.&lt;/p&gt;&lt;pre&gt;0:000&amp;gt; ~&lt;br&gt;.&amp;nbsp; 0&amp;nbsp; Id: 1c04.15f8 Suspend: 1 Teb: 7ffdf000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 1&amp;nbsp; Id: 1c04.11e8 Suspend: 1 Teb: 7ffde000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 2&amp;nbsp; Id: 1c04.16cc Suspend: 1 Teb: 7ffdd000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 3&amp;nbsp; Id: 1c04.d08 Suspend: 1 Teb: 7ffdc000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 4&amp;nbsp; Id: 1c04.153c Suspend: 1 Teb: 7ffda000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 5&amp;nbsp; Id: 1c04.1478 Suspend: 1 Teb: 7ffd7000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 6&amp;nbsp; Id: 1c04.d14 Suspend: 1 Teb: 7ffd9000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 7&amp;nbsp; Id: 1c04.102c Suspend: 1 Teb: 7ffd6000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 8&amp;nbsp; Id: 1c04.ac0 Suspend: 1 Teb: 7ffd5000 Unfrozen&lt;br&gt;&amp;nbsp;&amp;nbsp; 9&amp;nbsp; Id: 1c04.1118 Suspend: 1 Teb: 7ffd4000 Unfrozen&lt;br&gt;&amp;nbsp; 10&amp;nbsp; Id: 1c04.5a0 Suspend: 1 Teb: 7ffd3000 Unfrozen&lt;br&gt;&amp;nbsp; 11&amp;nbsp; Id: 1c04.13d8 Suspend: 1 Teb: 7ffd8000 Unfrozen&lt;/pre&gt;
&lt;p&gt;In this list, thread 10 matches the one where we hit the breakpoint in Visual Studio -- so we can switch to this thread from thread 0 by executing "~10 s".&amp;nbsp; Alternatively, if you were viewing the "Processes and Threads" window, you could just double-click on the thread in question.&lt;/p&gt;
&lt;p&gt;5. Now we're ready to look at the stack.&amp;nbsp; Execute the command "!clrstack".&amp;nbsp; The output should closely resemble the stack trace that you see in Visual Studio -- except now you'll see names for all of those "Lightweight Function" frames.&amp;nbsp; You'll also get the stack pointer and instruction pointer for each frame.&amp;nbsp; The result should look something like this:&lt;/p&gt;&lt;pre&gt;0:010&amp;gt; !clrstack&lt;br&gt;OS Thread Id: 0x66c (10)&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;0572da10 04f85469 IronPython.Modules.PythonNT.chdir(System.String)&lt;br&gt;0572da80 04a81b99 DynamicClass._stub_$11##11(System.Runtime.CompilerServices.Closure, System.Scripting.Actions.CallSite, System.Scripting.Runtime.CodeContext, System.Object, System.String)&lt;br&gt;0572dab8 04a81ab1 DynamicClass._stub_MatchCaller(System.Object, System.Scripting.Actions.CallSite, System.Object[])&lt;br&gt;0572dae4 047fa24d System.Scripting.Actions.CallSite`1[[System.__Canon, mscorlib]].UpdateAndExecute(System.Object[])&lt;br&gt;0572dc68 04f60307 System.Scripting.Actions.UpdateDelegates.Update3[[System.__Canon, mscorlib],[System.__Canon, mscorlib],[System.__Canon, mscorlib],[System.__Canon, mscorlib],[System.__Canon, mscorlib]](System.Scripting.Actions.CallSite, System.__Canon, System.__Canon, System.__Canon)&lt;br&gt;0572dce8 04a81925 DynamicClass.&amp;lt;module&amp;gt;$10##10(System.Runtime.CompilerServices.Closure, System.Scripting.Runtime.Scope, System.Scripting.Runtime.LanguageContext)&lt;br&gt;0572dd88 04a74ab8 System.Scripting.ScriptCode.InvokeTarget(System.Linq.Expressions.LambdaExpression, System.Scripting.Runtime.Scope)&lt;/pre&gt;
&lt;p&gt;6. That second-from-top entry looks intriguing.&amp;nbsp; How can we see its code?&amp;nbsp; The first thing we need to do is to get a method descriptor for it, which we can do using the SOS command !ipmd.&lt;/p&gt;&lt;pre&gt;0:010&amp;gt; !ip2md 04a81b99&lt;br&gt;MethodDesc: 047ee580&lt;br&gt;Method Name: DynamicClass._stub_$11##11(System.Runtime.CompilerServices.Closure, System.Scripting.Actions.CallSite, System.Scripting.Runtime.CodeContext, System.Object, System.String)&lt;br&gt;Class: 047ee2c0&lt;br&gt;MethodTable: 047ee324&lt;br&gt;mdToken: 06000000&lt;br&gt;Module: 047e6b48&lt;br&gt;IsJitted: yes&lt;br&gt;CodeAddr: 04a81b18&lt;/pre&gt;
&lt;p&gt;With the method descriptor, the !dumpil command will show us the actual MSIL for this method.&lt;/p&gt;&lt;pre&gt;0:010&amp;gt; !dumpil 047ee580&lt;br&gt;This is dynamic IL. Exception info is not reported at this time.&lt;br&gt;If a token is unresolved, run "!do &amp;lt;addr&amp;gt;" on the addr given&lt;br&gt;in parenthesis. You can also look at the token table yourself, by&lt;br&gt;running "!DumpArray 01eb82ec". 
&lt;p&gt;IL_0000: ldarg.3 &lt;br&gt;IL_0001: ldarg.0 &lt;br&gt;IL_0002: ldfld 4000002 (01eb7c4c)&lt;br&gt;IL_0007: ldc.i4.0 &lt;br&gt;IL_0008: ldelem.ref &lt;br&gt;IL_0009: castclass 2000003 "System.WeakReference"&lt;br&gt;IL_000e: callvirt 6000004 System.WeakReference.get_Target()&lt;br&gt;IL_0013: ceq &lt;br&gt;IL_0015: brfalse IL_0023&lt;br&gt;IL_001a: ldarg.s VAR OR ARG 4&lt;br&gt;IL_001c: call 6000005 IronPython.Modules.PythonNT.chdir(System.String)&lt;br&gt;IL_0021: ldnull &lt;br&gt;IL_0022: ret &lt;br&gt;IL_0023: ldarg.1 &lt;br&gt;IL_0024: castclass 2000006 "System.Scripting.Actions.CallSite`1[[System.Scripting.Actions.DynamicSiteTarget`4[[System.Scripting.Runtime.CodeContext, Microsoft.Scripting.Core],[System.Object, mscorlib],[System.String, mscorlib],[System.Object, mscorlib]], Microsoft.Scripting.Core]]"&lt;br&gt;IL_0029: ldfld 4000007 (01eb8120)&lt;br&gt;IL_002e: ldarg.1 &lt;br&gt;IL_002f: ldarg.2 &lt;br&gt;IL_0030: ldarg.3 &lt;br&gt;IL_0031: ldarg.s VAR OR ARG 4&lt;br&gt;IL_0033: callvirt 6000008 System.Scripting.Actions.DynamicSiteTarget`4[[System.__Canon, mscorlib],[System.__Canon, mscorlib],[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Invoke(System.Scripting.Actions.CallSite, System.__Canon, System.__Canon, System.__Canon)&lt;br&gt;IL_0038: ret &lt;br&gt;IL_0039: ldnull &lt;br&gt;IL_003a: ret &lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;If you want to see what the associated x86 or x64 machine code looks like, the "CodeAddr" value from the !ip2md command will give you the starting address of the JITted code.&amp;nbsp; You can use this with the windbg "u" command (for "unassemble").&lt;/p&gt;
&lt;p&gt;7. Once you're done, be sure to detach windbg from the program you're looking at; it's quite likely that Visual Studio will be hung until you do.&amp;nbsp; That's because it will be waiting to get data back from the debug thread that was injected into the target process -- but windbg has suspended that thread on your behalf.&amp;nbsp; "Detach Debuggee" is a menu choice on the "Debug" menu.&lt;/p&gt;
&lt;h3&gt;Left as an Exercise to the Reader&lt;/h3&gt;
&lt;p&gt;One of the interesting things that's possible with cdb.exe -- the command-line version of windbg.exe -- is to control it from a separate program.&amp;nbsp; All of the functionality we used above is accessible through cdb.&amp;nbsp; You can therefore write a program that starts a separate cdb process, piping commands to its standard input and reading -- and parsing -- the results from its standard output.&amp;nbsp; You could even write a GUI that shows the stack of the target process, and when the user clicks on a frame it puts up the MSIL for that frame into one pane and the assembly code into another.&lt;/p&gt;
&lt;p&gt;Write it using IronPython.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8855634" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/curth/archive/tags/IronPython/default.aspx">IronPython</category><category domain="http://blogs.msdn.com/curth/archive/tags/Guts/default.aspx">Guts</category></item><item><title>This... is... Dynamic!</title><link>http://blogs.msdn.com/curth/archive/2008/07/31/this-is-dynamic.aspx</link><pubDate>Fri, 01 Aug 2008 02:47:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8795828</guid><dc:creator>curth</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/curth/comments/8795828.aspx</comments><wfw:commentRss>http://blogs.msdn.com/curth/commentrss.aspx?PostID=8795828</wfw:commentRss><description>&lt;p&gt;Regarding &lt;a href="http://blogs.msdn.com/curth/default.aspx"&gt;our need to check-and-rethrow exceptions&lt;/a&gt; in &lt;a href="http://www.codeplex.com/IronPython"&gt;IronPython&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/user/Profile.aspx?UserID=132810"&gt;int19h&lt;/a&gt; asks "Shouldn't exception filters do the trick without the need to rethrow explicitly?"&lt;/p&gt; &lt;p&gt;That's a good question.&amp;nbsp; In fact, I had the exact same reaction when I first started looking into this issue.&amp;nbsp; So I changed IronPython's MSIL generation to use filters, and my updated version was able to pass all of our tests.&lt;/p&gt; &lt;p&gt;Later, during my weekly face-to-face meeting with &lt;a href="http://blogs.msdn.com/shrib/"&gt;Shri&lt;/a&gt;, I described the work I had done and Shri was immediately able to identify a corner case that was now broken.&lt;/p&gt; &lt;h3&gt;Results 1 - 10 of about 163 for "vb.net" "jan brady"&lt;/h3&gt; &lt;p&gt;Before looking at some sample Python code that causes the problem, it's worth digging a little into filters to learn something about their operation.&amp;nbsp; To do so, I'll need to leave my comfort zone and enter the world of VB.NET -- as C# doesn't have any functionality that maps onto MSIL exception filters.&lt;/p&gt; &lt;p&gt;Consider the following code:&lt;/p&gt;&lt;pre style="font-weight: bold; font-size: 10pt; background: black; color: white; font-family: consolas"&gt;    &lt;span style="color: #cc7832"&gt;Function&lt;/span&gt; CheckException(&lt;span style="color: #cc7832"&gt;ByVal&lt;/span&gt; pos &lt;span style="color: #cc7832"&gt;As&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Integer&lt;/span&gt;) &lt;span style="color: #cc7832"&gt;As&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Boolean&lt;/span&gt;
        System.Console.WriteLine(&lt;span style="color: #a5c25c"&gt;"Filter {0}"&lt;/span&gt;, pos)
        CheckException = (pos = &lt;span style="color: #6897bb"&gt;0&lt;/span&gt;)
    &lt;span style="color: #cc7832"&gt;End&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Function&lt;/span&gt;
 
    &lt;span style="color: #cc7832"&gt;Sub&lt;/span&gt; Test(&lt;span style="color: #cc7832"&gt;ByVal&lt;/span&gt; i &lt;span style="color: #cc7832"&gt;As&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Integer&lt;/span&gt;, &lt;span style="color: #cc7832"&gt;ByVal&lt;/span&gt; max &lt;span style="color: #cc7832"&gt;As&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Integer&lt;/span&gt;)
        &lt;span style="color: #cc7832"&gt;Try&lt;/span&gt;
            &lt;span style="color: #cc7832"&gt;If&lt;/span&gt; i &amp;lt; max &lt;span style="color: #cc7832"&gt;Then&lt;/span&gt;
                Test(i + &lt;span style="color: #6897bb"&gt;1&lt;/span&gt;, max)
            &lt;span style="color: #cc7832"&gt;Else&lt;/span&gt;
                &lt;span style="color: #cc7832"&gt;Throw&lt;/span&gt; &lt;span style="color: #cc7832"&gt;New&lt;/span&gt; ApplicationException(&lt;span style="color: #a5c25c"&gt;"Exception Occurred"&lt;/span&gt;)
            &lt;span style="color: #cc7832"&gt;End&lt;/span&gt; &lt;span style="color: #cc7832"&gt;If&lt;/span&gt;
        &lt;span style="color: #cc7832"&gt;Catch&lt;/span&gt; ex &lt;span style="color: #cc7832"&gt;As&lt;/span&gt; Exception &lt;span style="color: #cc7832"&gt;When&lt;/span&gt; CheckException(i)
        &lt;span style="color: #cc7832"&gt;Finally&lt;/span&gt;
            System.Console.WriteLine(&lt;span style="color: #a5c25c"&gt;"Finally {0}"&lt;/span&gt;, i)
        &lt;span style="color: #cc7832"&gt;End&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Try&lt;/span&gt;
    &lt;span style="color: #cc7832"&gt;End&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Sub&lt;/span&gt;
 
    &lt;span style="color: #cc7832"&gt;Sub&lt;/span&gt; Main()
        &lt;span style="color: #cc7832"&gt;Try&lt;/span&gt;
            Test(&lt;span style="color: #6897bb"&gt;1&lt;/span&gt;, &lt;span style="color: #6897bb"&gt;4&lt;/span&gt;)
        &lt;span style="color: #cc7832"&gt;Catch&lt;/span&gt; ex &lt;span style="color: #cc7832"&gt;As&lt;/span&gt; Exception &lt;span style="color: #cc7832"&gt;When&lt;/span&gt; CheckException(&lt;span style="color: #6897bb"&gt;0&lt;/span&gt;)
        &lt;span style="color: #cc7832"&gt;End&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Try&lt;/span&gt;
    &lt;span style="color: #cc7832"&gt;End&lt;/span&gt; &lt;span style="color: #cc7832"&gt;Sub&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;This code is designed so that the exception filter in the Test() method will always return false while the one in Main() will return true.&amp;nbsp; As a side effect of calculating this value, the filter will give us a visual notification that it has run.&lt;/p&gt;
&lt;p&gt;The exception handlers form a stack that will be traversed in reverse calling sequence, running the Finally block of each Test() invocation before continuing back up the chain.&amp;nbsp; Our natural expectation is that the filter will be executed just before the Finally, giving us output that looks like this:&lt;/p&gt;&lt;pre style="font-weight: bold; font-size: 10pt; background: black; color: white; font-family: consolas"&gt;Filter 4
Finally 4
Filter 3
Finally 3
Filter 2
Finally 2
Filter 1
Finally 1
Filter 0&lt;/pre&gt;
&lt;p&gt;But what we get when we run the code is output that actually looks like this:&lt;/p&gt;&lt;pre style="font-weight: bold; font-size: 10pt; background: black; color: white; font-family: consolas"&gt;Filter 4
Filter 3
Filter 2
Filter 1
Filter 0
Finally 4
Finally 3
Finally 2
Finally 1&lt;/pre&gt;
&lt;p&gt;So what happens instead is that the CLR actually walks the list of exception handlers twice.&amp;nbsp; The first time, it's looking for a catch block that will handle the exception.&amp;nbsp; In the course of doing so, it needs to run any filter methods it encounters in order to identify whether or not that particular catch block is "the one".&amp;nbsp; Only once it finds an exception handler does it go back and run all of the finally and fault blocks between the thrower and the catcher.&lt;/p&gt;
&lt;h3&gt;You fascinate me; tell me more!&lt;/h3&gt;
&lt;p&gt;This subtlety matters to us because of the dynamic nature of the Python language.&amp;nbsp; You can't reliably evaluate any expression in the dynamic world until you reach that particular point in the code -- because the meaning of just about anything is subject to change.&lt;/p&gt;
&lt;p&gt;Here's the Python code that demonstrates the problem:&lt;/p&gt;&lt;pre style="font-weight: bold; font-size: 10pt; background: black; color: white; font-family: consolas"&gt;x = RuntimeError
&lt;span style="color: #cc7832"&gt;def&lt;/span&gt; test():
    &lt;span style="color: #cc7832"&gt;global&lt;/span&gt; x
    &lt;span style="color: #cc7832"&gt;try&lt;/span&gt;:
        &lt;span style="color: #cc7832"&gt;raise&lt;/span&gt; x
    &lt;span style="color: #cc7832"&gt;finally&lt;/span&gt;:
        x = SyntaxError
 
&lt;span style="color: #cc7832"&gt;try&lt;/span&gt;:
    test()
&lt;span style="color: #cc7832"&gt;except&lt;/span&gt; x:
    &lt;span style="color: #cc7832"&gt;print&lt;/span&gt; &lt;span style="color: #a5c25c"&gt;'Match'&lt;/span&gt;
&lt;span style="color: #cc7832"&gt;except&lt;/span&gt;:
    &lt;span style="color: #cc7832"&gt;print&lt;/span&gt; &lt;span style="color: #a5c25c"&gt;'Mismatch'&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;In order for this to work correctly, the exception criteria "except x" at the top level must run after x is reassigned in the finally block of the test() method.&amp;nbsp; But if we use an exception filter to match the thrown exception against x, the filter will run before the value of x is set to SyntaxError and it will incorrectly report that it is the right handler for the job.&lt;/p&gt;
&lt;p&gt;And even though this is an edge case, there's nothing that actually distinguishes this code from the more usual example of "except RuntimeError" where we supply the type of the exception.&amp;nbsp; That's because the meaning of the symbol can't be determined until runtime no matter how familiar it may look to human eyes.&amp;nbsp; This is in sharp contrast to a statically typed language, where "catch (ArgumentException)" has to be resolvable to a definite type at build time or it's an error.&lt;/p&gt;
&lt;p&gt;This is part of what it means to be dynamic. Take the power and use it wisely.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8795828" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/curth/archive/tags/IronPython/default.aspx">IronPython</category><category domain="http://blogs.msdn.com/curth/archive/tags/Guts/default.aspx">Guts</category></item></channel></rss>