Date: Wed, 12 Dec 2018 22:00:56 -0800 From: Conrad Meyer <cem@freebsd.org> To: andrew@ziglang.org Cc: "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org> Subject: Re: raise() implementation in freebsd libc vs musl libc Message-ID: <CAG6CVpVGfL3Fu4DMyuzPa02Ud=cr1-kkDpkmpb_psjYrczMoaA@mail.gmail.com> In-Reply-To: <70c7214e-3619-115d-abca-09853a1729a6@ziglang.org> References: <70c7214e-3619-115d-abca-09853a1729a6@ziglang.org>
next in thread | previous in thread | raw e-mail | index | archive | help
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). 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(). 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). 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 >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG6CVpVGfL3Fu4DMyuzPa02Ud=cr1-kkDpkmpb_psjYrczMoaA>