I’ve been having some problems with TFumiliMinimizer.
I have a defined ROOT::Math::FitMethodFunction, with 70 parameters. I create a minimizer and set it:
fMinimizer = ROOT::Math::Factory::CreateMinimizer("Fumili");
fMinimizer->NDim() gives 70, as expected.
I then try to to call SetLimitedVariable to define my variables, with the name argument as a std::string. This causes a segfault for my 32st variable, apparently when it tries to set the name. This name is not really any different from the others - just a standard ASCII string (alphanumeric plus spaces, hyphens and semicolons).
==19633==ERROR: AddressSanitizer: SEGV on unknown address 0x00000380026f (pc 0x000000474c32 sp 0x7fffdd0ba5e8 bp 0x7fffdd0ba620 T0)
#0 0x474c31 in __sanitizer::internal_memmove(void*, void const*, unsigned long) (/home/steve/analysis/trunk/profiling/run_fit.exe+0x474c31)
#1 0x4577d3 in __interceptor_memmove (/home/steve/analysis/trunk/profiling/run_fit.exe+0x4577d3)
#2 0x7f20549f9ca6 in TString::Replace(int, int, char const*, int) /home/steve/packages/root/v5_34_18_symbols_clang/core/base/src/TString.cxx:971
#3 0x7f20549f9e84 in TString::operator=(char const*) /home/steve/packages/root/v5_34_18_symbols_clang/core/base/src/TString.cxx:265
#4 0x7f204463eecf in TFumili::SetParameter(int, char const*, double, double, double, double) /home/steve/packages/root/v5_34_18_symbols_clang/math/fumili/src/TFumili.cxx:1657
#5 0x7f2044642c1d in TFumiliMinimizer::SetLimitedVariable(unsigned int, std::string const&, double, double, double, double) /home/steve/packages/root/v5_34_18_symbols_clang/math/fumili/src/TFumiliMinimizer.cxx:439[/code]
For some reason the signature says it needs a const string& (a reference). Inside that function it just calls TFumiliMinimizer::SetParameter using your string&'s c_str() method, which is a const char *. It looks like ultimately the parameter name is stored in the object as a TString *. So everything is a long line of references and pointers, never making a copy of your original name.
My guess is that your variable name std::string is going out of scope and that the references/pointers are left referring and pointing to the memory where your string used to be. Something like strings on the stack in a loop or function which are destroyed while the TFumiliMinimizer still needs them.
If that’s the case, I would call that bad design in TFumiliMinimizer, as it’s obvious that a user might not want to manually handle the memory management of the parameter names. Again, if my guess is correct, I have two ideas for solutions:
leak the strings using “new”. Instead of std::string varname = “foo”, use std::string * varname = new std::string(“foo”); and pass the dereferenced pointer. This is very ROOTish, and leads to memory leaks, but that’s the point: that memory will always have those strings in it and not be invalidated.
keep a list of the parameter names in memory for as long as the TFumiliMinimizer lives. Create an std::vectorstd::string that holds all the names, and make sure the lifetime of this vector is the same as the Minimizer.
It’s very possible that my guess is incorrect and that your seg fault is from something else, but it’s something to try while you wait for a real expert to help.
Thanks for the response. I’ve tried your suggestions, and they do not resolve the issue. I did manage to get a few more parameters into the object this time (crashed on param #56), but the issue is essentially the same:
#5 __memmove_ssse3_back () at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:2411
#6 0x00007f036aa0e4c2 in TString::Replace(int, int, char const*, int) () from /home/steve/packages/root/v5_34_18/lib/libCore.so.5.34
#7 0x00007f03607c2689 in TFumili::SetParameter(int, char const*, double, double, double, double) () from /home/steve/packages/root/v5_34_18/lib/libFumili.so
#8 0x00007f03607c803b in TFumiliMinimizer::SetLimitedVariable(unsigned int, std::string const&, double, double, double, double) () from /home/steve/packages/root/v5_34_18/lib/libFumili.so
I think there is something more devious at work here.