180 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
.\"	Logging
 | 
						|
.\"
 | 
						|
.\"	$Id$
 | 
						|
.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 relevant places.
 | 
						|
.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.
 |