This reverts commit 8ef74e33b6
"Swapped out pthread_rwlock_xxlock() ..."
This could result in concurrent uses of pthread_cond_* erroneously
returning EAGAIN, which is not permitted by the spec and which the
application way well treat as a bug. This seems to be happening in
gem2deb in ci.debian.net.
The commit message in 8ef74e33b6 says (rewrapped)
Swapped out pthread_rwlock_xxlock(), which doesn't return if it
can't obtain the lock, with pthread_rwlock_xxtrylock() followed by
sched yield and error code return. The issue is sometimes a thread
calling pthread_cond_init() or pthread_cond_destroy() can't
acquire the lock when another thread is waiting on a condition
variable notification via pthread_cond_timedwait(), and thus the
thread calling pthread_cond_init() or pthread_cond_destroy() end
up hanging indefinitely.
I don't think this is true. The things that are done with
monotonic_conds_lock held are HASH_ADD_PTR HASH_FIND_PTR etc. on
monotonic_conds, which should all be fast and AFAICT don't in turn
take any locks. So it shouldn't deadlock.
I conjecture that the underlying bug being experienced by the author
of "Swapped out pthread_rwlock_xxlock" was the lack of ftpl_init - ie,
access to an uninitialised pthread_rwlock_t. That might result in a
hang.
Otherwise we can use this in an uninitialised state, which is not
allowed.
We call ftpl_init in pthread_cond_init_232, but the application might
not have called that. For example, it might have a static condition
variable set up with PTHREAD_COND_INITIALIZER.
timespec.tv_nsec is 32-bit, even though timeval.tv_usec is
64-bit (weirdly). This doesn't matter very much in practice because
* on little endian architectures (which is all our 32-bit release
arches) writing to a too big integer ends up writing the
desired value in the desired location, and
* it doesn't affect the overall struct size on any of our actual
architectures (which align the uint64_t to 8 so must make the
whole struct 16 not 12), so the write overflow is harmless.
> #include <time.h>
> #include <sys/time.h>
> #include <stdio.h>
> struct timeval tv;
> struct timespec ts;
> int main(void) {
> printf("time_t %lld\n", (unsigned long long) sizeof(time_t));
> printf("timeval %lld %lld %lld\n",
> (unsigned long long) sizeof(tv),
> (unsigned long long) sizeof(tv.tv_sec),
> (unsigned long long) sizeof(tv.tv_usec)
> );
> printf("timespec %lld %lld %lld\n",
> (unsigned long long) sizeof(ts),
> (unsigned long long) sizeof(ts.tv_sec),
> (unsigned long long) sizeof(ts.tv_nsec)
> );
> }
> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$ gcc t.c
> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$ ./a.out
> time_t 8
> timeval 16 8 8
> timespec 16 8 4
> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$
Since debian generally added 64-bit time support on 32-bit
arches, now glibc sometimes calls the clock_gettime64 syscall
(and library wrapper). This function was missing, and is added here.
Patch originally supplied here
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064555
We should ignore the return value for logging function, to fix a new gcc ftbfs
libmallocintercept.c: In function ‘print_msg’:
libmallocintercept.c:27:9: error: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Werror=unused-result]
27 | write(0, msg, strlen(msg));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
The shared semaphore is closed but it's not assigned to null.
That's required because the logic check the semaphore status if it's not null. For this reason, we are getting a core some times.
The use of shared memory has side effects. Currently, the only way to
opt out of shared memory is by compiling with -DFAKE_STATELESS.
To allow disabling shared memory without recompiling, this patch
introduces the --disable-shm option to `faketime`, equivalent to
setting the `FAKETIME_DISABLE_SHM=1` environment variable.
One callsite of ftpl_init wasn't protected by the "if (!initialized)"
condition, specifically:
static void ftpl_init (void) __attribute__ ((constructor));
If another "constructor" was called before this one, and that other
constructor used time or filesystem functions, ftlp_init would be
initialized by that other constructor, and then reinitialized by the
ftpl_init constructor. At that point, confusion ensues.
Function `timespec_get` is not guaranteed to be declared in MacOS
since its standard library is non-conformance to modern standards.
Therefore, skip patching `timespec_get` if it is undeclared by the
standard library.
The detection of `timespec_get` is based on the conjecture that the
macro `TIME_UTC` is only defined when `timespec_get` is declared.