viproma/cppfmu

Segmentation fault when freeing the instance in pyfmi before exiting

fcollonval opened this issue · 3 comments

I discover this wrapper through PythonFMU.

But I successfully reproduce my error using the spring_1d example. I got a Segmentation fault when closing Python after loading the FMU through pyfmi.

A question:

cppfmu/fmi_functions.cpp

Lines 93 to 100 in b0e71f3

void fmiFreeSlaveInstance(fmiComponent c)
{
const auto component = reinterpret_cast<Component*>(c);
// The Component object was allocated using cppfmu::AllocateUnique(),
// which uses cppfmu::New() internally, so we use cppfmu::Delete() to
// release it again.
cppfmu::Delete(component->memory, component);
}

The component is explicitly deleted here. But I don't see anything similar for the slave is it normal?

Environment

OS: Linux debian 4.19.0-6-amd64 Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64 GNU/Linux
conda environment:

# packages in environment at /home/fcollonval/miniconda3/envs/fmut:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       0_gnu    conda-forge
assimulo                  3.1              py38h64b6ff1_2    conda-forge
attrs                     19.3.0                     py_0    conda-forge
binutils_impl_linux-64    2.33.1               h53a641e_8    conda-forge
binutils_linux-64         2.33.1              h9595d00_15    conda-forge
boost                     1.70.0           py38h9de70de_1    conda-forge
boost-cpp                 1.70.0               h8e57a91_2    conda-forge
bzip2                     1.0.8                h516909a_2    conda-forge
ca-certificates           2019.11.28           hecc5488_0    conda-forge
certifi                   2019.11.28               py38_0    conda-forge
fmilib                    2.0.3             he1b5a44_1002    conda-forge
gcc_impl_linux-64         7.3.0                hd420e75_4    conda-forge
gcc_linux-64              7.3.0               h553295d_15  
gxx_impl_linux-64         7.3.0                hdf63c60_4    conda-forge
gxx_linux-64              7.3.0               h553295d_15  
icu                       64.2                 he1b5a44_1    conda-forge
importlib_metadata        1.5.0                    py38_0    conda-forge
inflect                   4.0.0                    py38_1    conda-forge
jaraco.itertools          5.0.0                      py_0    conda-forge
ld_impl_linux-64          2.33.1               h53a641e_8    conda-forge
libblas                   3.8.0               14_openblas    conda-forge
libcblas                  3.8.0               14_openblas    conda-forge
libffi                    3.2.1             he1b5a44_1006    conda-forge
libgcc-ng                 9.2.0                h24d8f2e_2    conda-forge
libgfortran-ng            7.3.0                hdf63c60_4    conda-forge
libgomp                   9.2.0                h24d8f2e_2    conda-forge
libiconv                  1.15              h516909a_1005    conda-forge
liblapack                 3.8.0               14_openblas    conda-forge
libopenblas               0.3.7                h5ec1e0e_6    conda-forge
libstdcxx-ng              9.2.0                hdf63c60_2    conda-forge
libxml2                   2.9.10               hee79883_0    conda-forge
libxslt                   1.1.33               h31b3aaa_0    conda-forge
lxml                      4.4.2            py38h7ec2d77_0    conda-forge
metis                     5.1.0             he1b5a44_1005    conda-forge
more-itertools            8.1.0                      py_0    conda-forge
ncurses                   6.1               hf484d3e_1002    conda-forge
numpy                     1.17.5           py38h95a1406_0    conda-forge
openssl                   1.1.1d               h516909a_0    conda-forge
packaging                 20.1                       py_0    conda-forge
pip                       20.0.2                   py38_0    conda-forge
pluggy                    0.13.1                   py38_0    conda-forge
py                        1.8.1                      py_0    conda-forge
pyfmi                     2.5.7            py38hc1659b7_0    conda-forge
pyparsing                 2.4.6                      py_0    conda-forge
pytest                    5.3.4                    py38_0    conda-forge
python                    3.8.1                h357f687_1    conda-forge
pythonfmu                 0.2.0                     dev_0    
readline                  8.0                  hf8c457e_0    conda-forge
scipy                     1.4.1            py38h921218d_0    conda-forge
setuptools                45.1.0                   py38_0    conda-forge
six                       1.14.0                   py38_0    conda-forge
sqlite                    3.30.1               hcee41ef_0    conda-forge
suitesparse               5.6.0                h717dc36_0    conda-forge
sundials                  5.1.0                h0186668_0    conda-forge
tbb                       2019.9               hc9558a2_1    conda-forge
tk                        8.6.10               hed695b0_0    conda-forge
wcwidth                   0.1.8                      py_0    conda-forge
wheel                     0.34.1                   py38_0    conda-forge
xz                        5.2.4             h14c3975_1001    conda-forge
zipp                      2.1.0                      py_0    conda-forge
zlib                      1.2.11            h516909a_1006    conda-forge

Steps to reproduce

  1. Compile on the conda environment, the demo-fmus repository (commit e5f04e79fce0949984b81361218108b5d964b278)
  2. Zip the spring_1d folder to get a FMU
  3. Start the python console
  4. Execute the FMU
from pyfmi import load_fmu
m = load_fmu('/path/to/spring_1d.fmu')
res = m.simulate(0, 1)
m.free_instance()
exit()

A Segmentation fault is raised when the Python console closes.

Expected behavior

No Segmentation fault occurs

Thank you for your bug report!

I don't recall this ever being an issue when running CPPFMU-based FMUs in other simulation tools, so I suspect that it may be a problem with PyFMI. I suppose it calls fmiFreeSlaveInstance() when you call m.free_instance(), but since the segmentation fault only happens when you exit the console, I suspect it calls fmiFreeSlaveInstance() one more time then. If that is the case, a segmentation fault is just what I'd expect.

But I will install PyFMI and look into it myself just to be sure.

Loading PythonFMU and FMI4j exported FMUs (both of which uses cppfmu) in FMPy also produces a segmentation fault. But I can't say who's to blame. FMPy, together with fmilib, is perhaps the most utilized FMI library out there so It might be either my use of cppfmu in the affected tools or cppfmu itself.

@kyllingstad you are right. I check that without calling free_instance, the segmentation fault does not appear for the spring_1d example.

from pyfmi import load_fmu
m = load_fmu('/path/to/spring_1d.fmu')
res = m.simulate(0, 1)
exit()

So I close this one as this is related to pyfmi behavior.

@markaren Unfortunately the segmentation fault arises when I'm using a FMU package with PythonFMU.