From 36090e8ceba3dd0cc9478403eacf5949530ab6d9 Mon Sep 17 00:00:00 2001 From: Wolfgang Hommel Date: Fri, 25 Feb 2022 21:25:58 +0100 Subject: dynamic forced monotonic fix autosense (addresses #366) --- src/libfaketime.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libfaketime.c b/src/libfaketime.c index 9813b16..5ac0300 100644 --- a/src/libfaketime.c +++ b/src/libfaketime.c @@ -32,6 +32,7 @@ #include #ifdef __linux__ #include +#include #endif #include #ifdef MACOS_DYLD_INTERPOSE @@ -3569,6 +3570,7 @@ bool needs_forced_monotonic_fix(char *function_name) { bool result = false; char *env_var; + const char *glibc_version_string = gnu_get_libc_version(); if (function_name == NULL) return false; @@ -3586,11 +3588,24 @@ bool needs_forced_monotonic_fix(char *function_name) /* Here we try to derive the necessity for a forced monotonic fix * * based on glibc version. What could possibly go wrong? */ - result = false; // chosen by unfair coin flip + int glibc_major, glibc_minor; + sscanf(glibc_version_string, "%d.%d", &glibc_major, &glibc_minor); + + /* The following decision logic is yet purely based on experiences + * with pthread_cond_timedwait(). The used boundaries may still be + * imprecise. */ + if ( (glibc_major == 2) && + ((glibc_minor <= 17) || (glibc_minor >= 30)) ) + { + result = true; + } + else + result = false; // avoid forced monotonic fixes unless really necessary } if (getenv("FAKETIME_DEBUG") != NULL) - fprintf(stderr, "libfaketime: forced monotonic fix for %s = %s\n", function_name, result?"yes":"no"); + fprintf(stderr, "libfaketime: forced monotonic fix for %s = %s (glibc version %s)\n", + function_name, result ? "yes":"no", glibc_version_string); return result; } -- cgit v1.2.1