Skip to content

Commit

Permalink
SKA-419: Fixed stack overflow exception & improved exception handling
Browse files Browse the repository at this point in the history
* Fixed a possible StackOverflow exception if an FMU returns a discard or error status code
* Fixed a possible stall of the SIL Kit component if the FMU component terminates unexpectedly
* Added more meaningful exit codes and documented them
  * 0 indicates success
  * 1xxx indicates an issue in the FMU Importer
  * 2xxx indicates an issue in the FMI binding
  * 3xxx indicates an issue in the SIL Kit binding
* Cleaned up exception logging behavior
  * The exception message is logged at an 'Error' level
  * The entire exception including its stack trace is logged at the 'Debug' level
  • Loading branch information
DominikHerr committed Mar 21, 2024
1 parent b5f8dcb commit 3dc1992
Show file tree
Hide file tree
Showing 21 changed files with 633 additions and 155 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ The format is based on `Keep a Changelog (http://keepachangelog.com/en/1.0.0/) <

* Added a configuration file schema ``FmuImporterConfiguration.schema.json`` for the FMU Importer and included it in release package and extended documentation how to use it

### Changed

* Changed exception logging behavior
* The exception message is logged at the `Error` log level
* The entire exception including its stack trace is logged at the `Debug` log level
* Added more meaningful exit codes and documented them
* 0 indicates success
* 1xxx indicates an issue in the FMU Importer
* 2xxx indicates an issue in the FMI binding
* 3xxx indicates an issue in the SIL Kit binding

### Fixed

* Fixed configuration of boolean parameters via config file
Expand All @@ -19,6 +30,8 @@ The format is based on `Keep a Changelog (http://keepachangelog.com/en/1.0.0/) <
* Improved documentation regarding the configuration file
* Adapted the documentation's table of contents to indicate more explicitly where to find information on how to configure the FMU (including the parameter values)
* The documentation now correctly states that there are prebuilt packages and the requirements to run them
* Fixed a possible StackOverflow exception if an FMU returns a discard or error status code
* Fixed a possible stall of the SIL Kit component if the FMU component terminates unexpectedly

---

Expand Down
72 changes: 58 additions & 14 deletions FmuImporter/FmiBridge/Binding/Fmi2Binding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public Fmi2Binding(string fmuPath) : base(fmuPath, OsPath)

private void ReleaseUnmanagedResources()
{
if (CurrentState != States.Freed)
if (CurrentState != InternalFmuStates.Freed)
{
try
{
Expand Down Expand Up @@ -269,34 +269,74 @@ internal override void SetValue(Variable mdVar, byte[] data)
}
}

SetReal(new[] { mdVar.ValueReference }, new[] { value });
SetReal(
new[]
{
mdVar.ValueReference
},
new[]
{
value
});
return;
}
case VariableTypes.Int32:
{
var value = BitConverter.ToInt32(data);
SetInteger(new[] { mdVar.ValueReference }, new[] { value });
SetInteger(
new[]
{
mdVar.ValueReference
},
new[]
{
value
});
return;
}
case VariableTypes.Boolean:
{
var value = BitConverter.ToBoolean(data);
SetBoolean(new[] { mdVar.ValueReference }, new[] { value });
SetBoolean(
new[]
{
mdVar.ValueReference
},
new[]
{
value
});
return;
}
case VariableTypes.String:
{
var byteLength = BitConverter.ToInt32(data, 0);
// offset = 4 byte -> 32 bit
var value = Encoding.UTF8.GetString(data, 4, byteLength);
SetString(new[] { mdVar.ValueReference }, new[] { value });
SetString(
new[]
{
mdVar.ValueReference
},
new[]
{
value
});
return;
}
case VariableTypes.EnumFmi2:
{
var value = BitConverter.ToInt32(data);

SetInteger(new[] { mdVar.ValueReference }, new[] { value });
SetInteger(
new[]
{
mdVar.ValueReference
},
new[]
{
value
});
return;
}
default:
Expand Down Expand Up @@ -382,7 +422,7 @@ public void Instantiate(
throw new NullReferenceException("Failed to create an FMU instance.");
}

CurrentState = States.Instantiated;
CurrentState = InternalFmuStates.Instantiated;
}

/*
Expand Down Expand Up @@ -411,7 +451,7 @@ private delegate IntPtr fmi2InstantiateTYPE(
public override void FreeInstance()
{
_fmi2FreeInstance(_component);
CurrentState = States.Freed;
CurrentState = InternalFmuStates.Freed;
}

/*
Expand Down Expand Up @@ -461,7 +501,7 @@ public void EnterInitializationMode()
_fmi2EnterInitializationMode(_component),
System.Reflection.MethodBase.GetCurrentMethod()?.MethodHandle);

CurrentState = States.InitializationMode;
CurrentState = InternalFmuStates.InitializationMode;
}

/*
Expand All @@ -478,7 +518,7 @@ public void ExitInitializationMode()
_fmi2ExitInitializationMode(_component),
System.Reflection.MethodBase.GetCurrentMethod()?.MethodHandle);

CurrentState = States.StepMode;
CurrentState = InternalFmuStates.StepMode;
}

/*
Expand All @@ -492,23 +532,27 @@ public void ExitInitializationMode()

public override void Terminate()
{
if (CurrentState == States.Terminated)
if (CurrentState is InternalFmuStates.Terminated or InternalFmuStates.TerminatedWithError)
{
// skip termination
return;
}

try
{
CurrentState = States.Terminated;
CurrentState = InternalFmuStates.Terminated;
ProcessReturnCode(
_fmi2Terminate(_component),
System.Reflection.MethodBase.GetCurrentMethod()?.MethodHandle);
}
catch (Exception e)
{
Log(LogSeverity.Error, "Terminate encountered an error:" + e);
Environment.ExitCode = e.HResult;
Log(LogSeverity.Error, "Terminate encountered an error:" + e.Message);
Log(LogSeverity.Debug, "Terminate encountered an error:" + e);
if (Environment.ExitCode == ExitCodes.Success)
{
Environment.ExitCode = ExitCodes.FmuFailedToTerminate;
}
}
}

Expand Down
Loading

0 comments on commit 3dc1992

Please sign in to comment.