Mirrored as part of a study of Minetest events of 2010 to 2019 and people involved, and in connection with a related book, events in 2017 to 2018, in particular, conferring upon host legal rights related to Fair Use.

Minetest MinGW instability finally fixed. True story.

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.

2 Responses to “Minetest MinGW instability finally fixed. True story.”

  1. :( Says:

    The game is very slow and choppy! impossible to play! Geeforce 4!

  2. Freedom Says:

    Uhhm :(, my pc has 1 gb only but minetest runs perfect, no bugs no lags

Leave a Reply