Skip to content

Commit b211dec

Browse files
committed
Address feedback
1 parent c2442a3 commit b211dec

File tree

2 files changed

+75
-44
lines changed

2 files changed

+75
-44
lines changed

libcxx/docs/Hardening.rst

Lines changed: 30 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ built with and the default hardening mode that users will build with. If set to
8686
``none``, the precompiled library will not contain any assertions, and user code
8787
will default to building without assertions.
8888

89-
Vendors can also override the termination handler by :ref:`providing a custom
90-
header <override-assertion-handler>`.
89+
Vendors can also override the way the program is terminated when an assertion
90+
fails by :ref:`providing a custom header <override-assertion-handler>`.
9191

9292
Assertion categories
9393
====================
@@ -97,6 +97,11 @@ Inside the library, individual assertions are grouped into different
9797
categories; categories provide an additional layer of abstraction that makes it
9898
easier to reason about the high-level semantics of a hardening mode.
9999

100+
.. note::
101+
102+
Users are not intended to interact with these categories directly -- the
103+
categories are considered internal to the library and subject to change.
104+
100105
- ``valid-element-access`` -- checks that any attempts to access a container
101106
element, whether through the container object or through an iterator, are
102107
valid and do not attempt to go out of bounds or otherwise access
@@ -151,7 +156,7 @@ easier to reason about the high-level semantics of a hardening mode.
151156
code.
152157

153158
- ``pedantic`` -- checks preconditions that are imposed by the Standard, but
154-
violating which happens to be benign in our implementation.
159+
violating which happens to be benign in libc++.
155160

156161
- ``semantic-requirement`` -- checks that the given argument satisfies the
157162
semantic requirements imposed by the Standard. Typically, there is no simple
@@ -232,6 +237,13 @@ Mapping between the hardening modes and the assertion categories
232237
assertion categories without disabling any), but this won't necessarily be
233238
true for any hardening modes that might be added in the future.
234239

240+
.. note::
241+
242+
The categories enabled by each mode are subject to change and users should not
243+
rely on the precise assertions enabled by a mode at a given point in time.
244+
However, the library does guarantee to keep the hardening modes stable and
245+
to fulfill the semantics documented here.
246+
235247
Hardening assertion failure
236248
===========================
237249

@@ -248,15 +260,15 @@ In the ``debug`` mode, an assertion failure terminates the program in an
248260
unspecified manner and also outputs the associated error message to the error
249261
output. This is less secure and increases the size of the binary (among other
250262
things, it has to store the error message strings) but makes the failure easier
251-
to debug. It also allows us to test the error messages in our test suite.
263+
to debug. It also allows testing the error messages in our test suite.
252264

253265
.. _override-assertion-handler:
254266

255267
Overriding the assertion failure handler
256268
----------------------------------------
257269

258-
Vendors can override the default termination handler mechanism by following
259-
these steps:
270+
Vendors can override the default assertion handler mechanism by following these
271+
steps:
260272

261273
- create a header file that provides a definition of a macro called
262274
``_LIBCPP_ASSERTION_HANDLER``. The macro will be invoked when a hardening
@@ -266,7 +278,17 @@ these steps:
266278
the root of the repository) via the CMake variable
267279
``LIBCXX_ASSERTION_HANDLER_FILE``.
268280

269-
There is no existing mechanism for users to override the termination handler.
281+
Note that almost all libc++ headers include the assertion handler header which
282+
means it should not include anything from the standard library to avoid creating
283+
circular dependencies.
284+
285+
There is no existing mechanism for users to override the assertion handler
286+
because the ability to do the override other than at configure-time carries an
287+
unavoidable code size penalty that would otherwise be imposed on all users,
288+
whether they require such customization or not. Instead, we let vendors decide
289+
what's right on their platform for their users -- a vendor who wishes to provide
290+
this capability is free to do so, e.g. by declaring the assertion handler as an
291+
overridable function.
270292

271293
ABI
272294
===
@@ -369,43 +391,7 @@ TODO(hardening): make this table exhaustive.
369391
Testing
370392
=======
371393

372-
Each hardening assertion should be tested using death tests (via the
373-
``TEST_LIBCPP_ASSERT_FAILURE`` macro). Use the ``libcpp-hardening-mode`` Lit
374-
feature to make sure the assertion is enabled in (and only in) the intended
375-
modes. The convention is to use `assert.` in the name of the test file to make
376-
it easier to identify as a hardening test, e.g. ``assert.my_func.pass.cpp``.
377-
A toy example:
378-
379-
.. code-block:: cpp
380-
381-
// Note: the following three annotations are currently needed to use the
382-
// `TEST_LIBCPP_ASSERT_FAILURE`.
383-
// REQUIRES: has-unix-headers
384-
// UNSUPPORTED: c++03
385-
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
386-
387-
// Example: only run this test in `fast`/`extensive`/`debug` modes.
388-
// UNSUPPORTED: libcpp-hardening-mode=none
389-
// Example: only run this test in the `debug` mode.
390-
// REQUIRES: libcpp-hardening-mode=debug
391-
// Example: only run this test in `extensive`/`debug` modes.
392-
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
393-
394-
#include <header_being_tested>
395-
396-
#include "check_assertion.h" // Contains the `TEST_LIBCPP_ASSERT_FAILURE` macro
397-
398-
int main(int, char**) {
399-
std::type_being_tested foo;
400-
int bad_input = -1;
401-
TEST_LIBCPP_ASSERT_FAILURE(foo.some_function_that_asserts(bad_input),
402-
"The expected assertion message");
403-
404-
return 0;
405-
}
406-
407-
Note that error messages are only tested (matched) if the ``debug``
408-
hardening mode is used.
394+
Please see :ref:`Testing documentation <testing-hardening-assertions>`.
409395

410396
Further reading
411397
===============

libcxx/docs/TestingLibcxx.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,48 @@ For example:
480480
$ ./algorithms.libcxx.out --benchmark_filter=BM_Sort.* # Only runs the sort benchmarks
481481
482482
For more information about running benchmarks see `Google Benchmark`_.
483+
484+
485+
.. _testing-hardening-assertions:
486+
487+
Testing hardening assertions
488+
============================
489+
490+
Each hardening assertion should be tested using death tests (via the
491+
``TEST_LIBCPP_ASSERT_FAILURE`` macro). Use the ``libcpp-hardening-mode`` Lit
492+
feature to make sure the assertion is enabled in (and only in) the intended
493+
modes. The convention is to use `assert.` in the name of the test file to make
494+
it easier to identify as a hardening test, e.g. ``assert.my_func.pass.cpp``.
495+
A toy example:
496+
497+
.. code-block:: cpp
498+
499+
// Note: the following three annotations are currently needed to use the
500+
// `TEST_LIBCPP_ASSERT_FAILURE`.
501+
// REQUIRES: has-unix-headers
502+
// UNSUPPORTED: c++03
503+
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing
504+
505+
// Example: only run this test in `fast`/`extensive`/`debug` modes.
506+
// UNSUPPORTED: libcpp-hardening-mode=none
507+
// Example: only run this test in the `debug` mode.
508+
// REQUIRES: libcpp-hardening-mode=debug
509+
// Example: only run this test in `extensive`/`debug` modes.
510+
// REQUIRES: libcpp-hardening-mode={{extensive|debug}}
511+
512+
#include <header_being_tested>
513+
514+
#include "check_assertion.h" // Contains the `TEST_LIBCPP_ASSERT_FAILURE` macro
515+
516+
int main(int, char**) {
517+
std::type_being_tested foo;
518+
int bad_input = -1;
519+
TEST_LIBCPP_ASSERT_FAILURE(foo.some_function_that_asserts(bad_input),
520+
"The expected assertion message");
521+
522+
return 0;
523+
}
524+
525+
Note that error messages are only tested (matched) if the ``debug``
526+
hardening mode is used.
527+

0 commit comments

Comments
 (0)