Louis Dionne bf68a595f6 [libc++] Start classifying debug mode features with more granularity
I am starting to granularize debug-mode checks so they can be controlled
more individually. The goal is for vendors to eventually be able to select
which categories of checks they want embedded in their configuration of
the library with more granularity.

Note that this patch is a bit weird on its own because it does not touch
any of the containers that implement iterator bounds checking through the
__dereferenceable check of the legacy debug mode. However, I added TODOs
to string and vector to change that.

Differential Revision: https://reviews.llvm.org/D138033
2022-11-15 11:18:22 -05:00

72 lines
3.2 KiB
ReStructuredText

==========
Debug Mode
==========
.. contents::
:local:
.. _using-debug-mode:
Using the debug mode
====================
Libc++ provides a debug mode that enables special debugging checks meant to detect
incorrect usage of the standard library. These checks are disabled by default, but
they can be enabled by vendors when building the library by using ``LIBCXX_ENABLE_DEBUG_MODE``.
Since the debug mode has ABI implications, users should compile their whole program,
including any dependent libraries, against a Standard library configured identically
with respect to the debug mode. In other words, they should not mix code built against
a Standard library with the debug mode enabled with code built against a Standard library
where the debug mode is disabled.
Furthermore, users should not rely on a stable ABI being provided when the debug mode is
enabled -- we reserve the right to change the ABI at any time. If you need a stable ABI
and still want some level of hardening, you should look into enabling :ref:`assertions <assertions-mode>`
instead.
The debug mode provides various checks to aid application debugging.
Comparator consistency checks
-----------------------------
Libc++ provides some checks for the consistency of comparators passed to algorithms. Specifically,
many algorithms such as ``binary_search``, ``merge``, ``next_permutation``, and ``sort``, wrap the
user-provided comparator to assert that `!comp(y, x)` whenever `comp(x, y)`. This can cause the
user-provided comparator to be evaluated up to twice as many times as it would be without the
debug mode, and causes the library to violate some of the Standard's complexity clauses.
Iterator bounds checking
------------------------
The library provides iterators that ensure they are within the bounds of their container when dereferenced.
Arithmetic can be performed on these iterators to create out-of-bounds iterators, but they cannot be dereferenced
when out-of-bounds. The following classes currently provide iterators that have bounds checking:
- ``std::string``
- ``std::vector<T>`` (``T != bool``)
- ``std::span``
.. TODO: Add support for iterator bounds checking in ``std::string_view`` and ``std::array``
Iterator ownership checking
---------------------------
The library provides iterator ownership checking, which allows catching cases where e.g.
an iterator from container ``X`` is used as a position to insert into container ``Y``.
The following classes support iterator ownership checking:
- ``std::string``
- ``std::vector<T>`` (``T != bool``)
- ``std::list``
- ``std::unordered_map``
- ``std::unordered_multimap``
- ``std::unordered_set``
- ``std::unordered_multiset``
Randomizing unspecified behavior
--------------------------------
The library supports the randomization of unspecified behavior. For example, randomizing
the relative order of equal elements in ``std::sort`` or randomizing both parts of the
partition after calling ``std::nth_element``. This effort helps migrating to potential
future faster versions of these algorithms that might not have the exact same behavior.
In particular, it makes it easier to deflake tests that depend on unspecified behavior.
A seed can be used to make such failures reproducible: use ``_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed``.