Segmentation fault when doing function expansion and unit inference after conversion to L3V2
avandecreme opened this issue · 1 comments
avandecreme commented
The following program segfault when fed the following uncompressed file
#include <stdio.h>
#include <sbml/SBMLTypes.h>
#include "util.h"
int main (int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: readSBML filename\n");
return 2;
}
const char * filename = argv[1];
SBMLDocument_t *d = readSBML(filename);
int success = SBMLDocument_setLevelAndVersion(d, 3, 2);
printf("Success: %d\n", success);
ConversionProperties_t* props;
props = ConversionProperties_create();
ConversionOption_t * expandFuncDefOpt = ConversionOption_create("expandFunctionDefinitions");
ConversionProperties_addOption(props, expandFuncDefOpt);
SBMLDocument_convert(d, props);
ConversionOption_free(expandFuncDefOpt);
ConversionProperties_free(props);
props = ConversionProperties_create();
ConversionOption_t * inferUnitsOpt = ConversionOption_create("inferUnits");
ConversionProperties_addOption(props, inferUnitsOpt);
SBMLDocument_convert(d, props);
ConversionOption_free(inferUnitsOpt);
ConversionProperties_free(props);
SBMLDocument_free(d);
}
From what I gathered, it is because tempUD1
is set to NULL
here:
libsbml/src/sbml/units/UnitFormulaFormatter.cpp
Line 2635 in 49ce5b4
The reason for that is that
inverseFunctionOnUnits
calls UnitDefinition::divide
on two UnitDefinition
s having different level and version (L2V4 like the original doc and L3V2 like the converted one), so we are falling in the following branch:libsbml/src/sbml/UnitDefinition.cpp
Line 1467 in 49ce5b4
I found two ways to avoid the crash:
- move the level/version conversion after function expansion and unit inference
- keep level/version conversion first but group function expansion and unit inference into one convert call like this:
props = ConversionProperties_create();
ConversionOption_t * expandFuncDefOpt = ConversionOption_create("expandFunctionDefinitions");
ConversionProperties_addOption(props, expandFuncDefOpt);
ConversionOption_t * inferUnitsOpt = ConversionOption_create("inferUnits");
ConversionProperties_addOption(props, inferUnitsOpt);
SBMLDocument_convert(d, props);
ConversionOption_free(expandFuncDefOpt);
ConversionOption_free(inferUnitsOpt);
ConversionProperties_free(props);
Having level/version conversion in between function expansion and unit inference also segfault.
skeating commented
Thanks very much for this. As far as I know you are the first person to have used the UnitInference since I wrote it some years ago and there may well be undiscovered issues. But thank you for the detailed report this is very helpful