mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-05-16 19:06:47 +00:00

This effort is dedicated to deflake the tests of the users which depend on the unspecified behavior of algorithms and containers. This also might help updating the sorting algorithm in libcxx which has the quadratic worst case in the future or at least create a new one under flag. For detailed design, please see the design doc I provide in the patch. Differential Revision: https://reviews.llvm.org/D96946
92 lines
3.5 KiB
ReStructuredText
92 lines
3.5 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 using the ``_LIBCPP_DEBUG`` macro.
|
|
|
|
Note that using the debug mode discussed in this document requires that the library
|
|
has been compiled with support for the debug mode (see ``LIBCXX_ENABLE_DEBUG_MODE_SUPPORT``).
|
|
|
|
Also note that while the debug mode has no effect on libc++'s ABI, it does have broad ODR
|
|
implications. Users should compile their whole program at the same debugging level.
|
|
|
|
The various levels of checking provided by the debug mode follow.
|
|
|
|
No debugging checks (``_LIBCPP_DEBUG`` not defined)
|
|
---------------------------------------------------
|
|
When ``_LIBCPP_DEBUG`` is not defined, there are no debugging checks performed by
|
|
the library. This is the default.
|
|
|
|
Basic checks (``_LIBCPP_DEBUG == 0``)
|
|
-------------------------------------
|
|
When ``_LIBCPP_DEBUG`` is defined to ``0`` (to be understood as level ``0``), some
|
|
debugging checks are enabled. The non-exhaustive list of things is:
|
|
|
|
- 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 ``_LIBCPP_DEBUG``, and
|
|
causes the library to violate some of the Standard's complexity clauses.
|
|
|
|
- FIXME: Update this list
|
|
|
|
Iterator debugging checks (``_LIBCPP_DEBUG == 1``)
|
|
--------------------------------------------------
|
|
Defining ``_LIBCPP_DEBUG`` to ``1`` enables "iterator debugging", which provides
|
|
additional assertions about the validity of iterators used by the program.
|
|
|
|
The following containers and classes support iterator debugging:
|
|
|
|
- ``std::string``
|
|
- ``std::vector<T>`` (``T != bool``)
|
|
- ``std::list``
|
|
- ``std::unordered_map``
|
|
- ``std::unordered_multimap``
|
|
- ``std::unordered_set``
|
|
- ``std::unordered_multiset``
|
|
|
|
The remaining containers do not currently support iterator debugging.
|
|
Patches welcome.
|
|
|
|
Randomizing Unspecified Behavior (``_LIBCPP_DEBUG == 1``)
|
|
---------------------------------------------------------
|
|
This also enables the randomization of unspecified behavior, for
|
|
example, for equal elements in ``std::sort`` or randomizing both parts of
|
|
the partition after ``std::nth_element`` call. This effort helps you to migrate
|
|
to potential future faster versions of these algorithms and deflake your tests
|
|
which depend on such behavior. To fix the seed, use
|
|
``_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY_SEED=seed`` definition.
|
|
|
|
Handling Assertion Failures
|
|
===========================
|
|
When a debug assertion fails the assertion handler is called via the
|
|
``std::__libcpp_debug_function`` function pointer. It is possible to override
|
|
this function pointer using a different handler function. Libc++ provides a
|
|
the default handler, ``std::__libcpp_abort_debug_handler``, which aborts the
|
|
program. The handler may not return. Libc++ can be changed to use a custom
|
|
assertion handler as follows.
|
|
|
|
.. code-block:: cpp
|
|
|
|
#define _LIBCPP_DEBUG 1
|
|
#include <string>
|
|
void my_handler(std::__libcpp_debug_info const&);
|
|
int main(int, char**) {
|
|
std::__libcpp_debug_function = &my_handler;
|
|
|
|
std::string::iterator bad_it;
|
|
std::string str("hello world");
|
|
str.insert(bad_it, '!'); // causes debug assertion
|
|
// control flow doesn't return
|
|
}
|