Minetest has never worked reliably when built on MinGW, causing very odd memory corruption in under a minute, for which, even while having been investigated multiple times, a fix was never found.
Well, now there is a fix.
Minetest was converting strings to floats using std::istringstream. With results like these:
http://paste.dy.fi/yeY http://paste.dy.fi/ybc http://paste.dy.fi/yGZ http://paste.dy.fi/wDX http://paste.dy.fi/whn http://paste.dy.fi/Gtt http://paste.dy.fi/fKk http://paste.dy.fi/yeY http://paste.dy.fi/ybc http://paste.dy.fi/yGZ http://paste.dy.fi/fKk
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 5572.0x11b0]
0x77c3330c in msvcrt!__argc () from C:\WINDOWS\system32\msvcrt.dll
What you are seeing is basically segfaults all over the place, in Windows’ DLLs and whatnot. And…
Well, yesterday, it took me six hours of backporting patches to build old versions of Minetest under MinGW, randomly coming up with ideas, recalling past investigations and trying out things.
I found the very early commit (combined with the next one that fixes it to be buildable) (it’s actually the 4th one ever committed) that introduced the problem. Minetest has always been built using MSVC on Windows, thus it had gone unnoticed for like forever. It’s a relatively large (2800 lines of diff) but innocious-looking commit.
The commits add the VoxelManipulator class, they implement the BlockEmergeQueue and add an in-case-of-bugs triggering of the EmergeThread. The first one is not used yet. Disabling the triggering doesn’t get rid of the bug.
After trying a number of things, nothing helped.
I started to wonder if it was a MinGW incompatibility with the distributed Irrlicht.dll. Wasn’t.
…Then the multiple occurrences of Settings::getFloat in the backtraces finally catched my eye. getFloat looked like this:
float getFloat(std::string name)
{
float f;
std::istringstream vis(get(name));
vis>>f;
return f;
}
It felt complete nonsense, but I replaced the contents with some dummy code and once again started testing the thing… to find out that it did not fail.
By testing a number of things, I found out that by replacing the istringstream stuff with a simple atof() fixed the problem.
Needless to say, the same modification could be applied to the latest github master version, in a slightly different place, and it worked.
So, to fix this:
inline float mystof(std::string s)
{
float f;
std::istringstream ss(s);
ss>>f;
return f;
}
You just:
inline float mystof(std::string s)
{
return atof(s.c_str());
}
I think this might have something to do with that function being called by threaded code.
Maybe the MinGW guys should get to know this. Dunno; I won’t bother poking them though. If somebody wants to, feel free to.