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

Java program uses 100% CPU with libfaketime #425

Open woshikid opened 1 year ago

woshikid commented 1 year ago

I uses libfaketime to change the time in docker container. But when I run Java programs with libfaketime, I noticed that it uses 100% of the cpu resources even no java code is using cpu.

It can be reproduced by run docker run -it eclipse-temurin:11 bash and install libfaketime by apt update && apt install libfaketime or build from source. And with java code Test.java

public class Test {
    public static void main(String args[]) throws Exception {
        System.out.println("waiting for input");
        System.in.read();
    }
}

when running this test code with libfaketime: LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1 java Test it takes all the CPU resources: image

I've tested the java 8, 11, and 17. Java 8 and 11 both have this issue and java 17 works fine.

pedroyzkrak commented 1 year ago

I have a similar issue, we have a java application running in a docker container, we're using LD_PRELOAD and FAKETIME_DONT_FAKE_MONOTIC environment variables as expressed in the README, the thing is: this worked fine with jdk 11.0.17 However, with the new jdk 11.0.19 the cpu usage skyrocketed without explanation, removing faketime appears to solve the high cpu usage so we know for sure that there's some incompatibility with jdk 11.0.19 and faketime.

dawsondong commented 1 year ago

@woshikid Could you tell us which precise worked version did you use for java17, 17.0.x?

woshikid commented 1 year ago

@dawsondong I used docker eclipse-temurin:17, and the version is openjdk "17.0.7" 2023-04-18

viquu commented 10 months ago

I have same issue too. In my case, the problem is mysql on macos13.1(M1). My faketime version is 0.9.10 install by brew. And I use .faketimerc set faketime.

faketime_cpu
christian-scheible commented 7 months ago

I have the same problem using Forgerock IDM and OpenJDK Runtime Environment 17.09 (build 17.0.9+8-LTS).

eriknellessen commented 7 months ago

Same problem here. I tested with Ubuntu in a Docker Image. I used the following program versions:

I did some analysis. To me it seems like the JVM compiler threads are causing the high CPU usage. Usually they should only use the CPU right after the start of the program. But with the new libfaketime version, they do not stop. See the following screenshot: threads_libfaketime

christian-scheible commented 5 months ago

I have an update regarding this issue. As I genuinely require this library for testing purposes, I endeavored to build various versions of libfaketime independently.

Here is my current setup:

I'm utilizing a base image with Debian GNU/Linux 11 (bullseye) and OpenJDK 17.09 (OpenJDK Runtime Environment Zulu17.46+19-CA (build 17.0.9+8-LTS)).

For anyone experiencing similar problems and seeking a workaround, here's what I did:

I experimented with different versions of libfaketime, and up until version 0.9.10, the issue does not exist.

For anyone haveing similar problems and looking for a work around this is what I did:

RUN apt-get update && apt-get install -y \
    wget \
    unzip \
    make \
    gcc \
 && rm -rf /var/lib/apt/lists/*

RUN mkdir faketime && \
    cd faketime && \
    wget https://github.com/wolfcw/libfaketime/archive/refs/tags/v0.9.9.zip && \
    unzip v0.9.9.zip && \
    cd libfaketime-0.9.9 && \
    make install

After that LD_PRELOAD has to be set to this value:

LD_PRELOAD: "/usr/local/lib/faketime/libfaketime.so.1"

wolfcw commented 5 months ago

Thanks for this update! Any chance you could go the extra mile and figure out which commit between 0.9.9 and 0.9.10 breaks it for you?

Based on @eriknellessen 's comment it seems like pre-0.9.9 versions may have this problem as well (unless Ubuntu backported something, I don't know), but it at least may give us a hint where to look closer when it comes to JDK compatibility.

christian-scheible commented 5 months ago

Hi wolfcw,

sure I did what you suggested and for me until commit: 36090e8ceba3dd0cc9478403eacf5949530ab6d9 everything was fine.

So:

wolfcw commented 5 months ago

@christian-scheible That's very helpful, thank you very much!

It's the commit that changed the auto-detection for the necessity of FORCE_MONOTONIC_FIX based on the system's glibc version. Different glibc versions behave differently in the context of the pthread_cond_timedwait() function, and correlating this with @eriknellessen 's list it seems like JDK might have the same or a similar issue with libfaketime independent of glibc.

Could you eventually try to activate / de-activate libfaketime's fixing attempts by setting the environment variable FAKETIME_FORCE_MONOTONIC_FIX to either 1 (activate) or 0 (de-activate) and check whether this changes anything (also with newer versions such as current HEAD)?

Also, could you tell which glibc version is used on your testing system?

christian-scheible commented 5 months ago

@wolfcw, happy to help. I like libfaketime, so it's great to be able to contribute.

I've tested commit versions 36090e8ceba3dd0cc9478403eacf5949530ab6d9 and the latest, f32986867addc9d22b0fab29c1c927f079d44ac1. Setting FAKETIME_FORCE_MONOTONIC_FIX to 0 fixed it for me.

The glibc version on my testing system is:

ldd (Debian GLIBC 2.31-13+deb11u7) 2.31

wolfcw commented 5 months ago

Great to know, thank you very much. Maybe the others could check as well whether this is a suitable workaround, and if so, we'll look into automating this.

pertyjons commented 4 months ago

Hi, just wanted you to know we got the same problem using temurin-21 when upgrading to spring-boot 3.2.2 (probably the cause). Solved it also by setting the FAKETIME_FORCE_MONOTONIC_FIX=0 using version 0.9.10

woshikid commented 4 months ago

😭 well, to me the problem still exists with FAKETIME_FORCE_MONOTONIC_FIX=0. I just tested this workaround on the code as I posted. FAKETIME_FORCE_MONOTONIC_FIX=0 LD_PRELOAD=/usr/lib/x86_64-linux-gnu/faketime/libfak etime.so.1 java Test and it still eat up all the cpu time.

the base docker image is eclipse-temurin:11 and the glibc version is ldd (Ubuntu GLIBC 2.35-0ubuntu3.6) 2.35

woshikid commented 4 months ago

I've tested the HEAD version of libfaketime, the workaround FAKETIME_FORCE_MONOTONIC_FIX=0 works! The libfaketime in image eclipse-temurin:11 by apt install libfaketime is 0.9.8-9, and that version didn't work with this workaround.

woshikid commented 4 months ago

This workaround has side effects (https://github.com/wolfcw/libfaketime/issues/460)

on Ubuntu (ldd (Ubuntu GLIBC 2.35-0ubuntu3.6) 2.35) with HEAD version of libfaketime and Java code Thread.sleep(1000); when set FAKETIME_FORCE_MONOTONIC_FIX=0 Java 11 (openjdk version "11.0.22" 2024-01-16): works fine. Java 17 (openjdk version "17.0.10" 2024-01-16): hangs forever. Java 21 (openjdk version "21.0.2" 2024-01-16 LTS): hangs forever.

So we have to find other way.