#6125 closed defect (fixed)
Don't throw / assert / abort inside FMUs
Reported by: | AnHeuermann | Owned by: | AnHeuermann |
---|---|---|---|
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 Changed 4 years ago by AnHeuermann
comment:2 Changed 4 years ago by sjoelund.se
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 Changed 4 years ago by lochel
The jumpers are problematic for certain industrial customers: see https://trac.openmodelica.org/OpenModelica/ticket/5965
comment:4 Changed 4 years ago by AnHeuermann
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:5 Changed 4 years ago by AnHeuermann
comment:6 Changed 4 years ago by AnHeuermann
- Resolution set to fixed
- Status changed from new to 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.
comment:7 Changed 4 years ago by casella
- Milestone changed from 1.17.0 to 1.16.0
The fix will be available in 1.16.0
There are two different approaches I could think off:
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.