mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-25 23:10:47 -08:00
Use MPS_ARGS_BEGIN etc in the Scheme example and in the manual. Use MPS_BEGIN and MPS_END instead of BEGIN and END. The _FIELD macros don't need to be function-like macros. Restore TODO comments in mps.h. Scheme example compiles with -std=c89. Copied from Perforce Change: 181749 ServerID: perforce.ravenbrook.com
146 lines
5.2 KiB
ReStructuredText
146 lines
5.2 KiB
ReStructuredText
.. Sources:
|
|
|
|
`<https://info.ravenbrook.com/project/mps/master/design/object-debug/>`_
|
|
|
|
.. index::
|
|
single: debugging; pool
|
|
single: pool; debugging
|
|
|
|
.. _topic-debugging:
|
|
|
|
Debugging pools
|
|
===============
|
|
|
|
Several :term:`pool classes` have debugging counterparts:
|
|
|
|
================= ==============================
|
|
Pool class Debugging counterpart
|
|
================= ==============================
|
|
:ref:`pool-ams` :c:func:`mps_class_ams_debug`
|
|
:ref:`pool-mv` :c:func:`mps_class_mv_debug`
|
|
:ref:`pool-mvff` :c:func:`mps_class_mvff_debug`
|
|
================= ==============================
|
|
|
|
These debugging pool classes provide two features that are useful for
|
|
debugging:
|
|
|
|
* .. index::
|
|
single: debugging; fencepost
|
|
single: fencepost
|
|
|
|
:dfn:`fenceposts` are patterns of data that are written before and
|
|
after each allocated block. In :term:`manually managed <manual
|
|
memory management>` pools, fenceposts are checked when the block is
|
|
deallocated, to see that they are unchanged. This helps detect
|
|
underwriting and :term:`overwriting errors`. Fenceposts for all
|
|
objects in a pool are checked when the pool is destroyed, and can be
|
|
checked at any time by calling :c:func:`mps_pool_check_fenceposts`.
|
|
|
|
* .. index::
|
|
single: debugging; free space splatting
|
|
single: free space splatting
|
|
|
|
:dfn:`free space splatting` overwrites recycled space with a pattern
|
|
of data. If the pattern is designed so that it does not resemble a
|
|
live object (and if code checks the consistency of its data
|
|
structues), then this helps to detect :term:`dangling pointer`
|
|
dereferences. The pattern is checked just before allocation, and
|
|
when a block of memory is released from the pool to the arena, to
|
|
see that it is unchanged. All free space in a pool can be checked
|
|
for the pattern at any time by calling
|
|
:c:func:`mps_pool_check_free_space`.
|
|
|
|
The :term:`client program` specifies templates for both of these
|
|
features via the :c:type:`mps_pool_debug_option_s` structure. This
|
|
allows it to specify patterns:
|
|
|
|
* that mimic illegal data values;
|
|
|
|
* that cause bus errors if wrongly interpreted as pointers;
|
|
|
|
* that cause assertions to fire if wrongly interpreted as data values;
|
|
|
|
* that contain an instruction sequence that wold cause the program to
|
|
signal an error or stop if wrongly interpreted as executable code.
|
|
|
|
For example::
|
|
|
|
mps_pool_debug_option_s debug_options = {
|
|
(void *)"postpost", 8,
|
|
(void *)"freefree", 8,
|
|
};
|
|
mps_pool_t pool;
|
|
mps_res_t res;
|
|
MPS_ARGS_BEGIN(args) {
|
|
MPS_ARGS_ADD(args, MPS_KEY_POOL_DEBUG_OPTIONS, &debug_options);
|
|
MPS_ARGS_ADD(args, MPS_KEY_FORMAT, &fmt);
|
|
MPS_ARGS_ADD(args, MPS_KEY_CHAIN, &chain);
|
|
MPS_ARGS_DONE(args);
|
|
res = mps_pool_create_k(&pool, arena, mps_class_ams_debug(), args);
|
|
} MPS_ARGS_END(args);
|
|
if (res != MPS_RES_OK) error("can't create debug pool");
|
|
|
|
|
|
.. c:type:: mps_pool_debug_option_s
|
|
|
|
The type of the structure passed as the
|
|
:c:macro:`MPS_KEY_POOL_DEBUG_OPTIONS` keyword argument to
|
|
:c:func:`mps_pool_create_k` when creating a debugging :term:`pool
|
|
class`. ::
|
|
|
|
typedef struct mps_pool_debug_option_s {
|
|
void *fence_template;
|
|
size_t fence_size;
|
|
void *free_template;
|
|
size_t free_size;
|
|
} mps_pool_debug_option_s;
|
|
|
|
``fence_template`` points to a template for :term:`fenceposts`.
|
|
|
|
``fence_size`` is the :term:`size` of ``fence_template`` in
|
|
:term:`bytes (1)`, or zero if the debugging pool should not use
|
|
fenceposts.
|
|
|
|
``free_template`` points to a template for splatting free space.
|
|
|
|
``free_size`` is the :term:`size` of ``free_template`` in bytes, or
|
|
zero if the debugging pool should not splat free space.
|
|
|
|
Both ``fence_size`` and ``free_size`` must be a multiple of the
|
|
:term:`alignment` of the :term:`pool`, and also a multiple of the
|
|
alignment of the pool's :term:`object format` if it has one.
|
|
|
|
The debugging pool will copy the ``fence_size`` bytes pointed to by
|
|
``fence_template`` in a repeating pattern onto each fencepost during
|
|
allocation, and it will copy the bytes pointed to by
|
|
``free_template`` in a repeating pattern over free space after the
|
|
space is reclaimed.
|
|
|
|
The MPS may not always use the whole of a template: it may use
|
|
pieces smaller than the given size, for example to pad out part of
|
|
a block that was left unused because of alignment requirements.
|
|
|
|
|
|
.. c:function:: void mps_pool_check_fenceposts(mps_pool_t pool)
|
|
|
|
Check all the :term:`fenceposts` in a :term:`pool`.
|
|
|
|
``pool`` is the pool whose fenceposts are to be checked.
|
|
|
|
If a corrupted fencepost is found, the MPS will :term:`assert
|
|
<assertion>`. It is only useful to call this on a :term:`debugging
|
|
pool` that has fenceposts turned on. It does nothing on
|
|
non-debugging pools.
|
|
|
|
|
|
.. c:function:: void mps_pool_check_free_space(mps_pool_t pool)
|
|
|
|
Check all the free space in a :term:`pool` for :term:`overwriting
|
|
errors`.
|
|
|
|
``pool`` is the pool whose free space is to be checked.
|
|
|
|
If corrupted free space is found, the MPS will :term:`assert
|
|
<assertion>`. It is only useful to call this on a :term:`debugging
|
|
pool` that has free space splatting turned on. It does nothing on
|
|
non-debugging pools.
|