#6125 closed defect (fixed)
Don't throw / assert / abort inside FMUs
Reported by: | Andreas Heuermann | Owned by: | Andreas Heuermann |
---|---|---|---|
Priority: | critical | Milestone: | 1.16.0 |
Component: | FMI | Version: | v1.16.0-dev |
Keywords: | fmi, fmu, assert, throw, abort | Cc: |
Description
When an error occurs inside an OpenModelica FMU we should return the appropriate FMI error code and don't throw an error / abort.
For example an FMU that has an equation with a square root will call throwStreamPrintWithEquationIndexes
if the argument for sqrt is negative.
But for instance this error is recoverable. Such an equation must be called by the FMU simulator multiple times, and if the evaluation failed the simulator can try with a different value. This is needed e.g. for iterative solvers for algebraic loops.
Related issue: OMSimulator Issue#808
Change History (7)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
I prefer 3: Fix the FMU functions to set the jumpers to not be NULL, and catch the errors so you can return the correct code in the FMI function call :)
I guess 2 is actually the same, but just the way you implement not making it crash.
comment:3 by , 4 years ago
The jumpers are problematic for certain industrial customers: see https://trac.openmodelica.org/OpenModelica/ticket/5965
comment:4 by , 4 years ago
I can add a try-catch block to all fmi2 functions. This would look something like this:
fmi2Status fmi2GetReal([..]) { [Variables] threadData = comp->threadData; [Check for invalid state] setThreadData(comp); #if NUMBER_OF_REALS > 0 saveJumpState = threadData->currentErrorStage; threadData->currentErrorStage = ERROR_INTEGRATOR; /* TRY */ #if !defined(OMC_EMCC) MMC_TRY_INTERNAL(simulationJumpBuffer) #endif [Stuff that normally happens] success = 1; /* CATCH */ #if !defined(OMC_EMCC) MMC_CATCH_INTERNAL(simulationJumpBuffer) #endif threadData->currentErrorStage = saveJumpState; if (!success) { FILTERED_LOG(comp, fmi2OK, LOG_FMI2_CALL, "fmi2GetReal: Catched error") return fmi2Discard; } #endif return fmi2OK; }
@lochel I think for the problem described in #5965 I can add defines with OMC_NO_THREADS
, so that it will not add more problems for that. Fixing some of the problems from #5965 along the way should be possible as well.
comment:6 by , 4 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
The PR is merged into the master. There are probably still some fmi functions left that don't catch asserts.
But I'm closing this for now. If there are more problems feel free to re-open.
There are two different approaches I could think off:
throwStreamPrintWithEquationIndexes
and similar in FMI context. But to report the error we need to change all C functions to return an FMI error code after each call and propagate it upwards. This will need a lot of changes and has a big potential to mess up a lot of code, since we share code generation for C and FMI.throwStreamPrintWithEquationIndexes
and similar to behave different inside the runtime linked to an FMU. It's not longer allowed to throw errors, but will jump / goto to some location to report the correct error code. But we have different runtimes linked in an C FMU. I think those are mainlylibSimulationRuntimeC
andlibOpenModelicaFMIRuntimeC
. So I expect to get some trouble with build dependecies and different behavior for static or dynamic linked FMUs.On both approaches is hard to differentiate what is a recoverable error (dividing by zero, sqrt of a negative number, ...) and what is not (can't allocate memory, dimensions of key components not correct, ...).
At the moment I prefer Option 2.