123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- .\" 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.
|