Bug 30478

Summary: Inner finally block not called
Product: [Mono] Compilers Reporter: Nate Cook <heavycrag>
Component: C#Assignee: Marek Safar <masafa>
Status: RESOLVED FIXED    
Severity: normal CC: masafa, mono-bugs+monotouch, mono-bugs+mono, sebastien
Priority: ---    
Version: 4.0.0   
Target Milestone: ---   
Hardware: Macintosh   
OS: Mac OS   
Tags: Is this bug a regression?: ---
Last known good build:

Description Nate Cook 2015-05-26 18:24:33 UTC
Put the following class Foo in a Sketch, or in a mobile app. (I was using Xamarin.iOS when I ran into this.) Call Foo.CallOuter();

Expected output on all platforms (Note: this is the output when running the in a console application.)
    finally in inner
    finally in Outer
    catch in CallOuter

Actual output when running in a mobile app, or in a sketch:
    catch in CallOuter
    finally in Outer

Note that the inner finally block is not called as expected.

=========================

public class Foo
{
    public void CallOuter()
    {
        try
        {
            Outer();
        }
        catch
        {
            Console.WriteLine("catch in CallOuter");
        }
    }

    void Outer()
    {
        try
        {
            Inner();
        }
        finally
        {
            Console.WriteLine("finally in Outer");
        }
    }

    void Inner()
    {
        try
        {
            throw new PlatformNotSupportedException("test exception");
        }
        catch
        {
            throw;
        }
        finally
        {
            Console.WriteLine("finally in inner");
        }
    }
}

=========================

=== Xamarin Studio ===

Version 5.9.1 (build 3)
Installation UUID: 7ce5ffa9-646f-4545-9e71-8a00bb46f696
Runtime:
	Mono 4.0.0 ((detached/d136b79)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 400000143

=== Apple Developer Tools ===

Xcode 6.3.2 (7718)
Build 6D2105

=== Xamarin.iOS ===

Version: 8.10.0.303 (Business Edition)
Hash: 3c4e832
Branch: master
Build date: 2015-05-20 21:47:57-0400

=== Xamarin.Android ===

Version: 5.1.1.0 (Business Edition)
Android SDK: /Users/ncook/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
Java SDK: /usr
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)

=== Xamarin Android Player ===

Version: Unknown version
Location: /Applications/Xamarin Android Player.app

=== Xamarin.Mac ===

Not Installed

=== Build Information ===

Release ID: 509010003
Git revision: aad75a6e7e48f18120ce41f47d0ff2c6216f49c3
Build date: 2015-05-08 12:46:18-04
Xamarin addins: 1246b3044cbb7f56a217334f8fc5489ef8eefe3f

=== Operating System ===

Mac OS X 10.10.3
Darwin NateCook-Insightly-MacBook-Pro.local 14.3.0 Darwin Kernel Version 14.3.0
    Mon Mar 23 11:59:05 PDT 2015
    root:xnu-2782.20.48~5/RELEASE_X86_64 x86_64

=========================

I wasn't really sure where to put this bug (especially since it works fine in a console application), but since I found it while I was working with an iOS app I put it here.
Comment 1 Nate Cook 2015-05-26 18:36:17 UTC
Just realized that the bug is only reproduced using the code I provided in the context of a sketch. So this bug as currently written needs to be marked as a bug with Sketches. (I originally ran into this problem with Xamarin.iOS, but the test code I provided here is not good enough because it doesn't reproduce the problem in the context of a mobile app. If I get more info I will pass it on.)
Comment 2 Sebastien Pouliot 2015-05-26 18:44:11 UTC
We can workout/move the bug across products if needed. The most important thing is to have all the information to be able to reproduce the issue.
Comment 3 Nate Cook 2015-05-26 19:04:23 UTC
Ok, I have a better example now:

==================

    public class BetterExample
    {
        public async Task Execute(Action actionToExecute)
        {
            try
            {
                await ExecuteCore(actionToExecute);
            }
            finally
            {
                Console.WriteLine("finally in ExecuteMain");
            }
        }

        private async Task ExecuteCore(Action actionToExecute)
        {
            await Task.Delay(500);

            try
            {
                await Task.Run(() => { 
                    actionToExecute();
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine("catch in ExecuteCore");

                throw;
            }
            finally
            {
                Console.WriteLine("finally in ExecuteCore");

                await Task.Delay(500);
            }
        }
    }

==================

Call it using the following code.

            var betterExample = new BetterExample();

            try
            {
                await betterExample.Execute(() => { 
                    Console.WriteLine("before exception");
                    throw new PlatformNotSupportedException("test exception");
                    Console.WriteLine("after exception");
                });
            }
            catch
            {
                Console.WriteLine("outermost catch");
            }   

==================

Note that "finally in ExecuteCore" is never printed in the application output window. Just reproduced it using that code in Xamarin.iOS.
Comment 4 Marek Safar 2015-05-28 09:46:32 UTC
Fixed in master and 4.2
Comment 5 Nate Cook 2015-05-28 16:24:22 UTC
Looking at the commit you made, looks like it was a problem with async. (Thanks for fixing it by the way.) Any thought on the sketches issue (which might be a separate bug)?
Comment 6 Marek Safar 2015-05-29 01:43:04 UTC
Best to fill different bug report against Sketch