Bug 20198: quick_exit should not call destructors.

In C++11 18.5.12 says "Objects shall not be destroyed as a
result of calling quick_exit." In C11 quick_exit is silent
about thread object destruction. Therefore to make glibc
C++ compliant we do not call any thread local destructors.
A new regression test verifies the fix.

I will note that C++11 18.5.3 makes it clear that C++
defines additional requirements for _Exit() to prevent it
from executing destructors.

Given that the point of _Exit() is to terminate the process
immediately it makes sense the C and C++ should line up
and avoid calling destructors.

No failures. New regtest passes.
This commit is contained in:
Carlos O'Donell 2016-06-06 14:20:58 -04:00
parent 3f61232ab3
commit 47dd3543d3
37 changed files with 216 additions and 9 deletions

View File

@ -1,3 +1,57 @@
2016-06-03 Carlos O'Donell <carlos@redhat.com>
[BZ #20198]
* stdlib/Makefile (tests): Add tst-quick_exit, and
tst-thread-quick_exit.
[ifeq ($(have-cxx-thread_local),yes)]
(CFLAGS-tst-quick_exit.o): Use -stdc=c++11.
(CFLAGS-tst-thread-quick_exit.o): Likewise.
(LDLIBS-tst-quick_exit): Use -lstdc++ for C++ program.
(LDLIBS-tst-thread-quick_exit): Likewise.
[ifneq ($(have-cxx-thread_local),yes)]
(tests-unsupported): Add tst-quick_exit, and tst-thread-quick_exit.
* stdlib/exit.c (__run_exit_handlers): Add run_dtors argument.
If run_dtors is true call __call_tls_dtors.
(exit): Call __run_exit_handlers with run_dtors set to true.
* stdlib/exit.h: Add run_dtors argument to __run_exit_handlers
definition.
* stdlib/quick_exit.c (quick_exit): Remove function.
(__new_quick_exit): New function.
[SHLIB_COMPAT(libc, GLIBC_2_10, GLIBC_2_24)] (__old_quick_exit): New
function.
* stdlib/tst-quick_exit.cc: New file.
* stdlib/tst-thread-quick_exit.cc: New file.
* stdlib/Versions: Add quick_exit@GLIBC_2.24.
* sysdeps/arm/nacl/libc.abilist: Add 'GLIBC_2.24 quick_exit F'.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise
2016-06-06 H.J. Lu <hongjiu.lu@intel.com>
* sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: Fix

View File

@ -76,8 +76,18 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
tst-secure-getenv tst-strtod-overflow tst-strtod-round \
tst-tininess tst-strtod-underflow tst-tls-atexit \
tst-setcontext3 tst-tls-atexit-nodelete \
tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l
tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l \
tst-quick_exit tst-thread-quick_exit
tests-static := tst-secure-getenv
ifeq ($(have-cxx-thread_local),yes)
CFLAGS-tst-quick_exit.o = -std=c++11
LDLIBS-tst-quick_exit = -lstdc++
CFLAGS-tst-thread-quick_exit.o = -std=c++11
LDLIBS-tst-thread-quick_exit = -lstdc++
$(objpfx)tst-thread-quick_exit: $(shared-thread-library)
else
tests-unsupported += tst-quick_exit tst-thread-quick_exit
endif
modules-names = tst-tls-atexit-lib
extra-test-objs += $(addsuffix .os, $(modules-names))

View File

@ -109,6 +109,9 @@ libc {
GLIBC_2.18 {
__cxa_thread_atexit_impl;
}
GLIBC_2.24 {
quick_exit;
}
GLIBC_PRIVATE {
# functions which have an additional interface since they are
# are cancelable.

View File

@ -31,13 +31,14 @@ DEFINE_HOOK (__libc_atexit, (void))
void
attribute_hidden
__run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit)
bool run_list_atexit, bool run_dtors)
{
/* First, call the TLS destructors. */
#ifndef SHARED
if (&__call_tls_dtors != NULL)
#endif
__call_tls_dtors ();
if (run_dtors)
__call_tls_dtors ();
/* We do it this way to handle recursive calls to exit () made by
the functions registered with `atexit' and `on_exit'. We call
@ -101,6 +102,6 @@ __run_exit_handlers (int status, struct exit_function_list **listp,
void
exit (int status)
{
__run_exit_handlers (status, &__exit_funcs, true);
__run_exit_handlers (status, &__exit_funcs, true, true);
}
libc_hidden_def (exit)

View File

@ -63,8 +63,9 @@ extern struct exit_function_list *__quick_exit_funcs attribute_hidden;
extern struct exit_function *__new_exitfn (struct exit_function_list **listp);
extern uint64_t __new_exitfn_called attribute_hidden;
extern void __run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit)
extern void __run_exit_handlers (int status,
struct exit_function_list **listp,
bool run_list_atexit, bool run_dtors)
attribute_hidden __attribute__ ((__noreturn__));
extern int __internal_atexit (void (*func) (void *), void *arg, void *d,

View File

@ -19,11 +19,30 @@
#include <stdlib.h>
#include <unistd.h>
#include <sysdep.h>
#include <signal.h>
#include <errno.h>
#include <shlib-compat.h>
#include "exit.h"
void
quick_exit (int status)
__new_quick_exit (int status)
{
__run_exit_handlers (status, &__quick_exit_funcs, false);
/* The new quick_exit, following C++11 18.5.12, does not run object
destructors. While C11 says nothing about object destructors,
since it has none, the intent is to run the registered
at_quick_exit handlers and then run _Exit immediately without
disturbing the state of the process and threads. */
__run_exit_handlers (status, &__quick_exit_funcs, false, false);
}
versioned_symbol (libc, __new_quick_exit, quick_exit, GLIBC_2_24);
#if SHLIB_COMPAT(libc, GLIBC_2_10, GLIBC_2_24)
void
attribute_compat_text_section
__old_quick_exit (int status)
{
/* The old quick_exit runs thread_local destructors. */
__run_exit_handlers (status, &__quick_exit_funcs, false, true);
}
compat_symbol (libc, __old_quick_exit, quick_exit, GLIBC_2_10);
#endif

40
stdlib/tst-quick_exit.cc Normal file
View File

@ -0,0 +1,40 @@
/* Bug 20198: Do not call object destructors at exit.
Copyright (C) 2016 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
<http://www.gnu.org/licenses/>. */
#include <cstdlib>
struct A
{
~A() { abort(); }
};
thread_local A a;
static int
do_test()
{
(void)a;
/* The C++11 standard in 18.5.12 says:
"Objects shall not be destroyed as a result of calling
quick_exit."
If quick_exit calls the destructors the test aborts. */
std::quick_exit(0);
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -0,0 +1,50 @@
/* Bug 20198: Do not call object destructors at exit.
Copyright (C) 2016 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
<http://www.gnu.org/licenses/>. */
#include <cstdlib>
#include <thread>
struct A
{
~A() { abort(); }
};
thread_local A a1;
thread_local A a2;
/* Call std::quick_exit from a non-main thread. */
void non_main_thread (void)
{
(void)a1;
/* The C++11 standard in 18.5.12 says:
"Objects shall not be destroyed as a result of calling
quick_exit."
If quick_exit calls the destructors the test aborts. */
std::quick_exit (0);
}
static int
do_test()
{
(void)a2;
std::thread th (non_main_thread);
th.join ();
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -1840,3 +1840,4 @@ GLIBC_2.23 fts64_close F
GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 quick_exit F

View File

@ -2088,6 +2088,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -1999,6 +1999,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -89,6 +89,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.4 GLIBC_2.4 A

View File

@ -1853,6 +1853,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -2011,6 +2011,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1875,6 +1875,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -90,6 +90,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.4 GLIBC_2.4 A

View File

@ -1967,6 +1967,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -2088,5 +2088,6 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F

View File

@ -1942,6 +1942,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1940,6 +1940,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1938,6 +1938,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1933,6 +1933,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -2129,5 +2129,6 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F

View File

@ -1971,6 +1971,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1976,6 +1976,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -2176,6 +2176,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -90,6 +90,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -1971,6 +1971,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1872,6 +1872,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -1857,6 +1857,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1963,6 +1963,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F
GLIBC_2.3 GLIBC_2.3 A

View File

@ -1901,6 +1901,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -2095,5 +2095,6 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F

View File

@ -2095,6 +2095,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -2095,5 +2095,6 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F

View File

@ -1852,6 +1852,7 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmmsg F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmmsg F

View File

@ -2095,5 +2095,6 @@ GLIBC_2.23 fts64_open F
GLIBC_2.23 fts64_read F
GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.24 recvmsg F
GLIBC_2.24 sendmsg F