| Summary: | C++ program signal handlers not called | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Dominic Fandrey <kami> | ||||||||
| Component: | misc | Assignee: | freebsd-bugs (Nobody) <bugs> | ||||||||
| Status: | Closed FIXED | ||||||||||
| Severity: | Affects Some People | CC: | emaste, kib, yamagi | ||||||||
| Priority: | --- | Keywords: | regression | ||||||||
| Version: | CURRENT | ||||||||||
| Hardware: | amd64 | ||||||||||
| OS: | Any | ||||||||||
| Attachments: |
|
||||||||||
|
Description
Dominic Fandrey
2017-01-06 12:58:12 UTC
Created attachment 178664 [details] Minimal testcase I managed to produce a minimal example. Apparently raising an exception causes the behaviour. I reproduced the problem using the following VM image: http://ftp.freebsd.org/pub/FreeBSD/snapshots/VM-IMAGES/12.0-CURRENT/amd64/20170105/ uname -a: FreeBSD 12.0-CURRENT FreeBSD 12.0-CURRENT #0 r311461: Thu Jan 5 22:46:38 UTC 2017 root@releng3.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64 Produce erroneous behaviour: c++ test.cpp -o test && ./test Produce expected behaviour: c++ test.cpp -o test -lpthread && ./test Created attachment 178670 [details]
Show sigprocmask, before and after exception
This is a version of the test case that outputs the sigprocmask before and after an exception.
Output on the same system as before:
# c++ mask.cpp -o mask && ./mask
main/try/sigprocmask: 00000000000000000000000000000000
main/catch/sigprocmask: 0xfffef007ffffffffffffffffffffffff
Raising signal: SIGINT
Returning despite signal!
# c++ mask.cpp -o mask -lpthread && ./mask
main/try/sigprocmask: 00000000000000000000000000000000
main/catch/sigprocmask: 00000000000000000000000000000000
Raising signal: SIGINT
#
This was broken in HEAD by SVN revision r310025[1] and in 11-STABLE with it's MFC in r311202[2]. I don't think that revision is the culprit, it's more likely that it exposed another bug. An educated guess would be the 'make libthr dlopen()able"-work about 1 year ago: https://lists.freebsd.org/pipermail/freebsd-threads/2014-December/005636.html 1: https://svnweb.freebsd.org/base?view=revision&revision=310025 2: https://svnweb.freebsd.org/changeset/base/311202 Created attachment 178720 [details]
Fix nested write locks for the compat rtld locking.
The issue is that nested write locking for non-libthr locks is broken, and I knew it, see the patched comment. Due to the peculiarity of the problem, I forgot about it when reviewed the r310025.
I can confirm that the patch fixes the problem for me. Thank you! A commit references this bug: Author: kib Date: Tue Jan 10 19:26:55 UTC 2017 New revision: 311886 URL: https://svnweb.freebsd.org/changeset/base/311886 Log: Fix acquisition of nested write compat rtld locks. Obtaining compat rtld lock in write mode sets process signal mask to block all signals. Previous mask is stored in the global variable oldsigmask. If a lock is write-locked while another lock is already write-locked, oldsigmask is overwritten by the total mask and on the last unlock, all signals except traps appear to be blocked. Fix this by counting the write-lock nested level, and only storing to oldsigmask/restoring from it at the outermost level. Masking signals disables involuntary preemption for libc_r, and there could be no voluntary context switches in the locked code (dl_iterate_phdr(3) keeps a lock around user callback, but it was added long after libc_r was renounced). Due to this, remembering the level in the global variable after the lock is obtained should be safe, because no two libc_r threads can acquire different write locks in parallel. PR: 215826 Reported by: kami Tested by: yamagi@yamagi.org (previous version) To be reviewed by: kan Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Changes: head/libexec/rtld-elf/rtld_lock.c I managed to reproduce the problem on stable/11 r311880 and the patch fixes it there too. So I recommend/request an MFC ASAP. Waiting for MFC. A commit references this bug: Author: kib Date: Tue Jan 24 11:13:42 UTC 2017 New revision: 312693 URL: https://svnweb.freebsd.org/changeset/base/312693 Log: MFC r311886: Fix acquisition of nested write compat rtld locks. PR: 215826 Changes: _U stable/11/ stable/11/libexec/rtld-elf/rtld_lock.c A commit references this bug: Author: kib Date: Tue Jan 24 17:30:13 UTC 2017 New revision: 312701 URL: https://svnweb.freebsd.org/changeset/base/312701 Log: MFC r311886: Fix acquisition of nested write compat rtld locks. PR: 215826 Changes: _U stable/10/ stable/10/libexec/rtld-elf/rtld_lock.c I can confirm that stable/11 r312742 passes my tests. Thank you for fixing! |