You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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:
or e.g. asserts in the interpreter.
How to reproduce
Run code provided in description
Expected behaviour
No response
Screenshots
No response
Aditional information
No response
The text was updated successfully, but these errors were encountered:
I found that if we don't attach an extension method directly to the delegate but through an indirect static method, everything seems to work fine.
Working code:
publicclassProgram{staticMyCollectioncollection;publicstaticvoidMain(){
Thread.Sleep(5000);collection=new MyCollection();ContainsElementsIsNotEmpty= Wrapper;while(true){if(IsNotEmpty()){
Console.WriteLine($"collection has {collection.Count} elements");}else{
Console.WriteLine("collection is empty");}}}staticboolWrapper(){return collection.HasElements();}}
This may suggest a problem already at the time of assigning the method to the delegate.
At the same time, I'm afraid that the fact that this code with a workaround does not cause problems right away, but it may explode in other situations.
but extension methods are also static methods that can be called as if they were instance methods of a different type.
For example, static void M(this string s) can be called from any string, such as "abc".M().
Maybe that's where the problem is. When assigning a method to a delegate, it really shouldn't take any parameters, but the extension method takes one parameter.
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:
Running this on a real device looks like the first 3 iterations will work and the next one throws an exception:
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)
.
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:
or e.g. asserts in the interpreter.
How to reproduce
Run code provided in description
Expected behaviour
No response
Screenshots
No response
Aditional information
No response
The text was updated successfully, but these errors were encountered: