mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
posix: Add _Fork [BZ #4737]
Austin Group issue 62 [1] dropped the async-signal-safe requirement for fork and provided a async-signal-safe _Fork replacement that does not run the atfork handlers. It will be included in the next POSIX standard. It allow to close a long standing issue to make fork AS-safe (BZ#4737). As indicated on the bug, besides the internal lock for the atfork handlers itself; there is no guarantee that the handlers itself will not introduce more AS-safe issues. The idea is synchronize fork with the required internal locks to allow children in multithread processes to use mostly of standard function (even though POSIX states only AS-safe function should be used). On signal handles, _Fork should be used intead and only AS-safe functions should be used. For testing, the new tst-_Fork only check basic usage. I also added a new tst-mallocfork3 which uses the same strategy to check for deadlock of tst-mallocfork2 but using threads instead of subprocesses (and it does deadlock if it replaces _Fork with fork). [1] https://austingroupbugs.net/view.php?id=62
This commit is contained in:
parent
dd45734e32
commit
c32c868ab8
8
NEWS
8
NEWS
@ -52,6 +52,14 @@ Major new features:
|
|||||||
* On Linux, a new tunable, glibc.pthread.stack_cache_size, can be used
|
* On Linux, a new tunable, glibc.pthread.stack_cache_size, can be used
|
||||||
to configure the size of the thread stack cache.
|
to configure the size of the thread stack cache.
|
||||||
|
|
||||||
|
* The function _Fork has been added as an async-signal-safe fork replacement
|
||||||
|
since Austin Group issue 62 droped the async-signal-safe requirement for
|
||||||
|
fork (and it will be included in the future POSIX standard). The new _Fork
|
||||||
|
function does not run any atfork function neither resets any internal state
|
||||||
|
or lock (such as the malloc one), and only sets up a minimal state required
|
||||||
|
to call async-signal-safe functions (such as raise or execve). This function
|
||||||
|
is currently a GNU extension.
|
||||||
|
|
||||||
Deprecated and removed features, and other changes affecting compatibility:
|
Deprecated and removed features, and other changes affecting compatibility:
|
||||||
|
|
||||||
* The function pthread_mutex_consistent_np has been deprecated; programs
|
* The function pthread_mutex_consistent_np has been deprecated; programs
|
||||||
|
@ -31,6 +31,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
|
|||||||
tst-malloc-backtrace tst-malloc-thread-exit \
|
tst-malloc-backtrace tst-malloc-thread-exit \
|
||||||
tst-malloc-thread-fail tst-malloc-fork-deadlock \
|
tst-malloc-thread-fail tst-malloc-fork-deadlock \
|
||||||
tst-mallocfork2 \
|
tst-mallocfork2 \
|
||||||
|
tst-mallocfork3 \
|
||||||
tst-interpose-nothread \
|
tst-interpose-nothread \
|
||||||
tst-interpose-thread \
|
tst-interpose-thread \
|
||||||
tst-alloc_buffer \
|
tst-alloc_buffer \
|
||||||
@ -113,6 +114,8 @@ libmemusage-inhibit-o = $(filter-out .os,$(object-suffixes))
|
|||||||
$(objpfx)tst-malloc-backtrace: $(shared-thread-library)
|
$(objpfx)tst-malloc-backtrace: $(shared-thread-library)
|
||||||
$(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
|
$(objpfx)tst-malloc-thread-exit: $(shared-thread-library)
|
||||||
$(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
|
$(objpfx)tst-malloc-thread-fail: $(shared-thread-library)
|
||||||
|
$(objpfx)tst-mallocfork3: $(shared-thread-library)
|
||||||
|
$(objpfx)tst-mallocfork3-mcheck: $(shared-thread-library)
|
||||||
$(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library)
|
$(objpfx)tst-malloc-fork-deadlock: $(shared-thread-library)
|
||||||
$(objpfx)tst-malloc-stats-cancellation: $(shared-thread-library)
|
$(objpfx)tst-malloc-stats-cancellation: $(shared-thread-library)
|
||||||
$(objpfx)tst-malloc-backtrace-malloc-check: $(shared-thread-library)
|
$(objpfx)tst-malloc-backtrace-malloc-check: $(shared-thread-library)
|
||||||
|
213
malloc/tst-mallocfork3.c
Normal file
213
malloc/tst-mallocfork3.c
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/* Test case for async-signal-safe _Fork (with respect to malloc).
|
||||||
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||||
|
not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
/* This test is similar to tst-mallocfork2.c, but specifically stress
|
||||||
|
the async-signal-safeness of _Fork on multithread environment. */
|
||||||
|
|
||||||
|
#include <array_length.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/support.h>
|
||||||
|
#include <support/xsignal.h>
|
||||||
|
#include <support/xthread.h>
|
||||||
|
#include <support/xunistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
/* How many malloc objects to keep arond. */
|
||||||
|
enum { malloc_objects = 1009 };
|
||||||
|
|
||||||
|
/* The maximum size of an object. */
|
||||||
|
enum { malloc_maximum_size = 70000 };
|
||||||
|
|
||||||
|
/* How many iterations the test performs before exiting. */
|
||||||
|
enum { iterations = 10000 };
|
||||||
|
|
||||||
|
/* Barrier for synchronization with the threads sending SIGUSR1
|
||||||
|
signals, to make it more likely that the signals arrive during a
|
||||||
|
fork/free/malloc call. */
|
||||||
|
static pthread_barrier_t barrier;
|
||||||
|
|
||||||
|
/* Set to 1 if SIGUSR1 is received. Used to detect a signal during
|
||||||
|
fork/free/malloc. */
|
||||||
|
static volatile sig_atomic_t sigusr1_received;
|
||||||
|
|
||||||
|
/* Periodically set to 1, to indicate that the thread is making
|
||||||
|
progress. Checked by liveness_signal_handler. */
|
||||||
|
static volatile sig_atomic_t progress_indicator = 1;
|
||||||
|
|
||||||
|
/* Set to 1 if an error occurs in the signal handler. */
|
||||||
|
static volatile sig_atomic_t error_indicator = 0;
|
||||||
|
|
||||||
|
static void
|
||||||
|
sigusr1_handler (int signo)
|
||||||
|
{
|
||||||
|
sigusr1_received = 1;
|
||||||
|
|
||||||
|
/* Perform a fork with a trivial subprocess. */
|
||||||
|
pid_t pid = _Fork ();
|
||||||
|
if (pid == -1)
|
||||||
|
{
|
||||||
|
write_message ("error: fork\n");
|
||||||
|
error_indicator = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pid == 0)
|
||||||
|
_exit (0);
|
||||||
|
int status;
|
||||||
|
int ret = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
write_message ("error: waitpid\n");
|
||||||
|
error_indicator = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (status != 0)
|
||||||
|
{
|
||||||
|
write_message ("error: unexpected exit status from subprocess\n");
|
||||||
|
error_indicator = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
liveness_signal_handler (int signo)
|
||||||
|
{
|
||||||
|
if (progress_indicator)
|
||||||
|
progress_indicator = 0;
|
||||||
|
else
|
||||||
|
write_message ("warning: thread seems to be stuck\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct signal_send_args
|
||||||
|
{
|
||||||
|
pthread_t target;
|
||||||
|
int signo;
|
||||||
|
bool sleep;
|
||||||
|
};
|
||||||
|
#define SIGNAL_SEND_GET_ARG(arg, field) \
|
||||||
|
(((struct signal_send_args *)(arg))->field)
|
||||||
|
|
||||||
|
/* Send SIGNO to the parent thread. If SLEEP, wait a second between
|
||||||
|
signals, otherwise use barriers to delay sending signals. */
|
||||||
|
static void *
|
||||||
|
signal_sender (void *args)
|
||||||
|
{
|
||||||
|
int signo = SIGNAL_SEND_GET_ARG (args, signo);
|
||||||
|
bool sleep = SIGNAL_SEND_GET_ARG (args, sleep);
|
||||||
|
|
||||||
|
pthread_t target = SIGNAL_SEND_GET_ARG (args, target);
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!sleep)
|
||||||
|
xpthread_barrier_wait (&barrier);
|
||||||
|
xpthread_kill (target, signo);
|
||||||
|
if (sleep)
|
||||||
|
usleep (1 * 1000 * 1000);
|
||||||
|
else
|
||||||
|
xpthread_barrier_wait (&barrier);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static pthread_t sigusr1_sender[5];
|
||||||
|
static pthread_t sigusr2_sender;
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
xsignal (SIGUSR1, sigusr1_handler);
|
||||||
|
xsignal (SIGUSR2, liveness_signal_handler);
|
||||||
|
|
||||||
|
pthread_t self = pthread_self ();
|
||||||
|
|
||||||
|
struct signal_send_args sigusr2_args = { self, SIGUSR2, true };
|
||||||
|
sigusr2_sender = xpthread_create (NULL, signal_sender, &sigusr2_args);
|
||||||
|
|
||||||
|
/* Send SIGUSR1 signals from several threads. Hopefully, one
|
||||||
|
signal will hit one of the ciritical functions. Use a barrier to
|
||||||
|
avoid sending signals while not running fork/free/malloc. */
|
||||||
|
struct signal_send_args sigusr1_args = { self, SIGUSR1, false };
|
||||||
|
xpthread_barrier_init (&barrier, NULL,
|
||||||
|
array_length (sigusr1_sender) + 1);
|
||||||
|
for (size_t i = 0; i < array_length (sigusr1_sender); ++i)
|
||||||
|
sigusr1_sender[i] = xpthread_create (NULL, signal_sender, &sigusr1_args);
|
||||||
|
|
||||||
|
void *objects[malloc_objects] = {};
|
||||||
|
unsigned int fork_signals = 0;
|
||||||
|
unsigned int free_signals = 0;
|
||||||
|
unsigned int malloc_signals = 0;
|
||||||
|
unsigned int seed = 1;
|
||||||
|
for (int i = 0; i < iterations; ++i)
|
||||||
|
{
|
||||||
|
progress_indicator = 1;
|
||||||
|
int slot = rand_r (&seed) % malloc_objects;
|
||||||
|
size_t size = rand_r (&seed) % malloc_maximum_size;
|
||||||
|
|
||||||
|
/* Occasionally do a fork first, to catch deadlocks there as
|
||||||
|
well (see bug 24161). */
|
||||||
|
bool do_fork = (rand_r (&seed) % 7) == 0;
|
||||||
|
|
||||||
|
xpthread_barrier_wait (&barrier);
|
||||||
|
if (do_fork)
|
||||||
|
{
|
||||||
|
sigusr1_received = 0;
|
||||||
|
pid_t pid = _Fork ();
|
||||||
|
TEST_VERIFY_EXIT (pid != -1);
|
||||||
|
if (sigusr1_received)
|
||||||
|
++fork_signals;
|
||||||
|
if (pid == 0)
|
||||||
|
_exit (0);
|
||||||
|
int status;
|
||||||
|
int ret = TEMP_FAILURE_RETRY (waitpid (pid, &status, 0));
|
||||||
|
if (ret < 0)
|
||||||
|
FAIL_EXIT1 ("waitpid: %m");
|
||||||
|
TEST_COMPARE (status, 0);
|
||||||
|
}
|
||||||
|
sigusr1_received = 0;
|
||||||
|
free (objects[slot]);
|
||||||
|
if (sigusr1_received)
|
||||||
|
++free_signals;
|
||||||
|
sigusr1_received = 0;
|
||||||
|
objects[slot] = malloc (size);
|
||||||
|
if (sigusr1_received)
|
||||||
|
++malloc_signals;
|
||||||
|
xpthread_barrier_wait (&barrier);
|
||||||
|
|
||||||
|
if (objects[slot] == NULL || error_indicator != 0)
|
||||||
|
{
|
||||||
|
printf ("error: malloc: %m\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up allocations. */
|
||||||
|
for (int slot = 0; slot < malloc_objects; ++slot)
|
||||||
|
free (objects[slot]);
|
||||||
|
|
||||||
|
printf ("info: signals received during fork: %u\n", fork_signals);
|
||||||
|
printf ("info: signals received during free: %u\n", free_signals);
|
||||||
|
printf ("info: signals received during malloc: %u\n", malloc_signals);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TIMEOUT 100
|
||||||
|
#include <support/test-driver.c>
|
@ -137,8 +137,8 @@ creating a process and making it run another program.
|
|||||||
@cindex parent process
|
@cindex parent process
|
||||||
@cindex subprocess
|
@cindex subprocess
|
||||||
A new processes is created when one of the functions
|
A new processes is created when one of the functions
|
||||||
@code{posix_spawn}, @code{fork}, or @code{vfork} is called. (The
|
@code{posix_spawn}, @code{fork}, @code{_Fork} or @code{vfork} is called.
|
||||||
@code{system} and @code{popen} also create new processes internally.)
|
(The @code{system} and @code{popen} also create new processes internally.)
|
||||||
Due to the name of the @code{fork} function, the act of creating a new
|
Due to the name of the @code{fork} function, the act of creating a new
|
||||||
process is sometimes called @dfn{forking} a process. Each new process
|
process is sometimes called @dfn{forking} a process. Each new process
|
||||||
(the @dfn{child process} or @dfn{subprocess}) is allocated a process
|
(the @dfn{child process} or @dfn{subprocess}) is allocated a process
|
||||||
@ -154,9 +154,10 @@ limited information about why the child terminated---for example, its
|
|||||||
exit status code.
|
exit status code.
|
||||||
|
|
||||||
A newly forked child process continues to execute the same program as
|
A newly forked child process continues to execute the same program as
|
||||||
its parent process, at the point where the @code{fork} call returns.
|
its parent process, at the point where the @code{fork} or @code{_Fork}
|
||||||
You can use the return value from @code{fork} to tell whether the program
|
call returns. You can use the return value from @code{fork} or
|
||||||
is running in the parent process or the child.
|
@code{_Fork} to tell whether the program is running in the parent process
|
||||||
|
or the child.
|
||||||
|
|
||||||
@cindex process image
|
@cindex process image
|
||||||
Having several processes run the same program is only occasionally
|
Having several processes run the same program is only occasionally
|
||||||
@ -248,16 +249,13 @@ It is declared in the header file @file{unistd.h}.
|
|||||||
@deftypefun pid_t fork (void)
|
@deftypefun pid_t fork (void)
|
||||||
@standards{POSIX.1, unistd.h}
|
@standards{POSIX.1, unistd.h}
|
||||||
@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}}
|
@safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{}}@acunsafe{@aculock{}}}
|
||||||
@c The nptl/.../linux implementation safely collects fork_handlers into
|
@c The posix/fork.c implementation iterates over the fork_handlers
|
||||||
@c an alloca()ed linked list and increments ref counters; it uses atomic
|
@c using a lock. It then takes the IO_list lock, resets the thread-local
|
||||||
@c ops and retries, avoiding locking altogether. It then takes the
|
@c pid, and runs fork. The parent releases the lock, and runs parent
|
||||||
@c IO_list lock, resets the thread-local pid, and runs fork. The parent
|
@c handlers, and unlocks the internal lock. The child bumps the fork
|
||||||
@c restores the thread-local pid, releases the lock, and runs parent
|
@c generation, sets the thread-local pid, resets cpu clocks, initializes
|
||||||
@c handlers, decrementing the ref count and signaling futex wait if
|
@c the robust mutex list, the stream locks, the IO_list lock, the dynamic
|
||||||
@c requested by unregister_atfork. The child bumps the fork generation,
|
@c loader lock, runs the child handlers, reseting ref counters to 1, and
|
||||||
@c sets the thread-local pid, resets cpu clocks, initializes the robust
|
|
||||||
@c mutex list, the stream locks, the IO_list lock, the dynamic loader
|
|
||||||
@c lock, runs the child handlers, reseting ref counters to 1, and
|
|
||||||
@c initializes the fork lock. These are all safe, unless atfork
|
@c initializes the fork lock. These are all safe, unless atfork
|
||||||
@c handlers themselves are unsafe.
|
@c handlers themselves are unsafe.
|
||||||
The @code{fork} function creates a new process.
|
The @code{fork} function creates a new process.
|
||||||
@ -321,6 +319,19 @@ process is cleared. (The child process inherits its mask of blocked
|
|||||||
signals and signal actions from the parent process.)
|
signals and signal actions from the parent process.)
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
@deftypefun pid_t _Fork (void)
|
||||||
|
@standards{GNU, unistd.h}
|
||||||
|
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
||||||
|
The @code{_Fork} function is similar to @code{fork}, but it does not invoke
|
||||||
|
any callbacks registered with @code{pthread_atfork}, nor does it reset
|
||||||
|
any internal state or locks (such as the @code{malloc} locks). In the
|
||||||
|
new subprocess, only async-signal-safe functions may be called, such as
|
||||||
|
@code{dup2} or @code{execve}.
|
||||||
|
|
||||||
|
The @code{_Fork} function is an async-signal-safe replacement of @code{fork}.
|
||||||
|
It is a GNU extension.
|
||||||
|
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
@deftypefun pid_t vfork (void)
|
@deftypefun pid_t vfork (void)
|
||||||
@standards{BSD, unistd.h}
|
@standards{BSD, unistd.h}
|
||||||
|
@ -130,7 +130,7 @@ test-srcs := globtest
|
|||||||
tests += wordexp-test tst-exec tst-spawn tst-spawn2 tst-spawn3
|
tests += wordexp-test tst-exec tst-spawn tst-spawn2 tst-spawn3
|
||||||
endif
|
endif
|
||||||
ifeq (yesyes,$(build-shared)$(have-thread-library))
|
ifeq (yesyes,$(build-shared)$(have-thread-library))
|
||||||
tests += tst-getopt-cancel
|
tests += tst-getopt-cancel tst-_Fork
|
||||||
endif
|
endif
|
||||||
tests-static = tst-exec-static tst-spawn-static
|
tests-static = tst-exec-static tst-spawn-static
|
||||||
tests += $(tests-static)
|
tests += $(tests-static)
|
||||||
@ -299,6 +299,7 @@ $(objpfx)ptestcases.h: PTESTS PTESTS2C.sed
|
|||||||
$(objpfx)runptests.o: $(objpfx)ptestcases.h
|
$(objpfx)runptests.o: $(objpfx)ptestcases.h
|
||||||
|
|
||||||
$(objpfx)tst-getopt-cancel: $(shared-thread-library)
|
$(objpfx)tst-getopt-cancel: $(shared-thread-library)
|
||||||
|
$(objpfx)tst-_Fork: $(shared-thread-library)
|
||||||
|
|
||||||
test-xfail-annexc = yes
|
test-xfail-annexc = yes
|
||||||
$(objpfx)annexc.out: $(objpfx)annexc
|
$(objpfx)annexc.out: $(objpfx)annexc
|
||||||
|
@ -152,6 +152,7 @@ libc {
|
|||||||
GLIBC_2.30 {
|
GLIBC_2.30 {
|
||||||
}
|
}
|
||||||
GLIBC_2.34 {
|
GLIBC_2.34 {
|
||||||
|
_Fork;
|
||||||
execveat;
|
execveat;
|
||||||
}
|
}
|
||||||
GLIBC_PRIVATE {
|
GLIBC_PRIVATE {
|
||||||
|
@ -41,7 +41,10 @@ __libc_fork (void)
|
|||||||
{
|
{
|
||||||
/* Determine if we are running multiple threads. We skip some fork
|
/* Determine if we are running multiple threads. We skip some fork
|
||||||
handlers in the single-thread case, to make fork safer to use in
|
handlers in the single-thread case, to make fork safer to use in
|
||||||
signal handlers. */
|
signal handlers. Although POSIX has dropped async-signal-safe
|
||||||
|
requirement for fork (Austin Group tracker issue #62) this is
|
||||||
|
best effort to make is async-signal-safe at least for single-thread
|
||||||
|
case. */
|
||||||
bool multiple_threads = __libc_single_threaded == 0;
|
bool multiple_threads = __libc_single_threaded == 0;
|
||||||
|
|
||||||
__run_fork_handlers (atfork_run_prepare, multiple_threads);
|
__run_fork_handlers (atfork_run_prepare, multiple_threads);
|
||||||
|
154
posix/tst-_Fork.c
Normal file
154
posix/tst-_Fork.c
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/* Basic tests for _Fork.
|
||||||
|
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <array_length.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/xsignal.h>
|
||||||
|
#include <support/temp_file.h>
|
||||||
|
#include <support/xunistd.h>
|
||||||
|
#include <support/xthread.h>
|
||||||
|
|
||||||
|
/* For single-thread, _Fork behaves like fork. */
|
||||||
|
static int
|
||||||
|
singlethread_test (void)
|
||||||
|
{
|
||||||
|
const char testdata1[] = "abcdefghijklmnopqrtuvwxz";
|
||||||
|
enum { testdatalen1 = array_length (testdata1) };
|
||||||
|
const char testdata2[] = "01234567890";
|
||||||
|
enum { testdatalen2 = array_length (testdata2) };
|
||||||
|
|
||||||
|
pid_t ppid = getpid ();
|
||||||
|
|
||||||
|
int tempfd = create_temp_file ("tst-_Fork", NULL);
|
||||||
|
|
||||||
|
/* Check if the opened file is shared between process by read and write
|
||||||
|
some data on parent and child processes. */
|
||||||
|
xwrite (tempfd, testdata1, testdatalen1);
|
||||||
|
off_t off = xlseek (tempfd, 0, SEEK_CUR);
|
||||||
|
TEST_COMPARE (off, testdatalen1);
|
||||||
|
|
||||||
|
pid_t pid = _Fork ();
|
||||||
|
TEST_VERIFY_EXIT (pid != -1);
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
TEST_VERIFY_EXIT (getpid () != ppid);
|
||||||
|
TEST_COMPARE (getppid(), ppid);
|
||||||
|
|
||||||
|
TEST_COMPARE (xlseek (tempfd, 0, SEEK_CUR), testdatalen1);
|
||||||
|
|
||||||
|
xlseek (tempfd, 0, SEEK_SET);
|
||||||
|
char buf[testdatalen1];
|
||||||
|
TEST_COMPARE (read (tempfd, buf, sizeof (buf)), testdatalen1);
|
||||||
|
TEST_COMPARE_BLOB (buf, testdatalen1, testdata1, testdatalen1);
|
||||||
|
|
||||||
|
xlseek (tempfd, 0, SEEK_SET);
|
||||||
|
xwrite (tempfd, testdata2, testdatalen2);
|
||||||
|
|
||||||
|
xclose (tempfd);
|
||||||
|
|
||||||
|
_exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int status;
|
||||||
|
xwaitpid (pid, &status, 0);
|
||||||
|
TEST_VERIFY (WIFEXITED (status));
|
||||||
|
TEST_COMPARE (WEXITSTATUS (status), EXIT_SUCCESS);
|
||||||
|
|
||||||
|
TEST_COMPARE (xlseek (tempfd, 0, SEEK_CUR), testdatalen2);
|
||||||
|
|
||||||
|
xlseek (tempfd, 0, SEEK_SET);
|
||||||
|
char buf[testdatalen2];
|
||||||
|
TEST_COMPARE (read (tempfd, buf, sizeof (buf)), testdatalen2);
|
||||||
|
|
||||||
|
TEST_COMPARE_BLOB (buf, testdatalen2, testdata2, testdatalen2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static volatile sig_atomic_t sigusr1_handler_ran;
|
||||||
|
#define SIG_PID_EXIT_CODE 20
|
||||||
|
|
||||||
|
static bool atfork_prepare_var;
|
||||||
|
static bool atfork_parent_var;
|
||||||
|
static bool atfork_child_var;
|
||||||
|
|
||||||
|
static void
|
||||||
|
atfork_prepare (void)
|
||||||
|
{
|
||||||
|
atfork_prepare_var = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
atfork_parent (void)
|
||||||
|
{
|
||||||
|
atfork_parent_var = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
atfork_child (void)
|
||||||
|
{
|
||||||
|
atfork_child_var = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Different than fork, _Fork does not execute any pthread_atfork
|
||||||
|
handlers. */
|
||||||
|
static int
|
||||||
|
singlethread_atfork_test (void)
|
||||||
|
{
|
||||||
|
pthread_atfork (atfork_prepare, atfork_parent, atfork_child);
|
||||||
|
singlethread_test ();
|
||||||
|
TEST_VERIFY (!atfork_prepare_var);
|
||||||
|
TEST_VERIFY (!atfork_parent_var);
|
||||||
|
TEST_VERIFY (!atfork_child_var);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
mt_atfork_test (void *args)
|
||||||
|
{
|
||||||
|
singlethread_atfork_test ();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
multithread_atfork_test (void)
|
||||||
|
{
|
||||||
|
pthread_t thr = xpthread_create (NULL, mt_atfork_test, NULL);
|
||||||
|
xpthread_join (thr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
singlethread_atfork_test ();
|
||||||
|
multithread_atfork_test ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <support/test-driver.c>
|
@ -781,6 +781,13 @@ extern __pid_t fork (void) __THROWNL;
|
|||||||
extern __pid_t vfork (void) __THROW;
|
extern __pid_t vfork (void) __THROW;
|
||||||
#endif /* Use misc or XPG < 7. */
|
#endif /* Use misc or XPG < 7. */
|
||||||
|
|
||||||
|
#ifdef __USE_GNU
|
||||||
|
/* This is similar to fork, however it does not run the atfork handlers
|
||||||
|
neither reinitialize any internal locks in multithread case.
|
||||||
|
Different than fork, _Fork is async-signal-safe. */
|
||||||
|
extern __pid_t _Fork (void) __THROW;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Return the pathname of the terminal FD is open on, or NULL on errors.
|
/* Return the pathname of the terminal FD is open on, or NULL on errors.
|
||||||
The returned storage is good only until the next call to this function. */
|
The returned storage is good only until the next call to this function. */
|
||||||
|
@ -2215,6 +2215,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __isnanf128 F
|
GLIBC_2.34 __isnanf128 F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 _hurd_libc_proc_init F
|
GLIBC_2.34 _hurd_libc_proc_init F
|
||||||
|
@ -2369,6 +2369,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2468,6 +2468,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2128,6 +2128,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -190,6 +190,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -187,6 +187,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2312,6 +2312,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2265,6 +2265,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2448,6 +2448,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2305,6 +2305,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __isnanf128 F
|
GLIBC_2.34 __isnanf128 F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
|
@ -191,6 +191,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2392,6 +2392,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2363,6 +2363,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2360,6 +2360,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2357,6 +2357,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2355,6 +2355,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2363,6 +2363,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2357,6 +2357,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2402,6 +2402,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2419,6 +2419,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2452,6 +2452,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2270,6 +2270,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2564,6 +2564,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __isnanf128 F
|
GLIBC_2.34 __isnanf128 F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
|
@ -2130,6 +2130,7 @@ GLIBC_2.33 wprintf F
|
|||||||
GLIBC_2.33 write F
|
GLIBC_2.33 write F
|
||||||
GLIBC_2.33 writev F
|
GLIBC_2.33 writev F
|
||||||
GLIBC_2.33 wscanf F
|
GLIBC_2.33 wscanf F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2330,6 +2330,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2417,6 +2417,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2307,6 +2307,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2272,6 +2272,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2269,6 +2269,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2412,6 +2412,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 ___adjtimex64 F
|
GLIBC_2.34 ___adjtimex64 F
|
||||||
GLIBC_2.34 __adjtime64 F
|
GLIBC_2.34 __adjtime64 F
|
||||||
GLIBC_2.34 __aio_suspend_time64 F
|
GLIBC_2.34 __aio_suspend_time64 F
|
||||||
|
@ -2329,6 +2329,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
GLIBC_2.34 __pthread_cleanup_routine F
|
GLIBC_2.34 __pthread_cleanup_routine F
|
||||||
|
@ -2284,6 +2284,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __isnanf128 F
|
GLIBC_2.34 __isnanf128 F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
|
@ -2383,6 +2383,7 @@ GLIBC_2.33 mknod F
|
|||||||
GLIBC_2.33 mknodat F
|
GLIBC_2.33 mknodat F
|
||||||
GLIBC_2.33 stat F
|
GLIBC_2.33 stat F
|
||||||
GLIBC_2.33 stat64 F
|
GLIBC_2.33 stat64 F
|
||||||
|
GLIBC_2.34 _Fork F
|
||||||
GLIBC_2.34 __isnanf128 F
|
GLIBC_2.34 __isnanf128 F
|
||||||
GLIBC_2.34 __libc_start_main F
|
GLIBC_2.34 __libc_start_main F
|
||||||
GLIBC_2.34 __mq_open_2 F
|
GLIBC_2.34 __mq_open_2 F
|
||||||
|
Loading…
Reference in New Issue
Block a user