Chapter 5. Supplementary topics 5.1. Compatibility breaking changes in compilers and development tools Non-constant PTHREAD_STACK_MIN , MINSIGSTKSZ , and SIGSTKSZ macros In order to better support architectures that need a variable stack size for scalable vector registers, the constant value for the PTHREAD_STACK_MIN , MINSIGSTKSZ , and SIGSTKSZ macros have changed to a non-constant value, such as a sysconf call. You can no longer use the PTHREAD_STACK_MIN , MINSIGSTKSZ , and SIGSTKSZ macros in a way that treats them like constant values. The value returned for the PTHREAD_STACK_MIN , MINSIGSTKSZ , and SIGSTKSZ macros is now of the long data type and might generate compiler warnings when compared against an unsigned value, such as size_t . Libraries merged into libc.so.6 With this update, the following libraries have been merged into the libc library to provide a smoother in-place-upgrade experience, support safe use of threading at any time by a process, and to simplify the internal implementation: libpthread libdl libutil libanl Additionally, parts of the libresolv library have been moved into libc to support moving the Name Switch Service (NSS) files and Domain Name System (DNS) plugins directly into the libc library. The NSS files and DNS plugins are now directly built into the libc library and can be used during an upgrade or across a chroot or container boundary. Their use across a chroot or container boundary supports safely querying Identity Management (IdM) data from those sources. New location of zdump utility /usr/bin/zdump is the new location of the zdump utility. Deprecation of sys_siglist , _sys_siglist , and sys_sigabbrev symbols The sys_siglist , _sys_siglist , and sys_sigabbrev symbols are exported only as compatibility symbols to support old binaries. All programs should use the strsignal symbol instead. Using the sys_siglist , _sys_siglist , and sys_sigabbrev symbols creates issues such as copy relocations and an error-prone Application Binary Interface (ABI) with no explicit bound checks for the array access. This change might affect building from source for some package. To fix the issue, rewrite the program to use the strsignal symbol instead. For example: #include <signal.h> #include <stdio.h> static const char *strsig (int sig) { return sys_siglist[sig]; } int main (int argc, char *argv[]) { printf ("%s\n", strsig (SIGINT)); return 0; } should be adjusted to: #include <signal.h> #include <stdio.h> #include <string.h> static const char *strsig (int sig) { return strsignal(sig); } int main (int argc, char *argv[]) { printf ("%s\n", strsig (SIGINT)); return 0; } Or, to use the glibc-2.32 GNU extensions sigabbrev_np or sigdescr_np ,: #define _GNU_SOURCE #include <signal.h> #include <stdio.h> #include <string.h> static const char *strsig (int sig) { const char *r = sigdescr_np (sig); return r == NULL ? "Unknown signal" : r; } int main (int argc, char *argv[]) { printf ("%s\n", strsig (SIGINT)); printf ("%s\n", strsig (-1)); return 0; } Both extensions are async-signal-safe and multithread-safe. Deprecation of the sys_errlist , _sys_errlist , sys_nerr , and _sys_nerr symbols The sys_errlist , _sys_errlist , sys_nerr , and _sys_nerr symbols are exported solely as compatibility symbols to support old binaries. All programs should use the strerror or strerror_r symbols instead. Using the sys_errlist , _sys_errlist , sys_nerr , and _sys_nerr symbols creates issues such as copy relocations and an error-prone ABI with no explicit bound checks for the array access. This change might affect building from source for some packages. To fix the problem, rewrite the program using the strerror or strerror_r symbols. For example: #include <stdio.h> #include <errno.h> static const char *strerr (int err) { if (err < 0 || err > sys_nerr) return "Unknown"; return sys_errlist[err]; } int main (int argc, char *argv[]) { printf ("%s\n", strerr (-1)); printf ("%s\n", strerr (EINVAL)); return 0; } should be adjusted to: #include <stdio.h> #include <errno.h> static const char *strerr (int err) { return strerror (err); } int main (int argc, char *argv[]) { printf ("%s\n", strerr (-1)); printf ("%s\n", strerr (EINVAL)); return 0; } Or, to use the glibc-2.32 GNU extensions strerrorname_np or strerrordesc_np : #define _GNU_SOURCE #include <stdio.h> #include <errno.h> #include <string.h> static const char *strerr (int err) { const char *r = strerrordesc_np (err); return r == NULL ? "Unknown error" : r; } int main (int argc, char *argv[]) { printf ("%s\n", strerr (-1)); printf ("%s\n", strerr (EINVAL)); return 0; } Both extensions are async-signal-safe and multithread-safe. Userspace memory allocator, malloc , changes The mallwatch and tr_break symbols are now deprecated and no longer used in the mtrace function. You can achieve similar functionality by using conditional breakpoints within mtrace functions from within GDB. The __morecore and __after_morecore_hook malloc hooks and the default implementation, __default_morecore , have been removed from the API. Existing applications continue to link against these symbols but the interfaces no longer have any effect on malloc . Debugging features in malloc such as the MALLOC_CHECK_ environment variable (or the glibc.malloc.check tunable), mtrace() , and mcheck() have now been disabled by default in the main C library. To use these features, preload the new libc_malloc_debug.so debugging DSO. The deprecated functions malloc_get_state and malloc_set_state have been moved from the core C library into the libc_malloc_debug.so library. Legacy applications that still use these functions must now preload the libc_malloc_debug.so library in their environment using the LD_PRELOAD environment variable. The deprecated memory allocation hooks __malloc_hook , __realloc_hook , __memalign_hook , and __free_hook are now removed from the API. Compatibility symbols are present to support legacy programs, but new applications can no longer link to these symbols. These hooks no longer have any effect on glibc functionality. The malloc debugging DSO libc_malloc_debug.so currently supports hooks and can be preloaded to get this functionality back for older programs. However, this is a transitional measure and may be removed in a future release of the GNU C Library. You can port away from these hooks by writing and preloading your own malloc interposition library. Lazy binding failures terminate the process If a lazy binding failure happens during the dlopen function, during the execution of an ELF constructor, the process is now terminated. Previously, the dynamic loader returned NULL from dlopen with the lazy binding error captured in a dlerror message. In general, this is unsafe because resetting the stack in an arbitrary function call is not possible. Deprecation of the stime function The stime function is no longer available to newly linked binaries, and its declaration has been removed from <time.h> . Use the clock_settime function for programs that set the system time instead. popen and system functions do not run atfork handlers anymore Although it is a possible POSIX violation, the POSIX rationale in pthread_atfork documentation regarding atfork handlers is to handle inconsistent mutex states after a fork call in a multi-threaded process. In both the popen and system functions there is no direct access to user-defined mutexes. Deprecated features in the C++ standard library std::string::reserve(n) will no longer reduce the string's capacity if called with an argument that is less than the string's current capacity. A string's capacity can be reduced by calling reserve() with no arguments, but that form is deprecated. The equivalent shrink_to_fit() should be used instead. The non-standard std::__is_nullptr_t type trait was deprecated. The standard std::is_null_pointer trait should be used instead.

Commands:
#include <signal.h> #include <stdio.h> static const char *strsig (int sig) { return sys_siglist[sig]; } int main (int argc, char *argv[]) { printf ("%s\n", strsig (SIGINT)); return 0; }
#include <signal.h> #include <stdio.h> #include <string.h> static const char *strsig (int sig) { return strsignal(sig); } int main (int argc, char *argv[]) { printf ("%s\n", strsig (SIGINT)); return 0; }
#define _GNU_SOURCE #include <signal.h> #include <stdio.h> #include <string.h> static const char *strsig (int sig) { const char *r = sigdescr_np (sig); return r == NULL ? "Unknown signal" : r; } int main (int argc, char *argv[]) { printf ("%s\n", strsig (SIGINT)); printf ("%s\n", strsig (-1)); return 0; }
#include <stdio.h> #include <errno.h> static const char *strerr (int err) { if (err < 0 || err > sys_nerr) return "Unknown"; return sys_errlist[err]; } int main (int argc, char *argv[]) { printf ("%s\n", strerr (-1)); printf ("%s\n", strerr (EINVAL)); return 0; }
#include <stdio.h> #include <errno.h> static const char *strerr (int err) { return strerror (err); } int main (int argc, char *argv[]) { printf ("%s\n", strerr (-1)); printf ("%s\n", strerr (EINVAL)); return 0; }
#define _GNU_SOURCE #include <stdio.h> #include <errno.h> #include <string.h> static const char *strerr (int err) { const char *r = strerrordesc_np (err); return r == NULL ? "Unknown error" : r; } int main (int argc, char *argv[]) { printf ("%s\n", strerr (-1)); printf ("%s\n", strerr (EINVAL)); return 0; }