.. highlight:: none


.. index::
   pair: diagnostic feedback; design

.. _design-diag:


Diagnostic feedback
===================

.. mps:prefix:: design.mps.diag


Introduction
------------

:mps:tag:`intro` This document describes how to use the diagnostic feedback
mechanism in the Memory Pool System.

:mps:tag:`sources` Initially abased on [RHSK_2007-04-13]_ and [RHSK_2007-04-18]_.


Overview
--------

Diagnostic feedback is information created by the MPS diagnostic
system for the purpose of helping MPS programmers and client
programmers.

Such a piece of information is called "a diagnostic". (See also
:mps:ref:`.parts`.)

A diagnostic is not intended to be visible to end users, or readable
by them.

A diagnostic is not intended to be stable from one release to the
next: it may be modified or removed at any time.


Requirements
------------

MPS diagnostic feedback code must do these things:

- calculate, store, and propagate data;
- collate, synthesise, and format it into a human-useful diagnostic;
- control (for example, filter) output of diagnostics;
- use a channel to get the diagnostic out.


Usage
-----

To get diagnostic output from the MPS, you must use a variety with
diagnostics compiled-in. Currently, that means variety.cool. See
``config.h``.

There are two mechanism for getting diagnostic output:

#. Automatically via the telemetry system. See design.mps.telemetry_,
   and the "Telemetry" chapter in the manual.

   .. _design.mps.telemetry: telemetry.html

#. Manually via the debugger. In the debugger, set break points at the
   places where you want to inspect data structures (or wait for the
   debugger to be entered via an :c:func:`abort()` call or unhandled
   segmentation fault). Then at the debugger command prompt, run
   :c:func:`Describe()` commands of your choice. For example::

        (gdb) run
        Starting program: mv2test
        Reading symbols for shared libraries +............................. done
        cbs.c:94: MPS ASSERTION FAILED: !cbs->inCBS

        Program received signal SIGABRT, Aborted.
        0x00007fff83e42d46 in __kill ()
        (gdb) frame 12
        #12 0x000000010000b1fc in MVTFree (pool=0x103ffe160, base=0x101dfd000, size=5024) at poolmv2.c:711
        711         Res res = CBSInsert(MVTCBS(mvt), base, limit);
        (gdb) p MVTDescribe(mvt, mps_lib_get_stdout(), 0)
        MVT 0000000103FFE160 {
          minSize: 8
          meanSize: 42
          maxSize: 8192
          fragLimit: 30
          reuseSize: 16384
          fillSize: 8192
          availLimit: 90931
          abqOverflow: FALSE
          splinter: TRUE
          splinterBase: 0000000106192FF0
          splinterLimit: 0000000106193000
          size: 303104
          allocated: 262928
          available: 40176
          unavailable: 0
          # ... etc ...
        }


How to write a diagnostic
-------------------------

Compile away in non-diag varieties; no side effects
...................................................

Wrap code with the :c:macro:`STATISTIC` and :c:macro:`METER` macros, to make sure
that non-diagnostic varieties do not execute diagnostic-generating
code.

Diagnostic-generating code must have no side effects.


Writing good paragraph text
...........................

Make your diagnostics easy to understand! Other people will read your
diagnostics! Make them clear and helpful. Do not make them terse and
cryptic. If you use symbols, print a key in the diagnostic.


How the MPS diagnostic system works
-----------------------------------

Parts of the MPS diagnostic system
..................................

:mps:tag:`parts` The following facilities are considered part of the MPS
diagnostic system:

- the :c:func:`Describe()` methods.
- the :c:macro:`STATISTIC` macros (see ``mpm.h``);
- the :c:macro:`METER` macros and meter subsystem.


Statistics
..........

:mps:tag:`stat` The statistic system collects information about the
behaviour and performance of the MPS that may be useful for MPS
developers and customers, but which is not needed by the MPS itself
for internal decision-making.

:mps:tag:`stat.remove` The space needed for these statistics, and the code
for maintaining them, can therefore be removed (compiled out) in some
varieties.

:mps:tag:`stat.config` Statistics are compiled in if :c:macro:`CONFIG_STATS` is
defined (in the cool variety) and compiled out if
:c:macro:`CONFIG_STATS_NONE` is defined (in the hot and rash varieties).

.. c:macro:: STATISTIC_DECL(decl)

:mps:tag:`stat.decl` The :c:macro:`STATISTIC_DECL` macro is used to wrap the
declaration of storage for a statistic. Note that the expansion
supplies a terminating semi-colon and so it must not be followed by a
semi-colon in use. This is so that it can be used in structure
declarations.

.. c:macro:: STATISTIC(gather)

:mps:tag:`stat.gather` The :c:macro:`STATISTIC` macro is used to gather statistics.
The argument is a statement and the expansion followed by a semicolon
is syntactically a statement. The macro expends to :c:macro:`NOOP` in
non-statistical varieties. (Note that it can't use :c:macro:`DISCARD_STAT` to
check the syntax of the statement because it is expected to use fields
that have been compiled away by :c:macro:`STATISTIC_DECL`, and these will
cause compilation errors.)

:mps:tag:`stat.gather.effect` The argument to the :c:macro:`STATISTIC` macro is not
executed in non-statistical varieties and must have no side effects,
except for updates to fields that are declared in :c:macro:`STATISTIC_DECL`,
and telemetry output containing the values of such fields.

.. c:macro:: STATISTIC_WRITE(format, arg)

:mps:tag:`stat.write` The :c:macro:`STATISTIC_WRITE` macro is used in :c:func:`WriteF()`
argument lists to output the values of statistics.


Related systems
...............

The MPS diagnostic system is separate from the following other MPS
systems:

- The telemetry-log-events system. This emits much more data, in a
  less human-readable form, requires MPS-aware external tools, and is
  more stable from release to release). In non-diagnostic telemetry
  varieties, the telemetry-log-events system emits events that log all
  normal MPS actions. In diagnostic telemetry varieties, it may emit
  additional events containing diagnostic information. Additionally,
  the telemetry-log-events stream might in future be available as a
  channel for emitting human-readable text diagnostics. See also
  design.mps.telemetry_.

- The MPS message system. This is present in all varieties, and
  manages asynchronous communication from the MPS to the client
  program). However, the MPS message system might in future also be
  available as a channel for emitting diagnostics. See also
  design.mps.message_.

  .. _design.mps.message: message.html



References
----------

.. [RHSK_2007-04-13] Richard Kistruck. 2007-04-13. "`diagnostic feedback from the MPS <https://info.ravenbrook.com/mail/2007/04/13/13-07-45/0.txt>`_".

.. [RHSK_2007-04-18] Richard Kistruck. 2007-04-18. "`Diverse types of diagnostic feedback <https://info.ravenbrook.com/mail/2007/04/18/10-58-49/0.txt>`_".