1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-13 06:50:39 -08:00
emacs/mps/manual/html/design/object-debug.html
Gareth Rees c5f77afc19 Bring html up to date for the mps manual.
Copied from Perforce
 Change: 181433
 ServerID: perforce.ravenbrook.com
2013-04-24 12:21:37 +01:00

487 lines
No EOL
40 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>15. Debugging features for client objects &mdash; Memory Pool System 1.111.0 documentation</title>
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.111.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<link rel="copyright" title="Copyright" href="../copyright.html" />
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
<link rel="up" title="Design" href="index.html" />
<link rel="next" title="16. Protocol inheritance" href="protocol.html" />
<link rel="prev" title="14. The lock module" href="lock.html" />
</head>
<body>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="protocol.html" title="16. Protocol inheritance"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="lock.html" title="14. The lock module"
accesskey="P">previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" accesskey="U">Design</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body">
<div class="section" id="debugging-features-for-client-objects">
<span id="design.mps.object-debug"></span><h1>15. Debugging features for client objects<a class="headerlink" href="#debugging-features-for-client-objects" title="Permalink to this headline"></a></h1>
<div class="section" id="introduction">
<h2>15.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.intro"></span><a class="mpstag reference internal" href="#design.mps.object-debug.intro">.intro:</a> This is the design for all the various debugging
features that MPS clients (and sometimes MPS developers) can use to
discover what is happening to their objects and the memory space.</p>
<p><span class="target" id="design.mps.object-debug.readership"></span><a class="mpstag reference internal" href="#design.mps.object-debug.readership">.readership:</a> MPS developers.</p>
</div>
<div class="section" id="history">
<h2>15.2. History<a class="headerlink" href="#history" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.hist.0"></span><a class="mpstag reference internal" href="#design.mps.object-debug.hist.0">.hist.0:</a> The first draft merely records all the various ideas
about fenceposting that came up in discussions in June, July and
September 1998. This includes the format wrapping idea from
mail.ptw.1998-06-19.21-13(0). Pekka Pirinen, 1998-09-10.</p>
<p><span class="target" id="design.mps.object-debug.hist.1"></span><a class="mpstag reference internal" href="#design.mps.object-debug.hist.1">.hist.1:</a> Converted from MMInfo database design document.
Richard Brooksby, 2002-06-07.</p>
<p><span class="target" id="design.mps.object-debug.hist.2"></span><a class="mpstag reference internal" href="#design.mps.object-debug.hist.2">.hist.2:</a> Converted to reStructuredText. Gareth Rees,
2013-04-14.</p>
</div>
<div class="section" id="overview">
<h2>15.3. Overview<a class="headerlink" href="#overview" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.over.fenceposts"></span><a class="mpstag reference internal" href="#design.mps.object-debug.over.fenceposts">.over.fenceposts:</a> In its current state, this document mostly
talks about fenceposts, straying a little into tagging where theses
features have an effect on each other. [There exist other documents
that list other required features, and propose interfaces and
implementations. These will eventually be folded into this one. pekka
1998-09-10]</p>
</div>
<div class="section" id="requirements">
<h2>15.4. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.req.fencepost"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.fencepost">.req.fencepost:</a> Try to detect overwrites and underwrites of
allocated blocks by adding fenceposts (source req.product.??? VC++,
req.epcore.fun.debug.support).</p>
<p><span class="target" id="design.mps.object-debug.req.fencepost.size"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.fencepost.size">.req.fencepost.size:</a> The fenceposts should be at least 4
bytes on either side or 8 bytes if on one side only, with an
adjustable content (although VC++ only has 4 bytes with pattern
0xFDFDFDFD, having unwisely combined the implementation with other
debug features).</p>
<p><span class="target" id="design.mps.object-debug.req.fencepost.check"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.fencepost.check">.req.fencepost.check:</a> There should be a function to check all
the fenceposts (source req.epcore.fun.debug.support).</p>
<p><span class="target" id="design.mps.object-debug.req.free-block"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.free-block">.req.free-block:</a> Try to detect attempts to write and read
free blocks.</p>
<p><span class="target" id="design.mps.object-debug.req.walk"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.walk">.req.walk:</a> There should be a way to map (&#8220;walk&#8221;) a user
function over all allocated objects (except PS VM objects), possibly
only in a separate debugging variety/mode (source
req.epcore.fun.debug.support).</p>
<p><span class="target" id="design.mps.object-debug.req.tag"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.tag">.req.tag:</a> There should be a way to store at least a word of
user data (a &#8220;tag&#8221;, borrowing the SW term) with every object in
debugging mode, to be used in memory dumps (source req.product.???
VC++).</p>
<p><span class="target" id="design.mps.object-debug.req.tag.walk"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.tag.walk">.req.tag.walk:</a> The walking function (as required by
<a class="reference internal" href="#design.mps.object-debug.req.walk">.req.walk</a>) should have access to this data (source
req.epcore.fun.debug.support).</p>
<p><span class="target" id="design.mps.object-debug.req.dump.aver"></span><a class="mpstag reference internal" href="#design.mps.object-debug.req.dump.aver">.req.dump.aver:</a> It must be possible to perform a memory dump
after an <tt class="xref c c-func docutils literal"><span class="pre">AVER()</span></tt> has fired (naturally, if the information
required for the dump has been corrupted, it will fail, as softly as
possible). (source &#64;&#64;&#64;&#64;)</p>
<p>[There are more, especially about memory dumps and allocation
locations. pekka 1998-09-10]</p>
</div>
<div class="section" id="solution-ideas">
<h2>15.5. Solution ideas<a class="headerlink" href="#solution-ideas" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.note.assumptions"></span><a class="mpstag reference internal" href="#design.mps.object-debug.note.assumptions">.note.assumptions:</a> I&#8217;ve tried not to assume anything about
the coincidence of manual/automatic, formatted/unformatted, and
ap/mps_alloc. I think those questions deserve to be decided on their
own merits. instead of being constrained by a debug feature.</p>
<p><span class="target" id="design.mps.object-debug.fence.content.repeat"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.content.repeat">.fence.content.repeat:</a> The content of a fencepost could be
specified as a byte/word which used repeatedly to fill the fencepost.</p>
<p><span class="target" id="design.mps.object-debug.fence.content.template"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.content.template">.fence.content.template:</a> The content could be given as a
template which is of the right size and is simply copied onto the
fencepost.</p>
<p><span class="target" id="design.mps.object-debug.fence.walk"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.walk">.fence.walk:</a> <a class="reference internal" href="#design.mps.object-debug.req.fencepost.check">.req.fencepost.check</a> requires the
ability to find all the allocated objects. In formatted pools, this is
not a problem. In unformatted pools, we could use the walker. It&#8217;s a
feasible strategy to bet that any pool that might have to support
fenceposting will also have a walking requirement.</p>
<p><span class="target" id="design.mps.object-debug.fence.tag"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.tag">.fence.tag:</a> Fenceposting also needs to keep track which
objects have fenceposts. unless we manage to do them all. It would be
easiest to put this in the tags.</p>
<p><span class="target" id="design.mps.object-debug.fence.check.object"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.check.object">.fence.check.object:</a> A function to check the fenceposts on a
given object would be nice.</p>
<p><span class="target" id="design.mps.object-debug.fence.ap"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.ap">.fence.ap:</a> AP&#8217;s could support fenceposting transparently by
having a mode where <a class="reference internal" href="../topic/allocation.html#mps_reserve" title="mps_reserve"><tt class="xref c c-func docutils literal"><span class="pre">mps_reserve()</span></tt></a> always goes out-of-line and
fills in the fenceposts (the pool&#8217;s <tt class="xref c c-func docutils literal"><span class="pre">BufferFill()</span></tt> method isn&#8217;t
involved). This would leave the MPS with more freedom of
implementation, especially when combined with some of the other ideas.
We think doing a function call for every allocation is not too bad for
debugging.</p>
<p><span class="target" id="design.mps.object-debug.fence.outside-ap"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.outside-ap">.fence.outside-ap:</a> We could also let the client insert their
own fenceposts outside the MPS allocation mechanism. Even if
fenceposting were done like this, we&#8217;d still want it to be an MPS
feature, so we&#8217;d offer sample C macros for adding the size of the
fencepost and filling in the fencepost pattern. Possibly something
like this (while we could still store the parameters in the pool or
allocation point, there seems little point in doing so in this case,
and having them as explicit parameters to the macros allows the client
to specify constants to gain effiency):</p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#define mps_add_fencepost(size, fp_size)</span>
<span class="cp">#define mps_fill_fenceposts(obj, size, fp_size, fp_pattern)</span>
</pre></div>
</div>
<p>The client would need to supply their own fencepost checking function,
obviously, but again we could offer one that matches the sample
macros.</p>
<p><span class="target" id="design.mps.object-debug.fence.tail-only"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.tail-only">.fence.tail-only:</a> In automatic pools, the presence of a
fencepost at the head of the allocated block results in the object
reference being an internal pointer. This means that the format or the
pool would need to know about fenceposting and convert between
references and pointers. This would slow down the critical path when
fenceposting is used. This can be ameliorated by putting a fencepost
at the tail of the block only: this obviates the internal pointer
problem and could provide almost the same degree of checking (provided
the size was twice as large), especially in copying pools, where there
are normally no gaps between allocated blocks. In addition to the
inescapable effects on allocation and freeing (including copying and
reclaim thereunder), only scanning would have to know about
fenceposts.</p>
<p><span class="target" id="design.mps.object-debug.fence.tail-only.under"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.tail-only.under">.fence.tail-only.under:</a> Walking over all the objects in the
pool would be necessary to detect underwrites, as one couldn&#8217;t be sure
that there is a fencepost before any given object (or where it&#8217;s
located exactly). If the pool were doing the checking, it could be
sure: it would know about alignments and it could put fenceposts in
padding objects (free blocks will have them because they were once
allocated) so there&#8217;d be one on either side of any object (except at
the head of a segment, which is not a major problem, and could be
fixed by adding a padding object at the beginning of every segment).
This requires some cleverness to avoid splinters smaller than the
fencepost size, but it can be done.</p>
<p><span class="target" id="design.mps.object-debug.fence.wrapper"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.wrapper">.fence.wrapper:</a> On formatted pools, fenceposting could be
implemented by &#8220;wrapping&#8221; the client-supplied format at creation time.
The wrapper can handle the conversion from the fenceposted object and
back. This will be invisible to the client and gives the added benefit
that the wrapper can validate fenceposts on every format operation,
should it desire. That is, the pool would see the fenceposts as part
of the client object, but the client would only see its object; the
format wrapper would translate between the two. Note that hiding the
fenceposts from scan methods, which are required to take a contiguous
range of objects, is a bit complicated.</p>
<p><span class="target" id="design.mps.object-debug.fence.client-format"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.client-format">.fence.client-format:</a> The MPS would supply such a wrapper,
but clients could also be allowed to write their own fenceposted
formats (provided they coordinate with allocation, see below). This
would make scanning fenceposted segments more efficient.</p>
<p><span class="target" id="design.mps.object-debug.fence.wrapper.variable"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.wrapper.variable">.fence.wrapper.variable:</a> Furthermore, you could create
different classes of fencepost within a pool, because the fencepost
itself could have a variable format. For instance, you might choose to
have the fencepost be minimal (one to two words) for small objects,
and more detailed/complex for large objects (imagining that large
objects are likely vector-ish and subject to overruns). You could get
really fancy and have the fencepost class keyed to the object class
(for example, different allocation points create different classes of
fenceposting).</p>
<p><span class="target" id="design.mps.object-debug.fence.wrapper.alloc"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.wrapper.alloc">.fence.wrapper.alloc:</a> Even with a wrapped format, allocation
and freeing would still have know about the fenceposts. If allocation
points are used, either MPS-side (<a class="reference internal" href="#design.mps.object-debug.fence.ap">.fence.ap</a>) or client-side
(<a class="reference internal" href="#design.mps.object-debug.fence.outside-ap">.fence.outside-ap</a>) fenceposting could be used, with the obvious
modifications.</p>
<p><span class="target" id="design.mps.object-debug.fence.wrapper.alloc.format"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.wrapper.alloc.format">.fence.wrapper.alloc.format:</a> We could add three format
methods, to adjust the pointer and the size for alloc and free, to put
down the fenceposts during alloc, and to check them; to avoid slowing
down all allocation, this would require some MOPping to make the
format class affect the choice of the alloc and free methods (see
mail.pekka.1998-06-11.18-18).</p>
<p><span class="target" id="design.mps.object-debug.fence.wrapper.alloc.size"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.wrapper.alloc.size">.fence.wrapper.alloc.size:</a> We could just communicate the size
of the fenceposts between the format and the allocation routines, but
then you couldn&#8217;t use variable fenceposts (.fence.wrapper.variable).
[All this applies to copying and reclaim in a straight-forward manner,
I think.]</p>
<p><span class="target" id="design.mps.object-debug.fence.pool.wrapper"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.pool.wrapper">.fence.pool.wrapper:</a> Pools can be wrapped as well. This could
be a natural way to represent/implement the fenceposting changes to
the Alloc and Free methods. [&#64;&#64;&#64;&#64;alignment]</p>
<p><span class="target" id="design.mps.object-debug.fence.pool.new-class"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.pool.new-class">.fence.pool.new-class:</a> We could simply offer a debugging
version of each pool class (e.g., <tt class="xref c c-func docutils literal"><span class="pre">mps_pool_class_mv_debug()</span></tt>).
As we have seen, debugging features have synergies which make it
advantageous to have a coordinated implementation, so splitting them
up would not just complicate the client interface, it would also be an
implementation problem; we can turn features on or off with pool init
parameters.</p>
<p><span class="target" id="design.mps.object-debug.fence.pool.abstract"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.pool.abstract">.fence.pool.abstract:</a> We could simply use pool init
parameters only to control all debugging features (optargs would be
useful here). While there migh be subclasses and wrappers internally,
the client would only see a single pool class; in the internal view,
this would be an abstract class, and the parameters would determine
which concrete class actually gets instantiated.</p>
<p><span class="target" id="design.mps.object-debug.tag.out-of-line"></span><a class="mpstag reference internal" href="#design.mps.object-debug.tag.out-of-line">.tag.out-of-line:</a> It would be nice if tags were stored
out-of-line, so they can be used to study allocation patterns and
fragmentation behaviours. Such an implementation of tagging could also
easily be shared among several pools.</p>
</div>
<div class="section" id="architecture">
<h2>15.6. Architecture<a class="headerlink" href="#architecture" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.pool"></span><a class="mpstag reference internal" href="#design.mps.object-debug.pool">.pool:</a> The implementation is at the pool level, because pools
manage allocated objects. A lot of the code will be generic,
naturally, but the data structures and the control interfaces attach
to pools. In particular, clients will be able to use tagging and
fenceposting separately on each pool.</p>
<p><span class="target" id="design.mps.object-debug.fence.size"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.size">.fence.size:</a> Having fenceposts of adjustable size and pattern
is quite useful. We feel that restricting the size to an integral
multiple of the [pool or format?] alignment is harmless and simplifies
the implementation enormously.</p>
<p><span class="target" id="design.mps.object-debug.fence.template"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.template">.fence.template:</a> We use templates
(<a class="reference internal" href="#design.mps.object-debug.fence.content.template">.fence.content.template</a>) to fill in the fenceposts, but we
do not give any guarantees about the location of the fenceposts, only
that they&#8217;re properly aligned. This leaves us the opportunity to do
tail-only fenceposting, if we choose.</p>
<p><span class="target" id="design.mps.object-debug.fence.slop"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.slop">.fence.slop:</a> [see impl.c.dbgpool.FenceAlloc &#64;&#64;&#64;&#64;]</p>
<p><span class="target" id="design.mps.object-debug.fence.check.free"></span><a class="mpstag reference internal" href="#design.mps.object-debug.fence.check.free">.fence.check.free:</a> We check the fenceposts when freeing an
object.</p>
<p><span class="target" id="design.mps.object-debug.unified-walk"></span><a class="mpstag reference internal" href="#design.mps.object-debug.unified-walk">.unified-walk:</a> Combine the walking and tagging requirements
(<a class="reference internal" href="#design.mps.object-debug.req.tag.walk">.req.tag.walk</a> and &#64;&#64;&#64;&#64;) into a generic facility for
walking and tagging objects with just one interface and one name:
tagging. Also combine the existing formatted object walker into this
metaphor, but allowing the format and tag parameters of the step
function be optional [this part has not been implemented yet pekka
1998-09-10].</p>
<p><span class="target" id="design.mps.object-debug.init"></span><a class="mpstag reference internal" href="#design.mps.object-debug.init">.init:</a> It simplifies the implementation of both tagging and
fenceposting if they are always on, so that we don&#8217;t have to keep
track of which objects have been fenceposted and which have not, and
don&#8217;t have to have three kinds of tags: for user data, for
fenceposting, and for both. So we determine this at pool init time
(and let fenceposting turn on tagging, if necessary).</p>
<p><span class="target" id="design.mps.object-debug.pool-parameters"></span><a class="mpstag reference internal" href="#design.mps.object-debug.pool-parameters">.pool-parameters:</a> Fencepost templates and tag formats are
passed in as pool parameters.</p>
<p><span class="target" id="design.mps.object-debug.modularity"></span><a class="mpstag reference internal" href="#design.mps.object-debug.modularity">.modularity:</a> While a combined generic implementation of tags
and fenceposts is provided, it is structured so that each part of it
could be implemented by a pool-specific mechanism with a minimum of
new protocol. [This will be improved, when we figure out formatted
pools &#8211; they don&#8217;t need tags for fenceposting.]</p>
<p><span class="target" id="design.mps.object-debug.out-of-space"></span><a class="mpstag reference internal" href="#design.mps.object-debug.out-of-space">.out-of-space:</a> If there&#8217;s no room for tags, we will not dip
into the reservoir, just fail to allocate the tag. If the alloc call
had a reservoir permit, we let it succeed even without a tag, and just
make sure the free method will not complain if it can&#8217;t find a tag. If
the call didn&#8217;t have a reservoir permit, we free the block allocated
for the object and fail the allocation, so that the client gets a
chance to do whatever low-memory actions they might want to do.
[Should this depend on whether there is anything in the reservoir?]
This breaks the one-to-one relationship between tags and objects, so
some checks cannot be made, but we do count the &#8220;lost&#8221; tags.</p>
<p>[need to hash out how to do fenceposting in formatted pools]</p>
</div>
<div class="section" id="client-interface">
<h2>15.7. Client interface<a class="headerlink" href="#client-interface" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.interface.fenceposting.check"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.fenceposting.check">.interface.fenceposting.check:</a>
<a class="reference internal" href="../topic/debugging.html#mps_pool_check_fenceposts" title="mps_pool_check_fenceposts"><tt class="xref c c-func docutils literal"><span class="pre">mps_pool_check_fenceposts()</span></tt></a> is a function to check all
fenceposts in a pool (<tt class="xref c c-func docutils literal"><span class="pre">AVER()</span></tt> if a problem is found)</p>
<p>[from here on, these are tentative and incomplete]</p>
<dl class="function">
<dt id="mps_fmt_fencepost_wrap">
<a class="reference internal" href="../topic/error.html#mps_res_t" title="mps_res_t">mps_res_t</a> <tt class="descname">mps_fmt_fencepost_wrap</tt><big>(</big><a class="reference internal" href="../topic/format.html#mps_fmt_t" title="mps_fmt_t">mps_fmt_t</a><em>&nbsp;*format_return</em>, <a class="reference internal" href="../topic/arena.html#mps_arena_t" title="mps_arena_t">mps_arena_t</a><em>&nbsp;arena</em>, <a class="reference internal" href="../topic/format.html#mps_fmt_t" title="mps_fmt_t">mps_fmt_t</a><em>&nbsp;format</em>, [fp<em>&nbsp;parameters]</em><big>)</big><a class="headerlink" href="#mps_fmt_fencepost_wrap" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.object-debug.interface.fenceposting.format"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.fenceposting.format">.interface.fenceposting.format:</a> A function to wrap a format
(class) to provide fenceposting.</p>
<dl class="function">
<dt id="mps_fmt_adjust_fencepost_t">
void <tt class="descname">(*mps_fmt_adjust_fencepost_t)</tt><big>(</big>size_t<em>&nbsp;*size_io</em><big>)</big><a class="headerlink" href="#mps_fmt_adjust_fencepost_t" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.object-debug.interface.fenceposting.add"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.fenceposting.add">.interface.fenceposting.add:</a> A format method to adjust size
of a block about to be allocted to allow for fenceposts.</p>
<dl class="function">
<dt id="mps_fmt_put_fencepost_t">
void <tt class="descname">(*mps_fmt_put_fencepost_t)</tt><big>(</big><a class="reference internal" href="../topic/interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a> *<em>&nbsp;addr_io</em>, size_t<em>&nbsp;size</em><big>)</big><a class="headerlink" href="#mps_fmt_put_fencepost_t" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.object-debug.interface.fenceposting.add"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.fenceposting.add">.interface.fenceposting.add:</a> A format method to add a fencepost around a block
about to be allocated [the NULL method adds a tail fencepost]</p>
<dl class="function">
<dt id="mps_fmt_check_fenceposts_t">
<a class="reference internal" href="../topic/interface.html#mps_bool_t" title="mps_bool_t">mps_bool_t</a> <tt class="descname">(*mps_fmt_check_fenceposts_t)</tt><big>(</big><a class="reference internal" href="../topic/interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><big>)</big><a class="headerlink" href="#mps_fmt_check_fenceposts_t" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.object-debug.interface.fenceposting.add"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.fenceposting.add">.interface.fenceposting.add:</a> A format method to check the
fenceposts around an object [the <tt class="docutils literal"><span class="pre">NULL</span></tt> method checks tails].</p>
<dl class="function">
<dt id="mps_debug_class">
<a class="reference internal" href="../topic/pool.html#mps_class_t" title="mps_class_t">mps_class_t</a> <tt class="descname">mps_debug_class</tt><big>(</big><a class="reference internal" href="../topic/pool.html#mps_class_t" title="mps_class_t">mps_class_t</a><em>&nbsp;class</em><big>)</big><a class="headerlink" href="#mps_debug_class" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.object-debug.interface.fenceposting.pool"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.fenceposting.pool">.interface.fenceposting.pool:</a> A function to wrap a pool class
to provide fenceposting (note absence of arena parameter).</p>
<dl class="function">
<dt>
<tt class="descname">mps_res_t mps_alloc(mps_addr_t *, mps_pool_t, size_t);</tt></dt>
<dd></dd></dl>
<dl class="function">
<dt>
<tt class="descname">mps_res_t mps_alloc_dbg(mps_addr_t *, mps_pool_t, size_t, ...);</tt></dt>
<dd></dd></dl>
<dl class="function">
<dt>
<tt class="descname">mps_res_t mps_alloc_dbg_v(mps_addr_t *, mps_pool_t, size_t, va_list);</tt></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.object-debug.interface.tags.alloc"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.tags.alloc">.interface.tags.alloc:</a> Three functions to replace existing
<a class="reference internal" href="../topic/allocation.html#mps_alloc" title="mps_alloc"><tt class="xref c c-func docutils literal"><span class="pre">mps_alloc()</span></tt></a> (request.???.??? proposes to remove the varargs)</p>
<dl class="function">
<dt id="mps_objects_step_t">
void <tt class="descname">(*mps_objects_step_t)</tt><big>(</big><a class="reference internal" href="../topic/interface.html#mps_addr_t" title="mps_addr_t">mps_addr_t</a><em>&nbsp;addr</em>, size_t<em>&nbsp;size</em>, <a class="reference internal" href="../topic/format.html#mps_fmt_t" title="mps_fmt_t">mps_fmt_t</a><em>&nbsp;format</em>, <a class="reference internal" href="../topic/pool.html#mps_pool_t" title="mps_pool_t">mps_pool_t</a><em>&nbsp;pool</em>, void<em>&nbsp;*tag_data</em>, void<em>&nbsp;*p</em><big>)</big><a class="headerlink" href="#mps_objects_step_t" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="mps_pool_walk">
void <tt class="descname">mps_pool_walk</tt><big>(</big><a class="reference internal" href="../topic/arena.html#mps_arena_t" title="mps_arena_t">mps_arena_t</a><em>&nbsp;arena</em>, <a class="reference internal" href="../topic/pool.html#mps_pool_t" title="mps_pool_t">mps_pool_t</a><em>&nbsp;pool</em>, <a class="reference internal" href="#mps_objects_step_t" title="mps_objects_step_t">mps_objects_step_t</a><em>&nbsp;step</em>, void<em>&nbsp;*p</em><big>)</big><a class="headerlink" href="#mps_pool_walk" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="function">
<dt id="mps_arena_walk">
void <tt class="descname">mps_arena_walk</tt><big>(</big><a class="reference internal" href="../topic/arena.html#mps_arena_t" title="mps_arena_t">mps_arena_t</a><em>&nbsp;arena</em>, <a class="reference internal" href="#mps_objects_step_t" title="mps_objects_step_t">mps_objects_step_t</a><em>&nbsp;step</em>, void<em>&nbsp;*p</em><big>)</big><a class="headerlink" href="#mps_arena_walk" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<p><span class="target" id="design.mps.object-debug.interface.tags.walker"></span><a class="mpstag reference internal" href="#design.mps.object-debug.interface.tags.walker">.interface.tags.walker:</a> Functions to walk all the allocated
objects in a pool or an arena (only client pools in this case),
<tt class="docutils literal"><span class="pre">format</span></tt> and <tt class="docutils literal"><span class="pre">tag_data</span></tt> can be <tt class="docutils literal"><span class="pre">NULL</span></tt> (<tt class="docutils literal"><span class="pre">tag_data</span></tt> really wants
to be <tt class="docutils literal"><span class="pre">void</span> <span class="pre">*</span></tt>, not <a class="reference internal" href="../topic/interface.html#mps_addr_t" title="mps_addr_t"><tt class="xref c c-type docutils literal"><span class="pre">mps_addr_t</span></tt></a>, because it&#8217;s stored
together with the internal tag data in an MPS internal pool)</p>
</div>
<div class="section" id="examples">
<h2>15.8. Examples<a class="headerlink" href="#examples" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.example.debug-alloc"></span><a class="mpstag reference internal" href="#design.mps.object-debug.example.debug-alloc">.example.debug-alloc:</a></p>
<div class="highlight-c"><div class="highlight"><pre><span class="cp">#define MPS_ALLOC_DBG(res_io, addr_io, pool, size)</span>
<span class="n">MPS_BEGIN</span>
<span class="k">static</span> <span class="n">mps_tag_A_s</span> <span class="n">_ts</span> <span class="o">=</span> <span class="p">{</span> <span class="n">__FILE__</span><span class="p">,</span> <span class="n">__LINE__</span> <span class="p">};</span>
<span class="o">*</span><span class="n">res_io</span> <span class="o">=</span> <span class="n">mps_alloc</span><span class="p">(</span><span class="n">addr_io</span><span class="p">,</span> <span class="n">pool</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">_ts_</span><span class="p">)</span>
<span class="n">MPS_END</span>
</pre></div>
</div>
</div>
<div class="section" id="implementation">
<h2>15.9. Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline"></a></h2>
<p><span class="target" id="design.mps.object-debug.new-pool"></span><a class="mpstag reference internal" href="#design.mps.object-debug.new-pool">.new-pool:</a> The client interface to control fenceposting
consists of the new classes <tt class="xref c c-func docutils literal"><span class="pre">mps_pool_class_mv_debug()</span></tt>,
<tt class="xref c c-func docutils literal"><span class="pre">mps_pool_class_epdl_debug()</span></tt>, and
<tt class="xref c c-func docutils literal"><span class="pre">mps_pool_class_epdr_debug()</span></tt>, and their new init parameter of
type <a class="reference internal" href="../topic/debugging.html#mps_pool_debug_option_s" title="mps_pool_debug_option_s"><tt class="xref c c-type docutils literal"><span class="pre">mps_pool_debug_option_s</span></tt></a>. [This is a temporary solution,
to get it out without writing lots of new interface. pekka 1998-09-10]</p>
<p><span class="target" id="design.mps.object-debug.new-pool.impl"></span><a class="mpstag reference internal" href="#design.mps.object-debug.new-pool.impl">.new-pool.impl:</a> The debug pools are implemented using the
&#8220;class wrapper&#8221; <tt class="xref c c-func docutils literal"><span class="pre">EnsureDebugClass()</span></tt>, which produces a subclass
with modified <tt class="docutils literal"><span class="pre">init</span></tt>, <tt class="docutils literal"><span class="pre">finish</span></tt>, <tt class="docutils literal"><span class="pre">alloc</span></tt>, and <tt class="docutils literal"><span class="pre">free</span></tt> methods.
These methods are implemented in the generic debug class code
(<tt class="xref c c-func docutils literal"><span class="pre">impl.c.dbgpool()</span></tt>), and are basically wrappers around the
superclass methods (invoked through the <tt class="docutils literal"><span class="pre">pool-&gt;class-&gt;super</span></tt> field).
To find the data stored in the class for the debugging features, they
use the <tt class="docutils literal"><span class="pre">debugMixin</span></tt> method provided by the subclass. So to make a
debug subclass, three things should be provided: a structure
definition of the instance containing a
<tt class="xref c c-type docutils literal"><span class="pre">PoolDebugMixinStruct</span></tt>, a pool class function that uses
<tt class="xref c c-func docutils literal"><span class="pre">EnsureDebugClass()</span></tt>, and a <tt class="docutils literal"><span class="pre">debugMixin</span></tt> method that locates
the <tt class="xref c c-type docutils literal"><span class="pre">PoolDebugMixinStruct</span></tt> within an instance.</p>
<p><span class="target" id="design.mps.object-debug.tags.splay"></span><a class="mpstag reference internal" href="#design.mps.object-debug.tags.splay">.tags.splay:</a> The tags are stored in a splay tree of tags
allocated from a subsidiary MFS pool. The client needs to specify the
(maximum) size of the client data in a tag, so that the pool can be
created.</p>
<p>[Lots more should be said, eventually. pekka 1998-09-10]</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../index.html">
<img class="logo" src="../_static/logo.png" alt="Logo"/>
</a></p>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">15. Debugging features for client objects</a><ul>
<li><a class="reference internal" href="#introduction">15.1. Introduction</a></li>
<li><a class="reference internal" href="#history">15.2. History</a></li>
<li><a class="reference internal" href="#overview">15.3. Overview</a></li>
<li><a class="reference internal" href="#requirements">15.4. Requirements</a></li>
<li><a class="reference internal" href="#solution-ideas">15.5. Solution ideas</a></li>
<li><a class="reference internal" href="#architecture">15.6. Architecture</a></li>
<li><a class="reference internal" href="#client-interface">15.7. Client interface</a></li>
<li><a class="reference internal" href="#examples">15.8. Examples</a></li>
<li><a class="reference internal" href="#implementation">15.9. Implementation</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="lock.html"
title="previous chapter">14. The lock module</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="protocol.html"
title="next chapter">16. Protocol inheritance</a></p><h4>Downloads</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
</p>
<h4>Issues</h4>
<p class="topless">
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&amp;view=status%3dopen&amp;display=Job:Priority:Title&amp;sort=Priority">Known issues</a><br>
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
</p><h4>Contact us</h4>
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="protocol.html" title="16. Protocol inheritance"
>next</a> |</li>
<li class="right" >
<a href="lock.html" title="14. The lock module"
>previous</a> |</li>
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> &raquo;</li>
<li><a href="index.html" >Design</a> &raquo;</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
</div>
</body>
</html>