wolfcw / libfaketime

libfaketime modifies the system time for a single application
https://github.com/wolfcw/libfaketime
GNU General Public License v2.0
2.62k stars 319 forks source link

Feature request: automating FAKETIME_FORCE_MONOTONIC_FIX #460

Open woshikid opened 4 months ago

woshikid commented 4 months ago

When using libfaketime in alpine, java program hangs at code Thread.sleep(1000);. It can be fixed by setting either FAKETIME_FORCE_MONOTONIC_FIX=1 or FAKETIME_DONT_FAKE_MONOTONIC=1. But when speeding up the program like FAKETIME="+0 x2", the thread hangs again with FAKETIME_DONT_FAKE_MONOTONIC=1, only FAKETIME_FORCE_MONOTONIC_FIX=1 can fix these problems completely.

The doc says

and a glibc version is detected at run-time that is assumed to need this workaround

so can libfaketime detect musl libc on alpine and patch this fix automatically?

wolfcw commented 4 months ago

The most important rule here is that the 'monotonic fix' must not be activated on systems that don't need it (faking monotonic clock values would not work properly then).

I don't think the issue with Java programs is related to musl libc. Otherwise, maintainers for musl-libc-based distributions/images could just compile the 'monotonic fix' in via libfaketime's Makefile and it would be a non-issue for most users.

We once figured out that the 'monotonic fix' is required for certain (older, but still widely used) versions of glibc, and it has been automated for glibc somewhat successfully.

As far as Java applications are concerned, to our current knowledge certain JDK/Java Runtime Environment versions by certain vendors also require this 'monotonic fix', but this seems independent of glibc or other underlying libc implementations.

Automation for this has not yet been implemented mainly for two reasons:

So far, the workaround is somewhat simple (Java application hangs? Set the environment variable!) but needs to be performed by each user (= high total global effort). Automating it would certainly be interesting if it can be done reliably without to much effort required on libfaketime's end.

It's worth noting that the same problem applies to other complex run-time environment, such as .NET (for similar reasons as for JDK/JRE) and web browsers (such as Chromium, which are complex beasts). It is kind of an endless task to fix compatibility on libfaketime's end across all vendors/products/versions, and it's mostly nasty workarounds. I really wish libfaketime users would also mention such issues to the vendors / projects of the 'incompatible' applications, as considering and supporting the use of libfaketime within a target application is somewhat simple compared to implementing checks and workarounds for various environments in libfaketime.

woshikid commented 4 months ago

Thank you for the reply. I totally agree that libfaketime should not implement checks and workarounds for specific languages like Java and C#.

I did more tests and found that if I set FAKETIME_FORCE_MONOTONIC_FIX=0 on ubuntu, the thread hangs too! So you are right.

As far as Java applications are concerned, to our current knowledge certain JDK/Java Runtime Environment versions by certain vendors also require this 'monotonic fix', but this seems independent of glibc or other underlying libc implementations.

It seems that the Java will hang anyway without 'monotonic fix' regardless of the underlying libc implementations. The reason Java hangs on alpine is that 'monotonic fix' is not automatically enabled.

So maybe we can mention this in doc that when running Java, always set FAKETIME_FORCE_MONOTONIC_FIX=1.