Skip to content

Extension Methods and delegates problem #1326

Open
@MateuszKlatecki

Description

@MateuszKlatecki

Target name(s)

ALL

Firmware version

No response

Was working before? On which version?

No response

Device capabilities

No response

Description

For a long time, we have been seeing strange problems at random times, the source of which we could not identify. Weird assertions in Interpreter, or HardFaults in Garbage Collector during ComputeReachabilityGraph, data corruption causing strange exceptions.
Finally managed to extract a fairly short code that causes the problem:

using System;
using System.Threading;

namespace ExtensionMethodAndDelegateProblem
{
    public class Program
    {
        public static void Main()
        {
            Thread.Sleep(5000);

            MyCollection collection = new MyCollection();
            ContainsElements IsNotEmpty = collection.HasElements;
            while (true)
            {
                if (IsNotEmpty())
                {
                    Console.WriteLine($"collection has {collection.Count} elements");
                }
                else
                {
                    Console.WriteLine("collection is empty");
                }
            }
        }
    }

    public delegate bool ContainsElements();

    public class MyCollection
    {
        public int Count => 42;
    }

    public static class MyCollectionExtensions
    {
        public static bool HasElements(this MyCollection collection)
        {
            var upperLimit = collection == null ? 0 : collection.Count;
            return upperLimit > 0;
        }
    }
}

Running this on a real device looks like the first 3 iterations will work and the next one throws an exception:
image

Trying to run it in a Virtual nanoDevice throws a Stack Underflow exception (certainly here: https://github.com/nanoframework/nf-interpreter/blob/main/src/CLR/Core/CLR_RT_StackFrame.cpp#L255)
image.

Adding minor modifications to this code (e.g. adding a thread that stresses GC a lot, or modifying the MyCollection class) and running on real device, causes Hardfaults in GC:
HF in GC

or e.g. asserts in the interpreter.
ldarg0
assign_assert

How to reproduce

Run code provided in description

Expected behaviour

No response

Screenshots

No response

Aditional information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions