Opened 6 years ago
Last modified 6 years ago
#5196 new defect
Memory leak with inline arrays in when clauses
Reported by: | Owned by: | Lennart Ochel | |
---|---|---|---|
Priority: | high | Milestone: | Future |
Component: | FMI | Version: | v1.13.0-dev-nightly |
Keywords: | leak | Cc: |
Description
It seems there is a memory leak reproducible with a simple array defined inline in a while clause. I cannot say for sure, since it goes through the memory pool logic, but both valgrinding the FMUChecker with this FMU and looking at the generated source code suggest that the memory for this array is allocated but never freed.
How to reproduce
- Take these files:
TestAllTrue.mo:
model TestAllTrue input Boolean x, y, z; output Boolean res; equation when Modelica.Math.BooleanVectors.allTrue({x, y, z}) then res = true; end when; end TestAllTrue;TestAllTrue.mos:
print(buildModelFMU(TestAllTrue, "1.0", "me")); print(getErrorString());
- Compile it with
omc TestAllTrue.mos Modelica TestAllTrue.mo
- Run under Valgrind with
mkdir -p /tmp/fmu # So valgrind can show symbols from .so-file from FMU valgrind --leak-check=full --show-leak-kinds=all ~/tmp/FMUChecker-2.0.3/build/fmuCheck.linux64 -z /tmp/fmu -h 0.01 -s 10000 -o /dev/null TestAllTrue.fmu
Among other, it will print
==32160== 29,360,128 bytes in 3 blocks are still reachable in loss record 24 of 24 ==32160== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==32160== by 0x6C645EE: pool_malloc (in /tmp/fmu/binaries/linux64/TestAllTrue.so) ==32160== by 0x6C58383: array_alloc_scalar_boolean_array (in /tmp/fmu/binaries/linux64/TestAllTrue.so) ==32160== by 0x6C55301: TestAllTrue_eqFunction_4 (in /tmp/fmu/binaries/linux64/TestAllTrue.so) ==32160== by 0x6C55869: TestAllTrue_functionAlgebraics (in /tmp/fmu/binaries/linux64/TestAllTrue.so) ==32160== by 0x6C54FDC: TestAllTrue_fmiCompletedIntegratorStep (in /tmp/fmu/binaries/linux64/TestAllTrue.so) ==32160== by 0x40C689: fmi1_me_simulate (in /home/trosinenko/tmp/FMUChecker-2.0.3/build/fmuCheck.linux64) ==32160== by 0x40B99C: fmi1_check (in /home/trosinenko/tmp/FMUChecker-2.0.3/build/fmuCheck.linux64) ==32160== by 0x408934: main (in /home/trosinenko/tmp/FMUChecker-2.0.3/build/fmuCheck.linux64)this suggests where the leak is
- Running the same command without Valgrind but with
/usr/bin/time
(not built-intime
frombash
) shows thatwith -s 10000 option -> 20536maxresident k with -s 1000000 option -> 1567340maxresident k
this suggests that leak really exists :)
Analysis
Unpack the generated FMU and look at TestAllTrue.c:
/* equation index: 4 type: SIMPLE_ASSIGN $whenCondition1 = Modelica.Math.BooleanVectors.allTrue({x, y, z}) */ void TestAllTrue_eqFunction_4(DATA *data, threadData_t *threadData) { TRACE_PUSH const int equationIndexes[2] = {1,4}; boolean_array tmp0; array_alloc_scalar_boolean_array(&tmp0, 3, (modelica_boolean)data->localData[0]->booleanVars[2] /* x variable */, (modelica_boolean)data->localData[0]->booleanVars[3] /* y variable */, (modelica_boolean)data->localData[0]->booleanVars[4] /* z variable */); data->localData[0]->booleanVars[0] /* $whenCondition1 DISCRETE */ = omc_Modelica_Math_BooleanVectors_allTrue(threadData, tmp0); TRACE_POP }
Looks like array_alloc_scalar_boolean_array
was called but corresponding ..._free_...
was not.
This was tested with FMU ME 1.0 and FMUChecker 2.0.3
Change History (2)
comment:1 by , 6 years ago
comment:2 by , 6 years ago
#5406 is the same bug. You just need to free the pool at some intervals like the regular simulations do.
This seems to be reproducible without events:
Is there any
free_*_array_data(...)
function implementations anywhere? I see onlyextern
declarations in thesources/include/util/boolean_array.h
inside unzipped FMU. On the other hand, it seems that simulation executable uses bounded amount of memory (or I run it incorrectly).