181 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| .\"	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.
 |