Date: Thu, 13 Dec 2018 22:11:42 +0200 From: Konstantin Belousov <kostikbel@gmail.com> To: Conrad Meyer <cem@freebsd.org> Cc: andrew@ziglang.org, "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org> Subject: Re: raise() implementation in freebsd libc vs musl libc Message-ID: <20181213201142.GP60291@kib.kiev.ua> In-Reply-To: <CAG6CVpVGfL3Fu4DMyuzPa02Ud=cr1-kkDpkmpb_psjYrczMoaA@mail.gmail.com> References: <70c7214e-3619-115d-abca-09853a1729a6@ziglang.org> <CAG6CVpVGfL3Fu4DMyuzPa02Ud=cr1-kkDpkmpb_psjYrczMoaA@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Dec 12, 2018 at 10:00:56PM -0800, Conrad Meyer wrote: > Hi Andrew, > > The musl signal blocking dates to this commit: > > https://git.musl-libc.org/cgit/musl/commit/?id=0bed7e0acfd34e3fb63ca0e4d99b7592571355a9 > > The concern raised in that commit was that raise(3) could > theoretically be interrupted by a concurrently running signal handler > which invokes fork() (also sighandler-safe), resulting in > inconsistent/stale values from gettid(2)/getpid(2) on Linux (at the > time). But even then, for the child to signal wrong thread, it must return from the signal frame to the interrupted frame executing raise(). This would be really weird design. > > On both systems, gettid(2) / thr_self(2) returns a unique thread > identifier that cannot be reused until the thread it identifies has > exited. So, I don't know. I guess if fork happens between thr_self() > and thr_kill(), the parent process may have already exited and had its > tid recycled by the time the child process invokes thr_kill(). The difference between Linux and FreeBSD there, as I see it, is that thr_kill() only allows to send signals to the threads in the current process. So when the forked child sends a signal to the thread identified by the parent' thread id, nothing happens except an error code returned. > > OTOH, that seems like a pretty byzantine / broken application? I'm > not sure it's libc's job to prevent applications from shooting > themselves in the foot. Forking in a signal handler is already > somewhat dicey, and especially so if the child does not immediately > exec() or _exit(2). Forking in a signal handler is fine, assuming that the signal handler only uses async-signal safe functions, regardless of exec/_exit. Problem there is that atfork handlers must only use async-safe functions, which means that the author of the signal handler must be aware of the whole application code, including all libraries. > > Anyway, that's just my guess. I am not a libthr expert on either BSD > nor Linux, so take this with a big grain of salt. Signals were a > mistake ;-). > > Best, > Conrad > > P.S., Zig looks quite promising, I am excited to see where it goes. > > > On Wed, Dec 12, 2018 at 9:12 PM Andrew Kelley <andrew@ziglang.org> wrote: > > > > Howdy, > > > > I noticed that musl-libc blocks signals in raise() to prevent a race > > condition, but freebsd libc does not. is there a reason it's necessary > > on linux and not freebsd? > > > > musl > > int raise(int sig) > > { > > sigset_t set; > > __block_app_sigs(&set); > > int ret = syscall(SYS_tkill, __pthread_self()->tid, sig); > > __restore_sigs(&set); > > return ret; > > } > > > > freebsd > > int > > __raise(int s) > > { > > long id; > > > > if (__sys_thr_self(&id) == -1) > > return (-1); > > return (__sys_thr_kill(id, s)); > > } > > > > Regards, > > Andrew > > > _______________________________________________ > freebsd-hackers@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-hackers > To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20181213201142.GP60291>