Skip to content

Overflow in CalcTics causes a freeze after a few days #345

Description

@DankRank

I was playing S3DNA on steam and it froze after running for about 4 days. I gathered the following information using a debugger:

curtime = 0x1492f94f
lasttimecount = 0x0170b02b
delay = 3681400541 ms (~42.6 days)

The offending line in 1.3.3 is this one, where lasttimecount is an int32_t. That multiplication overflows after 2**31 / 100 tics (~3.6 days).

SDL_Delay(((lasttimecount + 1) * 100) / 7 - curtime);

From what I can tell this is still relevant in the master branch, though TICS2MS somewhat mitigates this by using uint32_t, making the overflow occur after 2**32 / 100 tics (~7.1 days)

SDL_Delay(TICS2MS(lasttimecount + 1) - curtime);

However, there's also this check:

ECWolf/src/wl_play.cpp

Lines 210 to 212 in 1bff92d

// Detect rollover, particularly if the game were paused for a LONG time
if(lasttimecount > GetTimeCount())
ResetTimeCount();

In vanilla this was meant to deal with a slightly different kind of rollover (TimeCount incrementing), but here it, perhaps unintentionally, manages to detect the rollover caused by 32-bit multiplication overflow in MS2TICS. It may seem that this check would also prevent an overflow in TICS2MS(lasttimecount + 1), but there's actually an edge case due to the + 1. Here's a example that, from what I can tell, would freeze the latest version of ecwolf:

curtime = 0x24924918 (the rollover is not detected until 0x24924925)
lasttimecount = 0x028f5c28
delay = 3681400552 ms (~42.6 days)

So, tl;dr, this does seem like it can happen on newer builds.

The easiest solution is to use uint64_t/SDL_GetTicks64 everywhere, since it takes millions of years to overflow.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions