1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-13 06:50:39 -08:00

Removed basic untruths and added some discussion of debugging, though this starts to resemble a manual rather than a design document, and needs to be reworked.

Copied from Perforce
 Change: 179203
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2012-09-03 15:28:57 +01:00
parent 986d55351a
commit 13e0ecd5fe

View file

@ -234,10 +234,7 @@ IMPLEMENTATION:
Annotation
<a id="annot" name="annot">.annot</a>: An event annotation is of the form:
EVENT_PAW(FooCreate, pointer, address, word);
<a id="annot.format" name="annot.format">.annot.format</a>: Note that the format is indicated in the macro name. See
.format.
EVENT3(FooCreate, pointer, address, word);
<a id="annot.string" name="annot.string">.annot.string</a>: If there is a string in the format, it must be the last
parameter (and hence there can be only one). There is currrently a maximum
@ -247,29 +244,27 @@ string length, defined by EventMaxStringLength in impl.h.eventcom.
macro, as registered in impl.h.eventdef.
<a id="annot.param" name="annot.param">.annot.param</a>: The parameters of the event should be given as the remaining
parameters of the event macro, in order as indicated in the format.
parameters of the event macro, in order as indicated in the event parameters definition in impl.h.eventdef.
Registration
<a id="reg" name="reg">.reg</a>: All event types should be registered in impl.h.eventdef, in the form of a
relation.
<a id="reg" name="reg">.reg</a>: All event types and parameters should
be registered in impl.h.eventdef, in the form of a higher-order list
macros.
<a id="reg.just" name="reg.just">.reg.just</a>: This use of a relation macro enables great flexibility in the use of
<a id="reg.just" name="reg.just">.reg.just</a>: This use of a higher-order macros enables great flexibility in the use of
this file.
<a id="reg.rel" name="reg.rel">.reg.rel</a>: The relation is of the form:
RELATION(FooCreate, 0x1234, TRUE, Arena, PAW)
<a id="reg.rel" name="reg.rel">.reg.rel</a>: The event type registration is of the form:
EVENT(X, FooCreate, 0x1234, TRUE, Arena)
<a id="reg.type" name="reg.type">.reg.type</a>: The first parameter of the relation is the event type. This needs
no prefix, and should correspond to that used in the annotation.
<a id="reg.code" name="reg.code">.reg.code</a>: The second parameter is the event code, a 16-bit value used to
represent this event type. [Not yet used. GavinM 1997-07-18]
<a id="reg.code.temp" name="reg.code.temp">.reg.code.temp</a>: On an interim basis, new events also have to be registered in
impl.h.eventcom. This will no longer be required when the event file format is
revised.
represent this event type. Codes should not be re-used for new event types, to allow interpretation of event
log files of all ages.
<a id="reg.always" name="reg.always">.reg.always</a>: The third parameter is a boolean value indicating whether this
event type should be implemented in all varieties. See .control.buffer.
@ -284,10 +279,39 @@ event falls into. See .control. The possible values are:
Seg -- per segment
Ref -- per reference or fix
Object -- per object or allocation
This list can be seen in impl.h.event.
User -- invoked by the user through the MPS interface
This list can be seen in impl.h.eventcom.
<a id="reg.format" name="reg.format">.reg.format</a>: The fifth parameter is the format (see .format) and should
correspond to the annotation (see .annot.format).
[.reg.doc: Add a docstring column. RB 2012-09-03]
.reg.params: The event parameters registration is of the form:
#define EVENT_FooCreate_PARAMS(PARAM, X) \
PARAM(X, 0, P, firstParamPointer) \
PARAM(X, 1, U, secondParamUnsigned)
.reg.param.index: The first column is the index, and must start at zero
and increase by one for each row.
.reg.param.sort: The second column is the parameter "sort", which, when
appended to EventF, yields a type for the parameter. It is a letter from the following list:
P -- void *
A -- Addr
W -- Word
U -- unsigned int
S -- char *
D -- double
B -- Bool
The corresponding event parameter must be assignment compatible with the type.
.param.types: When an event has parameters whose type is not in the above
list, use the following guidelines: All C pointer types not representing
strings use P; Size, Count, Index use W; others should be obvious.
.reg.param.name: The third column is the parameter name. It should be a valid C identifier
and is used for debugging display and human readable output.
[.reg.param.doc: Add a docstring column. RB 2012-09-03]
<a id="reg.dup" name="reg.dup">.reg.dup</a>: It is permissible for the one event type to be used for more than one
annotation. There are generally two reasons for this:
@ -297,69 +321,65 @@ Note that all annotations for one event type must have the same format (as
implied by .reg.format).
Format
<a id="format" name="format">.format</a>: Where a format is used to indicate the type, it is a sequence of
letters from the following list:
P -- void *
A -- Addr
W -- Word
U -- unsigned int
S -- char *
D -- double
The corresponding event parameters must be assignment compatible with these
types.
<a id="format.zero" name="format.zero">.format.zero</a>: If there are no parameters for an event, then the special format
"0" should be used.
<a id="format.types" name="format.types">.format.types</a>: When an event has parameters whose type is not in the above
list, use the following guidelines: All C pointer types not representing
strings use P; Size, Count, Index use W; Bool use U; others should be obvious.
<a id="format.support" name="format.support">.format.support</a>: Every format used needs bespoke support in impl.h.eventgen.
It has not been possible to provide support for all possible formats, so such
support is added when required. <a id="format.support.auto" name="format.support.auto">.format.support.auto</a>: There is a tool in
impl.pl.eventgen that will generate impl.h.eventgen automatically. It is used
as follows:
1. Claim the file eventgen.h.
2. Invoke eventgen.pl.
3. Check it compiles correctly in all varieties.
4. Check in eventgen.h.
Control
<a id="control" name="control">.control</a>: There are two types of event control, buffer and output.
<a id="control.buffer" name="control.buffer">.control.buffer</a>: Buffer control affects whether particular events implemented
at all, and is controlled statically by variety using the always value (see
.reg.always) for the event type. This is only relevant to release varieties.
[Not yet implemented. GavinM 1997-07-18]
.reg.always) for the event type. The hot variety does compiles out annotations
with always=FALSE. The cool variety does not, so always buffers a complete
set of events.
<a id="control.output" name="control.output">.control.output</a>: Output control affects whether events written to the internal
buffer are output via the plinth. This is set on a per-kind basis (see
.reg.kind), using a control bit table stored in EventKindControl. By default,
all event kinds are on (in variety.ti). You may switch some kinds off using a
all event kinds are off. You may switch some kinds on using a
debugger.
For example, to disable Ref events using gdb (see impl.h.event for numeric
codes):
break ArenaCreate
break TraceCreate
run
delete 1
call BTRes(EventKindControl, 4)
print EventKindControl |= 4
continue
.control.env: The initial value of EventKindControl is read from the C environment
when the ANSI Plinth is used, and so event output can be controlled like this:
MPS_TELEMETRY_CONTROL=127 amcss
<a id="control.just" name="control.just">.control.just</a>: These controls are coarse, but very cheap.
<a id="control.external" name="control.external">.control.external</a>: There will be an MPS interface function to control
EventKindControl.
<a id="control.external" name="control.external">.control.external</a>: The MPS interface function mps_telemetry_control
can be used to change EventKindControl.
<a id="control.tool" name="control.tool">.control.tool</a>: The tools will be able to control EventKindControl.
Debugging
.debug.buffer: Each event kind is logged in a separate buffer, EventBuffer[kind].
.debug.buffer.reverse: The events are logged in reverse order from the top of the buffer, with the last logged
event at EventLast[kind]. This allows recovery of the list of recent events using the event->any.size field.
.debug.dump: The contents of all buffers can be dumped with the EventDump function from a debugger, e.g.
gdb> print EventDump(mps_lib_get_stdout())
.debug.describe: Individual events can be described with the EventDescribe function, e.g.
gdb> print EventDescribe(EventLast[3], mps_lib_get_stdout())
.debug.core: The event buffers are preserved in core dumps and can be used
to work out what the MPS was doing before a crash. Since the kinds correspond
to frequencies, ancient events may still be available in some buffers, even
if they have been flushed to the output stream. Some digging may be required.
Dumper Tool
<a id="dumper" name="dumper">.dumper</a>: A primitive dumper tool is available in impl.c.eventcnv. For details,
@ -377,7 +397,6 @@ TEXT:
<a id="notes" name="notes">.notes</a>:
- Set always to FALSE for all Ref and Object events;
- Fix use of BT for size in bytes, guess then check, BTInit;
- Resolve protection transgression in impl.h.eventdef;
- Make EventKind* enum members so they can be used from the debugger.
@ -422,6 +441,16 @@ TEXT:
</tr>
<tr valign="top">
<td>2012-09-03</td>
<td><a href="mailto:rb@ravenbrook.com">RB</a></td>
<td>Removed basic untruths and added some discussion of debugging, though this starts to resemble a manual rather than a design document, and needs to be reworked.</td>
</tr>
</table>