public inbox for glibc-bugs@sourceware.org help / color / mirror / Atom feed
From: "0x66726565 at gmail dot com" <sourceware-bugzilla@sourceware.org> To: glibc-bugs@sourceware.org Subject: [Bug libc/26802] New: raise() marked __leaf__ is not C-compliant Date: Wed, 28 Oct 2020 17:14:02 +0000 [thread overview] Message-ID: <bug-26802-131@http.sourceware.org/bugzilla/> (raw) https://sourceware.org/bugzilla/show_bug.cgi?id=26802 Bug ID: 26802 Summary: raise() marked __leaf__ is not C-compliant Product: glibc Version: 2.30 Status: UNCONFIRMED Severity: normal Priority: P2 Component: libc Assignee: unassigned at sourceware dot org Reporter: 0x66726565 at gmail dot com CC: drepper.fsp at gmail dot com Target Milestone: --- To quote the C standard on the signal() function (C90, C99, C11, and C18 basically say the same) described in Section 7.14.1.1 Paragraph 5 of [1]: If the signal occurs other than as the result of calling the abort or raise function, the behavior is undefined if the signal handler refers to any object with static or thread storage duration that is not a lock-free atomic object other than by assigning a value to an object declared as volatile sig_atomic_t End quote. Based on that, a signal handler that is run as the result of calling raise() has no UB (undefined behavior) when the handler accesses an object with static storage duration that is not qualified with volatile. Indeed, the C standard does not say that it is a UB to access an object with static storage duration that is not qualified with volatile and/or is not of type sig_atomic_t from a signal handler that is run as the result of calling raise(). However, glibc 2.30 for my x86_64 machine managed by the Linux kernel version 4.15.0 marks raise() using the GCC function attribute __leaf__. This results in a UB because the following test program terminates when compiled by GCC with -O0 and -Os but never terminates when compiled by GCC with -O2: -- 8< -------------------- #include <signal.h> #include <stdlib.h> static int terminated; static void handler(int signo) { terminated = 1; } int main(int argc, char **argv) { unsigned total = 0, delta = drand48() >= argc ? 1 : 0; /* At runtime, delta will be 0 as argc is 1 */ signal(SIGUSR1, handler); /* Infinite loop unless `terminated' is 1 (delta is 0) */ for (int i = 0; !terminated && i < 100; i += delta) { total += i; raise(SIGUSR1); /* synchronously runs `handler' */ } return total; } -- 8< -------------------- As a reminder, the C standard says the following about the raise() function (C99, C11, and C18 basically say the same), which is stated on page 195 of [1]: If a signal handler is called, the raise function shall not return until after the signal handler does. End quote. Now the GCC documentation on __leaf__ [2] says the following (words in square brackets are additions/replacements to fit this context): Note that leaf functions might indirectly run a signal handler defined in the current compilation unit that uses static variables. [...] There is no standard-compliant way to write such [an] implementation function[, for example, glibc-2.30 raise()], and the best that you can do is to remove the leaf attribute or mark all such static variables volatile. End quote. Since glibc-2.30 raise() definitely runs a signal handler as required by the C standard, and the signal handler can be defined in the current compilation unit to use static variables, then unless the C standard says that it is a UB to access a non-volatile object with static storage duration from within a signal handler that is run using raise() on a normal execution path, the marking of raise() with __leaf__ makes raise() non-compliant with the C standard, and hence, this bug report. Therefore, this bug report requests that, to be compliant with the C standard, glibc does not mark raise() with __leaf__. Furthermore, if glibc aims to be POSIX-compliant as well, in accordance with IEEE Std 1003.1-2017, Volume 2 "System Interfaces", Section 2.4.3 "Signal Actions", the following functions should not be marked with __leaf__ as well: abort(), raise(), kill(), pthread_kill(), and sigqueue(). Thank you for your attention. References: [1] https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf [2] https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes -- You are receiving this mail because: You are on the CC list for the bug.
next reply other threads:[~2020-10-28 17:14 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-10-28 17:14 0x66726565 at gmail dot com [this message] 2020-10-28 19:57 ` [Bug libc/26802] " 0x66726565 at gmail dot com 2022-07-25 21:25 ` amonakov at gmail dot com
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-26802-131@http.sourceware.org/bugzilla/ \ --to=sourceware-bugzilla@sourceware.org \ --cc=glibc-bugs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).