Bug#1008174: libc6: poll() spuriously returns EINTR
Package: libc6
Version: 2.34-0experimental3
Severity: important
Dear Maintainer,
In the example below, glibc 2.34 from experimental causes a spurious
EINTR error in the poll() call from the child thread. It seems that
thread cancellation causes the poll() to be spuriously interrupted,
even though the cancellation is explicitly disabled at that time.
As far as I understand, POSIX allows (or even requires) thread
cancellation to be essentially like a signal interruption, save for
ending the thread. But that is *only* from the moment that cancellation
is effected. Cancellation cannot be effected while it is disabled by
definition, so the behaviour from glibc seems wrong here.
This regression is known to break the test suite from the VLC package.
Rolling back to 2.33 from unstable solves the problem.
----8<----
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <poll.h>
#include <pthread.h>
static void *thread(void *data)
{
int canc;
(void) data;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &canc);
if (poll(NULL, 0, 2000) < 0) {
perror("Unexpected poll error");
abort();
}
pthread_setcancelstate(canc, NULL);
return NULL;
}
int main(void)
{
pthread_t th;
void *ret;
struct timespec ts = { 0, 100*1000*1000 };
if (pthread_create(&th, NULL, thread, NULL)) {
perror("pthread_create");
return 1;
}
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
pthread_cancel(th);
pthread_join(th, &ret);
assert(ret == NULL);
return 0;
}
---->8----
-- System Information:
Debian Release: bookworm/sid
APT prefers unstable-debug
APT policy: (500, 'unstable-debug'), (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386, arm64
Kernel: Linux 5.16.0-5-amd64 (SMP w/12 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8) (ignored: LC_ALL set to fi_FI.UTF-8), LANGUAGE=fr:en_GB:fi
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages libc6 depends on:
ii libgcc-s1 12-20220319-1
Versions of packages libc6 recommends:
ii libidn2-0 2.3.2-2
Versions of packages libc6 suggests:
ii debconf [debconf-2.0] 1.5.79
pn glibc-doc <none>
ii libc-l10n 2.34-0experimental3
ii libnss-nis 3.1-4
ii libnss-nisplus 1.3-4
ii locales 2.33-7
-- debconf information:
* libraries/restart-without-asking: true
glibc/kernel-too-old:
glibc/restart-services:
glibc/kernel-not-supported:
glibc/restart-failed:
* glibc/upgrade: true
glibc/disable-screensaver:
Reply to: