<?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>catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx</link><description>Spot the bug: void CFoo::Bar() { m_array1[m_i++] = null; m_array2[m_j++] = null; } I&amp;#8217;ll give you a hint &amp;#8211; it relates to my last posting about &amp;#8220;i = i +1;&amp;#8221; being a bug. One answer was to let the increment overflow. Well in that case</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#75419</link><pubDate>Wed, 18 Feb 2004 13:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:75419</guid><dc:creator>dal</dc:creator><description>Correct exception handling is one of the least documented aspects of .net programming. The guidelines that exist are completely inadequate - they usually address trivial issues such as how to format a message and ignore the important (read: hard) issues such as how/when to throw or catch based on component type and system design. I've been involved in establishing internal standards about exception handling and while it's easy to agree on the trivial junk it's almost impossible to agree on the hard issues.&lt;br&gt;&lt;br&gt;One of the hard issues has to do with the side-effects of exceptions. There are two basic issues: how does it affect outbound arguments and how does it affect object state. When you design a compoment/method you need to think about these issues and establish a policy; will a given method ensure there are no side-effects, or will it allow side-effects to remain visible if an exception is thrown from the method. In the example no policy was stated so it is not possible to determine if the code is correct or not. Coding so that there are no side-effects is not impossible but it does require thought and careful implementation. &lt;br&gt;&lt;br&gt;In .NET it is almost impossible to examine source code and be able to predict where an exception cannot be thrown. The only safe approach is to assume that an exception can occur anywhere at all. For example, another thread with sufficient security rights can inject a thread abort exception into any other thread.&lt;br&gt;&lt;br&gt;It's usually easy to write code that implements a particular feature; it's hard to write code that does that and is also reliable and robust.&lt;br&gt;&lt;br&gt;You stated that the thread pool's catch will cause intervening unwinders to run...that is true, but only on the thread where the exception occurred. Other threads will not be affected until the exception is later propagated. Anyone writing multithreaded programs needs to understand the synchronization requirements of the design. &lt;br&gt;&lt;br&gt;As a side note, unless you want to introduce far more serious bugs into your code never ever call TerminateProcess, Environment.Exit, Process,Kill, or any other variants, especially from within a catch handler buried deep within your code.&lt;br&gt;&lt;br&gt;</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#75700</link><pubDate>Wed, 18 Feb 2004 22:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:75700</guid><dc:creator>Michael Grier [MSFT]</dc:creator><description>Re: terminating a process:&lt;br&gt;&lt;br&gt;The thing about terminating the process is that (a) if the process is system critical, you will bugcheck the system and (b) it may be an unpleasent experience for the user.&lt;br&gt;&lt;br&gt;On the other hand, running code while global invariants are not true has the potential of revealing private information, corrupting data or getting privileged code to execute based on false assumptions.&lt;br&gt;&lt;br&gt;I'll take &amp;quot;fail safe&amp;quot; any day.&lt;br&gt;</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#76022</link><pubDate>Thu, 19 Feb 2004 06:38:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:76022</guid><dc:creator>Pavel Lebedinsky</dc:creator><description>&amp;gt; Correct exception handling is one of the least documented aspects of .net programming. The guidelines that exist are completely inadequate...&lt;br&gt;&lt;br&gt;If you have any suggestions on improving design guidelines make sure you let Brad Abrams (&lt;a target="_new" href="http://weblogs.asp.net/brada"&gt;http://weblogs.asp.net/brada&lt;/a&gt;) know.&lt;br&gt;&lt;br&gt;&amp;gt; unless you want to introduce far more serious bugs into your code never ever call TerminateProcess, Environment.Exit, Process,Kill, or any other variants, especially from within a catch handler buried deep within your code.&lt;br&gt;&lt;br&gt;Can you give an example of what you mean here? I can't think of anything especially bad that could happen after I call Environment.Exit(unless the process was totally messed up to begin with).</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#76204</link><pubDate>Thu, 19 Feb 2004 13:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:76204</guid><dc:creator>dal</dc:creator><description>Calling Process.Kill is the worst way to shutdown because that does a hardstop on the entire process; no finalizers run, threads are killed, etc. This is similar to calling Win32's TerminateProcess; do not try this at home. &lt;br&gt;&lt;br&gt;The problem with calling Environment.Exit is that while it is a mostly-graceful shutdown (finalizers run) it still is not a completely graceful shutdown. It operates completely differently then unloading an appdomain. Refer to Chris Crumme's most excellent blog for a detailed description; here's a summary (there's a lot left out):&lt;br&gt;&lt;br&gt;1. The Finalizer thread finalizes all unreachable objects. This is normal and occurs in all appdomains.&lt;br&gt;2. ProcessExit event is raised.&lt;br&gt;3. Suspend all managed threads - these threads are never restarted.&lt;br&gt;4. Finalize all objects, including rooted objects.&lt;br&gt;5. Exit.&lt;br&gt;&lt;br&gt;Two big problems; first, all appdomains are unloaded, and second, code in finally blocks are not executed.&lt;br&gt;&lt;br&gt;In step 3 all threads are suspended and never resumed. This means that code in finally blocks never execute! While finalizers for rooted objects still run (step 4), which is useful for reclaiming unmanaged resources, finally blocks are not run, which means that any transaction-type cleanup code never run.&lt;br&gt;&lt;br&gt;A minor problem for unwary code; in step 4 finalizers are run for all objects, even those that are still rooted, and there is no defined order in which these are called. This means that some portion of the runtime may be unavailable for use, like remoting, web services, etc., so some code may expect services to exist when in fact they are unavailable.&lt;br&gt;&lt;br&gt;So here's my take on this: low-level code in components should not call an exit method just because it hit an unexpected condition. This is a policy decision that the application itself should make. This is especially true for applications that host multiple appdomains; it's bad practice for a problem in appdomain1 to cause all appdomains to be unexpectedly dumped. It would be better for the application to have a method that components can call to signal this condition (fatal error) and let the application decide what it wants to do; it can still shutdown the app, but perhaps in a more orderly fashion (unload all appdomains before exiting, cleanup critical operations, etc), or it can choose to only shutdown the offending appdomain. There should always be a backstop shutdown policy; e.g. start a watchdog and force an unload if it times out.&lt;br&gt;&lt;br&gt;I completely agree that code should not run while global invariants are invalid and that a fail-safe is necessary, the question is how should a managed application 1) make the decision to unload the entire process, and 2) how the unload process be initiated.&lt;br&gt;&lt;br&gt;Here's another problem; if any component anywhere can cause a system shutdown then how do testers go about testing all the possible permutations that can occur? Will open files be left open? Databases corrupted due to partially completed transactions? etc. &lt;br&gt;&lt;br&gt;Dave&lt;br&gt;</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#76371</link><pubDate>Thu, 19 Feb 2004 19:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:76371</guid><dc:creator>Michael Grier [MSFT]</dc:creator><description>Bunch of misconceptions here:&lt;br&gt;&lt;br&gt;1. The contract for (most) native APIs in Windows is that you may not catch any exceptions which propagate through the native API call frame.  Yes, some people do it and sometimes it works but often it doesn't and when it doesn't, it won't get fixed.  There are native APIs which have made code changes so that you can catch exceptions which pass through them but these are vastly in the minority and I won't name them on principle.&lt;br&gt;&lt;br&gt;2. If you can't deal with process termination, you have a bug in your code.  There are many user mode conditions which will immediately and unilaterally terminate the process which you cannot easily guard against.  (Easy case is touching your thread guard page without resetting it.)&lt;br&gt;&lt;br&gt;3. There is great internal debate about the utility of app domains.  The debate goes something like this: &amp;quot;if all the code is managed and well mannered, app domains are sufficient&amp;quot; vs. &amp;quot;except for the cases in the real world where they aren't.  Being in the same process is an optimization which needs to be dialable.&amp;quot;&lt;br&gt;&lt;br&gt;This isn't meant to be a CLR issue.  This is a generic programming one.  The CLR has the notable problem that since there are no throw specifications, no reference returning members (I don't know if they even have reference types per se in the C++ sense), no conventions around the use of a non-throwing primitive like swap() etc. it's subject to some basic correctness limitations.  But the same is true of most of these modern higher level languages which haven't yet been used to run critical software in stressful environments.&lt;br&gt;&lt;br&gt;The whole point actually of this thread of issues is that in the move towards higher level programming we seem to have forgotten or lost some of the basics.&lt;br&gt;</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#78304</link><pubDate>Mon, 23 Feb 2004 16:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:78304</guid><dc:creator>Jay Krell</dc:creator><description>Cool, CResetter, you don't need the Disarm calls though, what you do is in the destructor you check if an exception is going by, I forget the standard library function that tells you this, and based on it you do the rollback or not (rollback if there is an exception, do nothing if there isn't an exception).</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#94086</link><pubDate>Mon, 22 Mar 2004 23:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:94086</guid><dc:creator>James</dc:creator><description>I think you're cheating to make this look a lot harder than it is: you've cleverly avoided giving us all the details, to try and lull us into thinking we're still able to write meaningful code. &lt;br&gt;&lt;br&gt;Let's make some reasonable assumptions and try again... after all, you were able to implement CResetter, so we know that at least some operations have safe and well-defined behaviour; besides, the problem wouldn't be solvable otherwise.&lt;br&gt;&lt;br&gt;What's wrong with:&lt;br&gt;&lt;br&gt;void CFoo::Bar()&lt;br&gt;{&lt;br&gt;  CObject&amp;amp; rElem1 = m_array1[m_i];&lt;br&gt;  CObject&amp;amp; rElem2 = m_array2[m_j];&lt;br&gt;  rElem1 = rElem2 = null;&lt;br&gt;  ++m_i;&lt;br&gt;  ++m_j;&lt;br&gt;}&lt;br&gt;&lt;br&gt;If only the subscript operation can throw and it's a non-mutating operation, we can do them first. If the assignments can go wrong, I'd like to see your CResetter implementation... we can always use the same technique here. If integer overflow is an issue, even when the subscript operator would succeed, check for that up front.&lt;br&gt;&lt;br&gt;Presumably, these members have invariants maintained by your class, so there's something your not telling us: is overflow a realistic case? Do we need to do anything to maintain the invariants here? Is any of the code correct if those invariants don't hold? &lt;br&gt;&lt;br&gt;If you find some real code that's this hard, think about the design a bit more.&lt;br&gt;</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#94139</link><pubDate>Tue, 23 Mar 2004 00:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:94139</guid><dc:creator>Michael Grier [MSFT]</dc:creator><description>Integer overflow is the next round of exploitable security bugs as evidenced by some of the recent security bullitins(sp?).&lt;br&gt;&lt;br&gt;So you're still stuck.  I agree that CResetter had to make a copy of the value; maybe there's an even more clever solution which involves a single construction of a value in the CResetter and then a Swap (and a Swap in the destructor).&lt;br&gt;&lt;br&gt;I'm actually more optimistic for C++ here than the other exception-friendly languages because C++ has (a) deterministic finalization and (b) reference types.  Reference types seem to be the real key here to being able to do anything.&lt;br&gt;&lt;br&gt;One might argue that exception specifications are the final key for utility but the problem is that while necessary, they are not sufficient to demonstrate that you have done the proper level of unwinding based on all your potential error-exit paths.  they tend to lead to big try/catch blocks to make the compiler quiet rather than encouraging higher quality code.&lt;br&gt;&lt;br&gt;</description></item><item><title>re: catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#94777</link><pubDate>Tue, 23 Mar 2004 22:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:94777</guid><dc:creator>James</dc:creator><description>Hm, I didn't mean to suggest that integer overflow wasn't a bug - I've read a lot on that subject, including your prior blog entry and the recent MSDN article at &lt;a target="_new" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncode/html/secure01142004.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncode/html/secure01142004.asp&lt;/a&gt; (which has good content but attrocious code that will likely introduce more subtle security bugs - for example, overloading operator&amp;amp;&amp;amp; will prevent short-circuit evaluation and could be fatal if the programmer used some variant of 'if (p &amp;amp;&amp;amp; p-&amp;gt;foo)' involving SafeInts).&lt;br&gt;&lt;br&gt;I guess that I agree with you that programming is hard, but look at it from a different angle: if you make sure you know enough about what you're writing before you start, it becomes a lot easier.</description></item><item><title>re: Erroneous assumptions</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#108528</link><pubDate>Tue, 06 Apr 2004 20:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:108528</guid><dc:creator>Larry Osterman's WebLog</dc:creator><description /></item><item><title>re: Cleaner, more elegant, and wrong</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#118694</link><pubDate>Fri, 23 Apr 2004 07:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:118694</guid><dc:creator>The Old New Thing</dc:creator><description /></item><item><title>Exception Handling is hard...OK...now what?</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#121647</link><pubDate>Wed, 28 Apr 2004 03:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:121647</guid><dc:creator>JIS</dc:creator><description /></item><item><title>re: Structured Exception Handling Considered Harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#228172</link><pubDate>Sat, 11 Sep 2004 07:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:228172</guid><dc:creator>Larry Osterman's WebLog</dc:creator><description /></item><item><title>Exception Handling is hard...OK...now what?</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#249317</link><pubDate>Fri, 29 Oct 2004 02:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:249317</guid><dc:creator>JIS</dc:creator><description /></item><item><title>Dean - Integer Overflows: The Next Big Thing</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#617833</link><pubDate>Mon, 05 Jun 2006 14:03:55 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:617833</guid><dc:creator>Dean - Integer Overflows: The Next Big Thing</dc:creator><description>PingBack from &lt;a rel="nofollow" target="_new" href="http://codeka.com/blogs/index.php/dean/2006/06/05/integer_overflows_the_next_big_thing"&gt;http://codeka.com/blogs/index.php/dean/2006/06/05/integer_overflows_the_next_big_thing&lt;/a&gt;</description></item><item><title>On C++ Error Handling by sengelha () | LjSEEK.COM</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#746090</link><pubDate>Fri, 08 Sep 2006 13:05:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:746090</guid><dc:creator>On C++ Error Handling by sengelha () | LjSEEK.COM</dc:creator><description>PingBack from &lt;a rel="nofollow" target="_new" href="http://www.ljseek.com/on-c-error-handling_13761091.html"&gt;http://www.ljseek.com/on-c-error-handling_13761091.html&lt;/a&gt;</description></item><item><title>Cars &amp;raquo; Larry Osterman&amp;#8217;s WebLog : Structured Exception Handling Considered Harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#6906266</link><pubDate>Sun, 30 Dec 2007 10:56:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6906266</guid><dc:creator>Cars » Larry Osterman’s WebLog : Structured Exception Handling Considered Harmful</dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://cars.oneadayvitamin.info/?p=650"&gt;http://cars.oneadayvitamin.info/?p=650&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Famous Birthdays  &amp;raquo; Blog Archive   &amp;raquo; Larry Osterman&amp;#8217;s WebLog : Structured Exception Handling Considered Harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#6986928</link><pubDate>Sat, 05 Jan 2008 08:01:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6986928</guid><dc:creator>Famous Birthdays  » Blog Archive   » Larry Osterman’s WebLog : Structured Exception Handling Considered Harmful</dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://birthdays.247blogging.info/?p=515"&gt;http://birthdays.247blogging.info/?p=515&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>Famous Peoples Birthdays &amp;raquo; mgrier&amp;#8217;s WebLog : catch considered harmful</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#8414802</link><pubDate>Mon, 21 Apr 2008 18:20:02 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8414802</guid><dc:creator>Famous Peoples Birthdays &amp;raquo; mgrier&amp;#8217;s WebLog : catch considered harmful</dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://famouspeoplesbirthdayblog.info/mgriers-weblog-catch-considered-harmful/"&gt;http://famouspeoplesbirthdayblog.info/mgriers-weblog-catch-considered-harmful/&lt;/a&gt;&lt;/p&gt;
</description></item><item><title> mgrier s WebLog catch considered harmful | pool toys</title><link>http://blogs.msdn.com/mgrier/archive/2004/02/18/75324.aspx#9774384</link><pubDate>Thu, 18 Jun 2009 11:44:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9774384</guid><dc:creator> mgrier s WebLog catch considered harmful | pool toys</dc:creator><description>&lt;p&gt;PingBack from &lt;a rel="nofollow" target="_new" href="http://pooltoysite.info/story.php?id=5932"&gt;http://pooltoysite.info/story.php?id=5932&lt;/a&gt;&lt;/p&gt;
</description></item></channel></rss>