NetBSD Problem Report #59135
From www@netbsd.org Wed Mar 5 16:35:36 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
client-signature RSA-PSS (2048 bits) client-digest SHA256)
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 448971A923D
for <gnats-bugs@gnats.NetBSD.org>; Wed, 5 Mar 2025 16:35:36 +0000 (UTC)
Message-Id: <20250305163534.CA7411A923F@mollari.NetBSD.org>
Date: Wed, 5 Mar 2025 16:35:34 +0000 (UTC)
From: campbell+netbsd@mumble.net
Reply-To: campbell+netbsd@mumble.net
To: gnats-bugs@NetBSD.org
Subject: PTHREAD_CANCEL_ASYNCHRONOUS doesn't do much
X-Send-Pr-Version: www-1.0
>Number: 59135
>Category: lib
>Synopsis: PTHREAD_CANCEL_ASYNCHRONOUS doesn't do much
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Mar 05 16:40:01 +0000 2025
>Originator: Taylor R Campbell
>Release: current, 10, 9, ...
>Organization:
The PthreadBSD Foun
>Environment:
>Description:
Under POSIX, when a thread has asynchronous cancellation configured with pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, ...), cancellation should be able to happen at any time, not just at cancellation points:
> Each thread maintains its own cancelability state, which may be encoded in two bits:
> 1. Cancelability-Enable: ...
> 2. Cancelability Type: When cancelability is enabled and the cancelability type is PTHREAD_CANCEL_ASYNCHRONOUS (as defined in <pthread.h>), new or pending cancellation requests may be acted upon at any time. When cancelability is enabled and the cancelability type is PTHREAD_CANCEL_DEFERRED (as defined in <pthread.h>), cancellation requests are held pending until a cancellation point (see below) is reached....
However, NetBSD's libpthread doesn't really do much with PTHREAD_CANCEL_ASYNCHRONOUS.
>How-To-Repeat:
#include <err.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
static void
cleanup(void *cookie)
{
fprintf(stderr, "cleanup\n");
}
static void *
thread(void *cookie)
{
pthread_barrier_t *bar = cookie;
int error;
error = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
if (error)
errc(1, error, "pthread_setcanceltype");
pthread_cleanup_push(cleanup, NULL);
fprintf(stderr, "loop forever\n");
(void)pthread_barrier_wait(bar);
for (;;) {
__asm("");
}
pthread_cleanup_pop(0);
return NULL;
}
int
main(void)
{
pthread_barrier_t bar;
pthread_t t;
int error;
error = pthread_barrier_init(&bar, NULL, 2);
if (error)
errc(1, error, "pthread_barrier_init");
fprintf(stderr, "create thread\n");
error = pthread_create(&t, NULL, &thread, &bar);
if (error)
errc(1, error, "pthread_create");
(void)pthread_barrier_wait(&bar);
fprintf(stderr, "cancel\n");
error = pthread_cancel(t);
if (error)
errc(1, error, "pthread_cancel");
(void)alarm(1);
error = pthread_join(t, NULL);
if (error)
errc(1, error, "pthread_join");
(void)alarm(0);
fprintf(stderr, "ok\n");
return 0;
}
>Fix:
1. Invent a new signal, say SIGCANCEL.
2. Teach libc's signal/sigaction/sigprocmask stubs to pretend it doesn't exist.
3. Teach libpthread to set up a SIGCANCEL handler that does pthread_cancel as appropriate.
4. Shake out all the bugs.
5. Shake out some more bugs.
6. ???
7. Profit!
8. ...just one or two more bugs
(Contact us)
$NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2025
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.