Skip to content

Commit e36f9e1

Browse files
committed
[libc++] Allow enabling assertions when back-deploying
When back-deploying to older platforms, we can still provide assertions, but we might not be able to provide a great implementation for the verbose handler. Instead, we can just call ::abort(). Differential Revision: https://reviews.llvm.org/D131199
1 parent 7dc410c commit e36f9e1

9 files changed

+94
-68
lines changed

libcxx/docs/UsingLibcxx.rst

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,14 @@ value for ``_LIBCPP_ENABLE_ASSERTIONS`` (if any) will usually be respected.
155155
When an assertion fails, the program is aborted through a special verbose termination function. The
156156
library provides a default function that prints an error message and calls ``std::abort()``. Note
157157
that this function is provided by the static or shared library, so it is only available when deploying
158-
to a platform where the compiled library is sufficiently recent. However, users can also override that
159-
function with their own, which can be useful to provide custom behavior, or when deploying to older
160-
platforms where the default function isn't available.
158+
to a platform where the compiled library is sufficiently recent. On older platforms, the program will
159+
terminate in an unspecified unsuccessful manner, but the quality of diagnostics won't be great.
160+
However, users can also override that function with their own, which can be useful to either provide
161+
custom behavior or when deploying to an older platform where the default function isn't available.
161162

162-
Replacing the default verbose termination function is done by defining the following function:
163+
Replacing the default verbose termination function is done by defining the
164+
``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED`` macro in all translation units of your program
165+
and defining the following function in exactly one translation unit:
163166

164167
.. code-block:: cpp
165168
@@ -198,20 +201,6 @@ Furthermore, exceptions should not be thrown from the function. Indeed, many fun
198201
library are ``noexcept``, and any exception thrown from the termination function will result
199202
in ``std::terminate`` being called.
200203

201-
Back-deploying with a custom verbose termination function
202-
---------------------------------------------------------
203-
When deploying to an older platform that does not provide a default verbose termination function,
204-
the compiler will diagnose the usage of ``std::__libcpp_verbose_abort`` with an error. This is done
205-
to avoid the load-time error that would otherwise happen if the code was being deployed on older
206-
systems.
207-
208-
If you are providing a custom verbose termination function, this error is effectively a false positive.
209-
To let the library know that you are providing a custom function in back-deployment scenarios, you must
210-
define the ``_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED`` macro, and the library will assume that
211-
you are providing your own definition. If no definition is provided and the code is back-deployed to an older
212-
platform, it will fail to load when the dynamic linker fails to find a definition of the function, so you
213-
should only remove the guard rails if you really mean it!
214-
215204
Libc++ Configuration Macros
216205
===========================
217206

libcxx/include/__availability

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,11 @@
166166
// user has provided their own).
167167
//
168168
// Users can pass -D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED
169-
// to the compiler to tell the library to ignore the fact that the
170-
// default function isn't available on their deployment target. Note that
171-
// defining this macro but failing to define a custom function will lead to
172-
// a load-time error on back-deployment targets, so it should be avoided.
173-
# define _LIBCPP_AVAILABILITY_DEFAULT_VERBOSE_ABORT
169+
// to the compiler to tell the library not to define its own verbose abort.
170+
// Note that defining this macro but failing to define a custom function
171+
// will lead to a load-time error on back-deployment targets, so it should
172+
// be avoided.
173+
// # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
174174

175175
#elif defined(__APPLE__)
176176

@@ -271,8 +271,8 @@
271271
__attribute__((unavailable))
272272
# define _LIBCPP_AVAILABILITY_DISABLE_FTM___cpp_lib_format
273273

274-
# define _LIBCPP_AVAILABILITY_DEFAULT_VERBOSE_ABORT \
275-
__attribute__((unavailable))
274+
# define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY
275+
276276
#else
277277

278278
// ...New vendors can add availability markup here...
@@ -296,14 +296,4 @@
296296
# define _LIBCPP_AVAILABILITY_THROW_BAD_VARIANT_ACCESS _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS
297297
#endif
298298

299-
// Define the special verbose termination function availability attribute, which can be silenced by
300-
// users if they provide their own custom function. The rest of the code should not use the
301-
// *_DEFAULT_* macro directly, since that would make it ignore the fact that the user provided
302-
// a custom function.
303-
#if defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
304-
# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT /* nothing */
305-
#else
306-
# define _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_AVAILABILITY_DEFAULT_VERBOSE_ABORT
307-
#endif
308-
309299
#endif // _LIBCPP___AVAILABILITY

libcxx/include/__verbose_abort

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,34 @@
1717
# pragma GCC system_header
1818
#endif
1919

20+
// Provide a default implementation of __libcpp_verbose_abort if we know that neither the built
21+
// library not the user is providing one. Otherwise, just declare it and use the one from the
22+
// built library or the one provided by the user.
23+
//
24+
// We can't provide a great implementation because it needs to be pretty much
25+
// dependency-free (this is included everywhere else in the library).
26+
#if defined(_LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY) && !defined(_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED)
27+
28+
extern "C" void abort();
29+
2030
_LIBCPP_BEGIN_NAMESPACE_STD
2131

22-
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_AVAILABILITY_VERBOSE_ABORT _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
32+
_LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) _LIBCPP_HIDE_FROM_ABI inline
33+
void __libcpp_verbose_abort(const char *, ...) {
34+
::abort();
35+
}
36+
37+
_LIBCPP_END_NAMESPACE_STD
38+
39+
#else
40+
41+
_LIBCPP_BEGIN_NAMESPACE_STD
42+
43+
_LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2)
2344
void __libcpp_verbose_abort(const char *__format, ...);
2445

2546
_LIBCPP_END_NAMESPACE_STD
2647

48+
#endif
49+
2750
#endif // _LIBCPP___VERBOSE_ABORT

libcxx/test/libcxx/assertions/default_verbose_abort.availability.verify.cpp

Lines changed: 0 additions & 20 deletions
This file was deleted.

libcxx/test/libcxx/assertions/default_verbose_abort.pass.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@
1010

1111
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
1212

13-
// We flag uses of the verbose termination function in older dylibs at compile-time to avoid runtime
14-
// failures when back-deploying.
15-
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
16-
1713
#include <csignal>
1814
#include <cstdlib>
1915

libcxx/test/libcxx/assertions/headers_declare_verbose_abort.sh.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88

99
// Test that all public C++ headers define the verbose termination function.
1010

11-
// We flag uses of the verbose termination function in older dylibs at compile-time to avoid runtime
12-
// failures when back-deploying.
13-
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
14-
1511
// The system-provided <uchar.h> seems to be broken on AIX, which trips up this test.
1612
// XFAIL: LIBCXX-AIX-FIXME
1713

libcxx/test/libcxx/assertions/single_expression.sh.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@
1818
// RUN: %{build} -Wno-macro-redefined -D_LIBCPP_ENABLE_ASSERTIONS=0 -D_LIBCPP_ASSERTIONS_DISABLE_ASSUME
1919
// RUN: %{run}
2020

21-
// We flag uses of the assertion handler in older dylibs at compile-time to avoid runtime
22-
// failures when back-deploying.
23-
// XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11.0|12.0}}
24-
2521
#include <__assert>
2622
#include <cassert>
2723

libcxx/utils/ci/buildkite-pipeline.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,20 @@ steps:
725725
limit: 2
726726
timeout_in_minutes: 120
727727

728+
- label: "Apple back-deployment with assertions enabled"
729+
command: "libcxx/utils/ci/run-buildbot apple-system-backdeployment-assertions-11.0"
730+
artifact_paths:
731+
- "**/test-results.xml"
732+
- "**/*.abilist"
733+
agents:
734+
queue: "libcxx-builders"
735+
os: "macos"
736+
retry:
737+
automatic:
738+
- exit_status: -1 # Agent was lost
739+
limit: 2
740+
timeout_in_minutes: 120
741+
728742
- group: "ARM"
729743
steps:
730744
- label: "AArch64"

libcxx/utils/ci/run-buildbot

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,48 @@ apple-system)
385385
# TODO: It would be better to run the tests against the fake-installed version of libc++ instead
386386
xcrun --sdk macosx ninja -vC "${BUILD_DIR}/${arch}" check-cxx check-cxxabi check-cxx-abilist
387387
;;
388+
apple-system-backdeployment-assertions-*)
389+
clean
390+
391+
if [[ "${OSX_ROOTS}" == "" ]]; then
392+
echo "--- Downloading previous macOS dylibs"
393+
PREVIOUS_DYLIBS_URL="https://dl.dropboxusercontent.com/s/gmcfxwgl9f9n6pu/libcxx-roots.tar.gz"
394+
OSX_ROOTS="${BUILD_DIR}/macos-roots"
395+
mkdir -p "${OSX_ROOTS}"
396+
curl "${PREVIOUS_DYLIBS_URL}" | tar -xz --strip-components=1 -C "${OSX_ROOTS}"
397+
fi
398+
399+
DEPLOYMENT_TARGET="${BUILDER#apple-system-backdeployment-assertions-}"
400+
401+
# TODO: On Apple platforms, we never produce libc++abi.1.dylib or libunwind.1.dylib,
402+
# only libc++abi.dylib and libunwind.dylib. Fix that in the build so that the
403+
# tests stop searching for @rpath/libc++abi.1.dylib and @rpath/libunwind.1.dylib.
404+
cp "${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.dylib" \
405+
"${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}/libc++abi.1.dylib"
406+
cp "${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.dylib" \
407+
"${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}/libunwind.1.dylib"
408+
409+
arch="$(uname -m)"
410+
PARAMS="target_triple=${arch}-apple-macosx${DEPLOYMENT_TARGET}"
411+
PARAMS+=";cxx_runtime_root=${OSX_ROOTS}/macOS/libc++/${DEPLOYMENT_TARGET}"
412+
PARAMS+=";abi_runtime_root=${OSX_ROOTS}/macOS/libc++abi/${DEPLOYMENT_TARGET}"
413+
PARAMS+=";unwind_runtime_root=${OSX_ROOTS}/macOS/libunwind/${DEPLOYMENT_TARGET}"
414+
PARAMS+=";use_system_cxx_lib=True"
415+
PARAMS+=";enable_assertions=True"
416+
# TODO: Enable experimental features during back-deployment -- right now some of the availability
417+
# annotations are incorrect, leading to test failures that could be avoided.
418+
PARAMS+=";enable_experimental=False"
419+
420+
generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Apple.cmake" \
421+
-DLIBCXX_TEST_CONFIG="apple-libc++-backdeployment.cfg.in" \
422+
-DLIBCXXABI_TEST_CONFIG="apple-libc++abi-backdeployment.cfg.in" \
423+
-DLIBUNWIND_TEST_CONFIG="apple-libunwind-backdeployment.cfg.in" \
424+
-DLIBCXX_TEST_PARAMS="${PARAMS}" \
425+
-DLIBCXXABI_TEST_PARAMS="${PARAMS}" \
426+
-DLIBUNWIND_TEST_PARAMS="${PARAMS}"
427+
428+
check-runtimes
429+
;;
388430
apple-system-backdeployment-*)
389431
clean
390432

0 commit comments

Comments
 (0)