Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A callback was made on a garbage collected delegate #5

Open
Nils12345678901234567 opened this issue May 8, 2024 · 4 comments
Open

Comments

@Nils12345678901234567
Copy link

Nils12345678901234567 commented May 8, 2024

After running my simulation loop for a short while (setting inputs - AdvanceTime - reading outputs)the program crashes with this error:

Process terminated. A callback was made on a garbage collected delegate of type 'Femyou!Femyou.FMI2+fmi2StepFinished::Invoke'.
   at Femyou.Instance.AdvanceTime(Double)

Turns out that this happens when the garbage collector kicks in. If I call GC.Collect in my simulation loop I get the error immediately.

If I debug the program in Visual Studio it catches a ExecutionEngineException with no call stack.

@Oaz
Copy link
Owner

Oaz commented May 10, 2024

Can you provide a piece of code to reproduce this issue?

@Nils12345678901234567
Copy link
Author

If you modify the test LogWhenVariableCannotBeSet like this:

 [Test]
 public void LogWhenVariableCannotBeSet()
 {
     var spyCallback = new SpyCallback();
     using var model = Model.Load(TestTools.GetFmuPath("BouncingBall.fmu"));
     using var instance = model.CreateCoSimulationInstance("my name", spyCallback);
     try
     {
         GC.Collect();  // Force garbage collection here to reproduce bug
         instance.WriteReal((model.Variables["v_min"], 1));
     }

Note: The test will not fail, it will never finish execution. You have to look in the output window to see the error message.

@Nils12345678901234567
Copy link
Author

Nils12345678901234567 commented May 13, 2024

I tried to reproduce with the test FeedthroughReferenceScenario as well but that didi not work. I suspect that the 'Feedthrough.fmu' fmu never calls any callbacks. A similar test using BouncingBall.fmu would probably show the problem.

@Nils12345678901234567
Copy link
Author

Nils12345678901234567 commented May 13, 2024

If the local variable functions in the constructor of the Callbacks class is changed to a member variable of the Callbacks-class like shown below this should fix the problem.

 class Callbacks : IDisposable
 {
     private FMI2.fmi2CallbackFunctions functions;
     public Callbacks(Instance instance, ICallbacks cb)
     {
         Instance = instance;
         CB = cb;
         handle = GCHandle.Alloc(this);
         functions = new FMI2.fmi2CallbackFunctions
         {
             logger = LoggerCallback,
             allocateMemory = Marshalling.AllocateMemory,
             freeMemory = Marshalling.FreeMemory,
             stepFinished = StepFinishedCallback,
             componentEnvironment = GCHandle.ToIntPtr(handle)
         };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants