Interesting bugs in open source projects
GCC
Bug 54812: private
=default
destructor is public
Delete expression doesn't respect access of defaulted destructor
struct Base
{
private:
~Base() = default;
};
int main()
{
Base* p = new Base;
delete p;
}
Quote: The bug affects protected destructors too, and they're commonly used for base classes to prevent deletion via pointer-to-base.
Fixed in 4.9.0, by r203985. Test case added by r204057.
Glibc
strstr(3)
Since glibc 2.9, strstr(3) may use Two Way algorithm in some cases, but the impl. had several bugs:
getpid(2)
no longer caches PID
Since glibc 2.25, getpid(2)
no longer caches PID,
released on 2017-02-05. Ubuntu 18.04, Debian 10 and CentOS 8 contain this change.
Quote from
man 2 getpid
: From glibc version 2.3.4 up to and including version 2.24, the glibc wrapper function for getpid() cached PIDs, with the goal of avoiding additional system calls when a process calls getpid() repeatedly. ...Because of the aforementioned problems, since glibc version 2.25, the PID cache is removed: calls to getpid() always invoke the actual system call, rather than returning a cached value.
In a tight loop, it takes about 200ns for getpid(2)
on z420 (E5-1620 3.6GHz) running Linux 5.10.
Kernel
write(2)
not thread-safe
Fixed in v3.14, released in 2014-03-30. Ubuntu 14.04 has this bug, Debian 8 doesn't.
commit 9c225f2655e36a470c4f58dbbc99244c5fc7f2d4
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date: Mon Mar 3 09:36:58 2014 -0800
vfs: atomic f_pos accesses as per POSIX
Our write() system call has always been atomic in the sense that you get
the expected thread-safe contiguous write, but we haven't actually
guaranteed that concurrent writes are serialized wrt f_pos accesses, so
threads (or processes) that share a file descriptor and use "write()"
concurrently would quite likely overwrite each others data.
This violates POSIX.1-2008/SUSv4 Section XSI 2.9.7 that says:
"2.9.7 Thread Interactions with Regular File Operations
All of the following functions shall be atomic with respect to each
other in the effects specified in POSIX.1-2008 when they operate on
regular files or symbolic links: [...]"
and one of the effects is the file position update.
This unprotected file position behavior is not new behavior, and nobody
has ever cared. Until now. Yongzhi Pan reported unexpected behavior to
Michael Kerrisk that was due to this.
This resolves the issue with a f_pos-specific lock that is taken by
read/write/lseek on file descriptors that may be shared across threads
or processes.
Reported-by: Yongzhi Pan <panyongzhi@gmail.com>
Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
$ man 2 write
BUGS
According to POSIX.1-2008/SUSv4 Section XSI 2.9.7 ("Thread Interactions
with Regular File Operations"):
All of the following functions shall be atomic with respect to each
other in the effects specified in POSIX.1-2008 when they operate on
regular files or symbolic links: ...
Among the APIs subsequently listed are write() and writev(2). And among
the effects that should be atomic across threads (and processes) are
updates of the file offset. However, on Linux before version 3.14, this
was not the case: if two processes that share an open file description
(see open(2)) perform a write() (or writev(2)) at the same time, then the
I/O operations were not atomic with respect updating the file offset, with
the result that the blocks of data output by the two processes might
(incorrectly) overlap. This problem was fixed in Linux 3.14.
Java
"+=" applied to String operands can provoke side effects
Introduced in JDK9, fixed in JDK10 but not JDK9.
Why does array[idx++]+=“a” increase idx once in Java 8 but twice in Java 9 and 10?