From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.stackframe.dev (unknown [220.88.252.109]) by sourceware.org (Postfix) with ESMTPS id 087963858422 for ; Thu, 18 Nov 2021 18:07:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 087963858422 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=stackframe.dev Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=stackframe.dev Message-ID: <2fb82128-a9da-e7f5-8062-f7e72b1561db@stackframe.dev> Date: Fri, 19 Nov 2021 03:07:25 +0900 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.3.1 To: libc-help@sourceware.org Content-Language: en-US From: Gibeom Gwon Subject: Handles the masked signal when the thread exits Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-help@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-help mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Nov 2021 18:07:33 -0000 Hello, I am experiencing strange(unintended?) behavior when using pthread with signals. If I set the signal mask with pthread_sigmask() in the thread function and the process has pending signal when thread is exiting, signal handler executed in thread. It looks like glibc restores original signal mask at the end of the thread. So I suspect this eventually triggers masked signal handler. But I'm not sure it is intended or not. Code samples: sleep.c ------- #include #include #include #include #include #include pthread_t thread; pid_t pid; void stop_threads() { pthread_cancel(thread); pthread_join(thread, NULL); } void sigint_handler(int signum) { printf("sigint: %ld\n",pthread_self()); stop_threads(); exit(0); } void sigchld_handler(int signum) { printf("sigchld: %ld\n",pthread_self()); pid_t pid; int status; while((pid = waitpid(-1,&status,WNOHANG)) > 0) {} } void spawn_sleep() { pid = fork(); if(pid == 0) execl("./sleep","sleep",NULL); } void* worker(void *arg) { sigset_t mask; sigfillset(&mask); pthread_sigmask(SIG_SETMASK,&mask,NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); int i = 10; while(i) { printf("worker...\n"); sleep(1); i--; } pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); printf("thread close\n"); pthread_exit(0); } void spawn_thread() { pthread_create(&thread,NULL,worker,NULL); printf("child thread: %ld\n",thread); } int main() { printf("main thread: %ld\n",pthread_self()); spawn_sleep(); struct sigaction sa1; sa1.sa_handler = sigint_handler; sigemptyset(&sa1.sa_mask); sigaddset(&sa1.sa_mask,SIGCHLD); sa1.sa_flags = 0; sigaction(SIGINT, &sa1, 0); struct sigaction sa2; sa2.sa_handler = sigchld_handler; sigemptyset(&sa2.sa_mask); sa2.sa_flags = 0; sigaction(SIGCHLD, &sa2, 0); spawn_thread(); while(1) sleep(1); return 0; } result ====== $ ./signal main thread: 139882152073024 child thread: 139882152068672 worker... worker... worker... ^Csigint: 139882152073024 worker... worker... worker... worker... worker... worker... worker... thread close sigchld: 139882152068672 Comprehensive signal mask set in worker() but SIGCHLD handler executed after thread function exited. Regards, Gibeom Gwon