std::condition_wait::wait_for and wait_until in libstdc++ are broken

At work we hit a bug that resulted in the following behaviour:

  • We set the system time on our embedded Linux system backwards, to test that NTP was able to set it forwards again correctly.
  • Our system rebooted itself.

This was, obviously, unexpected. It boiled down to the fact that timer we used to kick our hardware watchdog was using std::wait_for, and unexpectedly, setting the system clock backwards caused us not to receive a wakeup. As a result we didn’t kick our hardware watchdog so the system was rebooted.

The documentation for std::wait_for implies that it will wait for a certain amount of elapsed time, but in fact that’s not the case. Cppreference.com says “A steady clock is used to measure the duration”, but that’s not true, at least in libstdc++, where wait_for is converted into a wait_until a specific time. And that specific time is measured against the wall clock time, not the monotonic/steady_clock time, so if the system time moves then so does the amount of time you are waiting.

There’s a good write up of the problem – and the difficulty of reaching a solution – here.