-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
glibc deprecated some stuff, leading to warnings #4183
Comments
Urgh, the |
Note that sys_errlist and sys_nerr have been implicitly deprecated for nearly twenty years. It sucks that strerror is not fork safe. If we can't come up with a better solution I recommend calling strerror for all possible errno values and caching the results as soon as we've initialized the environment (in particular the locale subsystem) but before doing anything that would fork. A solution I've pondered for this type of problem is an internal RPC mechanism. That would allow the child side of a fork to ask a RPC thread in the main fish process (via a fifo or anonymous unix domain socket) to do something that might acquire a lock and get the results back. This would be a non-trivial amount of work to implement but would allow us to simplify the code in other ways such as eliminating A far simpler solution is to use a barrier to ensure all threads are quiescent before calling fork/spawn. The child process is then free to call malloc, strerror, etc. Yes, I know we generally want to avoid blocking on a thread completing an action. But we have very few threads and none are likely to cause a delay in completing the fork/spawn. If we do have such a thread it is generally trivial to add barrier checks in its inner loop(s) to keep the latency low. The theoretical problem with this approach is that threads created "behind our back" by some library function throws a monkey wrench into the scheme. But we're unlikely to use an API that does so and I think the benefits of this approach outweigh the risks. |
Note that @ridiculousfish has already proposed something similar to my preferred solution in our pthread manifesto:
However, note that what I'm proposing does not involve waiting for those threads to exit. I am proposing that we introduce barriers where we block further execution of all threads, other than the main thread, when we need to fork/spawn until the fork/spawn has been done. Thus ensuring that the child process inherits a state that should be free of mutexes held that could result in a deadlock. |
I haven't looked into glibc's implementation of the XSI-compliant version of |
@mqudsi: By "named" semaphore do you mean a mutex that is stored in a page of memory shared by the parent and child process? If no then your solution doesn't work. And if yes then I think my proposal is simpler and more general. |
@krader1961 I meant using It probably wouldn't be too hard to wrap all calls to lock/unlock in a function that increments or decrements some global "obtained mutexes" count and have any fork calls block until that value is zero (condition variable + another mutex). But I have a different question: what's the reason behind the mix of threads and fork? If you limit forking to a single thread (not necessarily the main thread) used to spawn external processes (so never fork without a more-or-less-immediate exec), can you not avoid the issue entirely? I wonder if it would be too difficult to eliminate non-exec forks with threads that call the respective functions and sidestep the issue entirely. |
I don't know as I've only been contributing since October 2015. @ridiculousfish may have insight into that question. If I had to guess I would hypothesize that it's the result of the original C (not C++) implementation not using threads. Then when it was rewritten in C++ support for threads was added so that features like history based autosuggestions don't block the user input thread. But the thread implementation was done organically to minimize changes to the existing code that spawns jobs. |
Okay, I now made the readdir change for #5458. |
strerror is not thread-safe and strerror_r is not async-safe (see man signal-safety) glibc strerror_r can hang in certain real-world scenarios. (cf github issues fish-shell#472, fish-shell#1830, fish-shell#4183) To work around that, we previously used the underlying structures (_sys_err tables) but these are getting deprecated: $ make ld: libfishlib.a(wutil.cpp.o): in function `safe_strerror(int)': wutil.cpp:307: warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead ld: wutil.cpp:307: warning: `sys_nerr' is deprecated; use `strerror' or `strerror_r' instead ld: libfishlib.a(wutil.cpp.o): in function `safe_strerror(int)': wutil.cpp:307: warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead This new solution pre-generates a read-only list of messages at startup which can be safely returned. Since caching INT_MAX values is pretty big, let's look at various OS maximum value for errno: - Linux [1-133] https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/errno.h - FreeBSD (userspace visible) [1-97] https://github.com/freebsd/freebsd/blob/master/sys/sys/errno.h - OpenBSD (userspace visible) [1-95] https://github.com/openbsd/src/blob/master/sys/sys/errno.h - Apple (userspace visible) [1-88] https://opensource.apple.com/source/xnu/xnu-201/bsd/sys/errno.h.auto.html - Solaris [1-151] http://fxr.watson.org/fxr/source/common/sys/errno.h?v=OPENSOLARIS We are settling on 200 for good measure.
This no longer works on new glibcs because they removed sys_errlist. So just hardcode the relevant errno messages (and phrase them better). Fixes fish-shell#4183.
In glibc 2.25, a few things we use are marked as deprecated. On my system, this leads to the only remaining compiler warnings.
The full list:
readdir_r
(recommending plainreaddir
, which is apparently thread-safe as long as no two threads access the same directory stream simultaneously on glibc and solaris - see e.g.readdir_r
is deprecated as of glibc-2.24 rust-lang/rust#34668)sys_errlist
andsys_nerr
(recommendingstrerror
orstrerror_r
)The text was updated successfully, but these errors were encountered: