开发者

When is a try catch not a try catch?

I have a fun issue where during application shutdown, try / catch blocks are being seemingly ignored in the stack.

I don't have a working test project (yet due to deadline, otherwise I'd totally try to repro this), but consider the following code snippet.

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        return Run(index);
    }
    catch(IndexNotFoundException e)
    {
         if(doThrow)
             throw;
    }
    return "";
}

public static string Run(int index)
{
    if(_store.Contains(index))
        return _store[index];
    throw new IndexNotFoundExceptio开发者_开发技巧n ();
}

public static string RunAndIgnoreThrow(int index)
{
    try
    {
        return Run(index);
    }
    catch(IndexNotFoundException e)
    {
    }
    return "";
}

During runtime this pattern works famously. We get legacy support for code that relies on exceptions for program control (bad) and we get to move forward and slowly remove exceptions used for program control.

However, when shutting down our UI, we see an exception thrown from "Run" even though "doThrow" is false for ALL current uses of "RunAndPossiblyThrow". I've even gone so far as to verify this by modifying code to look like "RunAndIgnoreThrow" and I'll still get a crash post UI shutdown.

Mr. Eric Lippert, I read your blog daily, I'd sure love to hear it's some known bug and I'm not going crazy.

EDIT This is multi-threaded, and I've verified all objects are not modified while being accessed

EDIT Explicitly show exception is ours

EDIT forgot to mention, this is on closing, and unfortunately visual studio cannot catch the crash directly. It's likely crashing on a thread other than the UI thread, and once the main closes, this closes. I've only been able to debug this by repeatedly running & closing the application, with task manager open, "Create Dump File" and looking at the resulting 400+mb mess in Windbg. Win7 64 for reference. Make sure this makes sense to you.

EDIT

The following code on shutdown still shows the same exception.

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        return Run(index);
    }
    catch
    {
    }
    return "";
}

public static string Run(int index)
{
    if(_store.Contains(index))
        return _store[index];
    throw new IndexNotFoundException ();
}

The only thing that seems to get rid of the exception is to go straight to

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        return Run(index);
    }
    catch
    {
    }
    return "";
}

public static string Run(int index)
{
    if(_store.Contains(index))
        return _store[index];
    return "";
}

Naturally the exception's gone, but my fears of going crazy are still present.

EDIT

it just got worse... this still crashes...

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        throw new IndexNotFoundException();
    }
    catch
    {
    }
    return "";
}

EDIT I have a distinct feeling this is going to get me nowhere. On top of the wierd behavior, I can also note that during execution of the UI in the above case, the try catch is being executed faithfully. My UI doesn't crash & it's full of empty strings. However once I start closing the UI, the crash shows itself and the try catch no longer holds back the exception.

EDIT & final Apparently the dump file was listing in it the most recent first-chance exception. I verified this by creating a new project that threw inside a try catch & slept for 10 seconds. During the wait I got the .dmp file & sure enough, my completely caught exception was showing up.

I'll mark some points for the useful answers, however unfortunately there's still no rhyme or reason why my code is crashing...


Add an Exception as an extra catch. I think you are getting some other exception than ApplicationException and that is the one crashing your app.


There are various exceptions that cannot be caught. Stack Overflow in particular! Could one of these be occurring somewhere in your code?

See http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx


Have you tried adding a "finally" clause? just to see if it won't ignore the try/catch completely? In theory it should always jump to that line before it exits the try/catch no matter what.

If it still ignore that then there is something definitely strange about it.


Probably you catch and throw again some other exception from Run. Probably _store is null or something.


A few things that may help with diagnosis:

  • Register for AppDomain.CurrentDomain.UnhandledException so you can see if something is crashing on a thread other than the UI thread

  • Register for Application.ThreadException to catch any exceptions not being caught in the UI thread

  • Since this is happening during shutdown, are you using any Finalizers that could be throwing on the finalizer thread?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜