mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-13 06:50:39 -08:00
487 lines
No EOL
40 KiB
HTML
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 — 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> »</li>
|
|
<li><a href="index.html" accesskey="U">Design</a> »</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 (“walk”) 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 “tag”, 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 @@@@)</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’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’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’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’s <tt class="xref c c-func docutils literal"><span class="pre">BufferFill()</span></tt> method isn’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’d still want it to be an MPS
|
|
feature, so we’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’t be sure
|
|
that there is a fencepost before any given object (or where it’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’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 “wrapping” 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’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. [@@@@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’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 @@@@]</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 @@@@) 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’t have to keep
|
|
track of which objects have been fenceposted and which have not, and
|
|
don’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 – they don’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’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’t find a tag. If
|
|
the call didn’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 “lost” 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> *format_return</em>, <a class="reference internal" href="../topic/arena.html#mps_arena_t" title="mps_arena_t">mps_arena_t</a><em> arena</em>, <a class="reference internal" href="../topic/format.html#mps_fmt_t" title="mps_fmt_t">mps_fmt_t</a><em> format</em>, [fp<em> 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> *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> addr_io</em>, size_t<em> 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> 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> addr</em>, size_t<em> size</em>, <a class="reference internal" href="../topic/format.html#mps_fmt_t" title="mps_fmt_t">mps_fmt_t</a><em> format</em>, <a class="reference internal" href="../topic/pool.html#mps_pool_t" title="mps_pool_t">mps_pool_t</a><em> pool</em>, void<em> *tag_data</em>, void<em> *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> arena</em>, <a class="reference internal" href="../topic/pool.html#mps_pool_t" title="mps_pool_t">mps_pool_t</a><em> pool</em>, <a class="reference internal" href="#mps_objects_step_t" title="mps_objects_step_t">mps_objects_step_t</a><em> step</em>, void<em> *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> arena</em>, <a class="reference internal" href="#mps_objects_step_t" title="mps_objects_step_t">mps_objects_step_t</a><em> step</em>, void<em> *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’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
|
|
“class wrapper” <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->class->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&view=status%3dopen&display=Job:Priority:Title&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> »</li>
|
|
<li><a href="index.html" >Design</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <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> |