Undefined behaviour in juce_OpenGL_osx

We run pluginval on some build nodes and on one build node, that had not been restarted for almost a month, we started to see this:

../thirdparty/juce/modules/juce_opengl/native/juce_OpenGL_osx.h:183:36: runtime error: 4.90689e+09 is outside the range of representable values of type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../thirdparty/juce/modules/juce_opengl/native/juce_OpenGL_osx.h:183:36 in 
pluginval received Abort trap: 6, exiting immediately

The code looks like this:

    void swapBuffers()
    {
        auto now = Time::getMillisecondCounterHiRes();
        [renderContext flushBuffer];

        if (minSwapTimeMs > 0)
        {
            // When our window is entirely occluded by other windows, flushBuffer
            // fails to wait for the swap interval, so the render loop spins at full
            // speed, burning CPU. This hack detects when things are going too fast
            // and sleeps if necessary.

            auto swapTime = Time::getMillisecondCounterHiRes() - now;
            auto frameTime = (int) (now - lastSwapTime); <-------- row 183

            if (swapTime < 0.5 && frameTime < minSwapTimeMs - 3)
            {
                if (underrunCounter > 3)
                {
                    Thread::sleep (2 * (minSwapTimeMs - frameTime));
                    now = Time::getMillisecondCounterHiRes();
                }
                else
                {
                    ++underrunCounter;
                }
            }
            else
            {
                if (underrunCounter > 0)
                    --underrunCounter;
            }
        }

        lastSwapTime = now;
    }

From the documentation of Time::getMillisecondCounterHiRes() :

Returns the number of millisecs since a fixed event (usually system startup).

If now is some value larger than the max value of int and lastSwapTime is 0, then the above UBSAN warning would be printed. If getMillisecondCounterHiRes returns the number of milliseconds since system startup, then this would happen after ~25 days.

It looks like restarting the machine on our side made the warning go away.

What do you think about casting to std::int64_t instead, like this:

auto frameTime = (std::int64_t) (now - lastSwapTime);

1 Like

This is one of the reasons I don’t like to see auto being used haphazardly.

Why wouldn’t you just do:

int64_t frameTime = now - lastSwapTime;

… instead casting an alias? Makes it clear what your intention is (very long wait times)…

1 Like

@reuk Ping. This should be a quick fix…

Could someone please have a look at this issue since our nightly UBSAN (undefined behaviour sanitizer) build fails after the build node’s uptime has reached approx 25 days. :pray:

It’s a bit annoying that we need to restart the build node regularly to get rid of this test failure.

Thanks for reporting, and sorry for the delay in responding. This should be fixed on develop: