.. Sources: ``_ .. 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 ` 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 `. 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 `. 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.