182 lines
6.6 KiB
Plaintext
182 lines
6.6 KiB
Plaintext
|
.\" Logging
|
||
|
.\"
|
||
|
.\" $Header$
|
||
|
.bp
|
||
|
.NH
|
||
|
THE LOGGING MACHINE.
|
||
|
.PP
|
||
|
Since messages and warnings provided by \fBint\fP include source code file
|
||
|
names and line numbers, they alone often suffice to identify the error.
|
||
|
If, however, the necessity arises, much more extensive debugging information
|
||
|
can be obtained by activating the the Logging Machine.
|
||
|
This Logging Machine, which monitors all actions of the EM machine, is the
|
||
|
subject of this chapter.
|
||
|
.NH 2
|
||
|
Implementation.
|
||
|
.PP
|
||
|
When inspecting the source code of \fBint\fP, many lines in the
|
||
|
following format will show up:
|
||
|
.DS
|
||
|
LOG(("@<\fIletter\fP><\fIdigit\fP> message", args));
|
||
|
.DE
|
||
|
or
|
||
|
.DS
|
||
|
LOG(("\ <\fIletter\fP><\fIdigit\fP> message", args));
|
||
|
.DE
|
||
|
The double parentheses are needed, because \fILOG()\fP is
|
||
|
declared as a define, and has a printf-like argument structure.
|
||
|
.PP
|
||
|
The <\fIletter\fP> classifies the log message and corresponds to an entry in
|
||
|
the \fIlogmask\fP, which holds a threshold for each class of messages.
|
||
|
The following classes exist:
|
||
|
.TS
|
||
|
tab(@);
|
||
|
l l l.
|
||
|
\(bu A\-Z@the flow of instructions:
|
||
|
@A: array
|
||
|
@B: branch
|
||
|
@C: convert
|
||
|
@F: floating point arithmetic
|
||
|
@I: integer arithmetic
|
||
|
@L: load
|
||
|
@M: miscellaneous
|
||
|
@P: procedure call
|
||
|
@R: pointer arithmetic
|
||
|
@S: store
|
||
|
@T: compare
|
||
|
@U: unsigned arithmetic
|
||
|
@X: logical
|
||
|
@Y: sets
|
||
|
@Z: increment/decrement/zero
|
||
|
\(bu d@stack dumping.
|
||
|
\(bu g@gda & heap manipulation.
|
||
|
\(bu s@stack manipulation.
|
||
|
\(bu r@reading the loadfile.
|
||
|
\(bu q@floating point calculations during reading the loadfile.
|
||
|
\(bu x@the instruction count, contents and file position.
|
||
|
\(bu m@monitor calls.
|
||
|
\(bu p@procedure calls and returns.
|
||
|
\(bu t@traps.
|
||
|
\(bu w@warnings.
|
||
|
.TE
|
||
|
.LP
|
||
|
When the interpreter reaches a LOG(()) statement it scans its first argument;
|
||
|
if \fIletter\fP
|
||
|
occurs in the logmask, and if \fIdigit\fP is lower or equal to the
|
||
|
threshold in the logmask, the message is given.
|
||
|
Depending on the first character, the message will be preceded by a
|
||
|
position indication (with the @) or will be printed as is (with the
|
||
|
space).
|
||
|
The \fIletter\fP is determines the message class
|
||
|
and the \fIdigit\fP is used to distinguish various levels
|
||
|
of logging, with a lower digit indicating a more important message.
|
||
|
We will call the <\fIletter\fP><\fIdigit\fP> combination the \fBid\fP of
|
||
|
the logging.
|
||
|
.LP
|
||
|
In general, the lower the \fIdigit\fP following the \fIletter\fP,
|
||
|
the more important the message.
|
||
|
E.g. m5 reports about unsuccessful monitor calls only, m9 also reports
|
||
|
about successful monitors (which are obviously less interesting).
|
||
|
New logging messages can be added to the source code on places you
|
||
|
think relevant.
|
||
|
.LP
|
||
|
Reasonable settings for the logmask are:
|
||
|
.TS
|
||
|
tab(@);
|
||
|
l l l.
|
||
|
@A\-Z9d4twx9@advised setting when trouble shooting (default).
|
||
|
@A\-Zx9@shows the flow of instructions & global information.
|
||
|
@pm9@shows the procedure & monitor calls.
|
||
|
@tw9@shows warning & trap information.
|
||
|
.TE
|
||
|
.PP
|
||
|
An EM interpreter without a Logging Machine can be obtained by undefining the
|
||
|
macro \fICHECKING\fP in the file \fIchecking.h\fP.
|
||
|
.NH 2
|
||
|
Controlling the Logging machine.
|
||
|
.PP
|
||
|
The actions of the Logging Machine are controlled by a set of internal
|
||
|
variables (one of which is the log mask).
|
||
|
These variables can be set through assignments on the command line, as
|
||
|
explained int the manual page \fIint.1\fP, q.v.
|
||
|
Since there are a great many logging statements in the program, of which only a
|
||
|
few will be executed in any call of the interpreter, it is important to be able
|
||
|
to decide quickly if a given \fIid\fP has to be checked at all.
|
||
|
To this end all logging statements are guarded (in the #define) by a test for
|
||
|
the boolean variable \fIlogging\fP.
|
||
|
This variable will only be set if the command line assignments show the
|
||
|
potential need for logging (\fImust_log\fP) and the instruction count
|
||
|
(\fIinr\fP) is at least equal to \fIlog_start\fP (which derives from the
|
||
|
parameter \fBLOG\fP).
|
||
|
.LP
|
||
|
The log mask can be set by the assignment
|
||
|
.DS
|
||
|
"LOGMASK=\fIlogstring\fP"
|
||
|
.DE
|
||
|
which sets the current logmask to \fIlogstring\fP.
|
||
|
A logstring has the following form:
|
||
|
.DS
|
||
|
[ [ \fIletter\fP | \fIletter\fP \- \fIletter\fP ]+ \fIdigit\fP ]+
|
||
|
.DE
|
||
|
E.g. LOGMASK=A\-D8x9R7c0hi4 will print all messages belonging to loggings
|
||
|
with \fBid\fPs:
|
||
|
\fIA0..A8,B0..B8,C0..C8,D0..D8,x0..x9,R0..R7,c0,h0..h4,i0..i4\fP.
|
||
|
.PP
|
||
|
The logging variable STOP can be used to prevent run-away logging
|
||
|
past the point where the user expects an error to occur.
|
||
|
STOP=\fInr\fP will stop the interpreter after instruction number \fInr\fP.
|
||
|
.PP
|
||
|
To simplify the use of the logging machine, a number of abbreviations have been
|
||
|
defined.
|
||
|
E.g., AT=\fInr\fP can be thought of as an abbreviation of LOG=\fInr\-1\fP
|
||
|
STOP=\fInr+1\fP; this causes three stack dumps, one before the suspect
|
||
|
instruction, one on it and one after it; then the interpreter stops.
|
||
|
.PP
|
||
|
Logging results will appear in a special logging file (default: \fIint.log\fP).
|
||
|
.NH 2
|
||
|
Dumps.
|
||
|
.PP
|
||
|
There are three routines available to examine the memory contents:
|
||
|
.TS
|
||
|
tab(@);
|
||
|
l l l.
|
||
|
@\fIstd_all()\fP@dumps the contents of the stack (\fId1\fP or \fId2\fP must be in the logmask).
|
||
|
@\fIgdad_all()\fP@dumps the contents of the gda (\fI+1\fP must be in the logmask).
|
||
|
@\fIhpd_all()\fP@dumps the contents of the heap (\fI*1\fP must be in the logmask).
|
||
|
.TE
|
||
|
.LP
|
||
|
These routines can be used everywhere in the program to examine the
|
||
|
contents of memory.
|
||
|
The internal variables allow the
|
||
|
gda and heap to be dumped only once (according to the
|
||
|
corresponding internal variable).
|
||
|
The stack is dumped after each
|
||
|
instruction if the log mask contains d1 or d2; d2 gives a full formatted
|
||
|
dump, d1 produces a listing of the Return Status Blocks only.
|
||
|
An attempt is made to format the stack correctly, based on the shadow
|
||
|
bytes, which identify the Return Status Block.
|
||
|
.LP
|
||
|
Remember to set the correct \fBid\fP in the LOGMASK, and to give
|
||
|
LOG the correct value.
|
||
|
If dumping is needed before the first instruction, then LOG must be
|
||
|
set to 0.
|
||
|
.LP
|
||
|
The dumps of the global data area and the heap are controlled internally by
|
||
|
the id-s +1 and *1 resp.; the corresponding logmask entries are set
|
||
|
automatically by setting the GDA and HEAP variables.
|
||
|
.NH 2
|
||
|
Forking.
|
||
|
.PP
|
||
|
As mentioned earlier, a call to \fIfork()\fP, causes an image of the current
|
||
|
program to start running.
|
||
|
To prevent a messy logfile, the child process gets its own logfile
|
||
|
(and message file, tally file, etc.).
|
||
|
These logfiles are distinguished from the parent logfile by the a
|
||
|
postfix, e.g.,
|
||
|
\fIlogfile_1\fP for the first child, \fIlogfile_2\fP for the second child,
|
||
|
\fIlogfile_1_2\fP for the second child of the first child, etc.
|
||
|
.br
|
||
|
\fINote\fP: the implementation of this feature is shaky; it works for the log
|
||
|
file but should also work for other files and for the names of the logging
|
||
|
variables.
|