*** Notes *** 1. I used @@@xxx@@ to flag thinks to be bolded. 2. The figures and files are as follows: Figure 1 ERLUN.MAC Figure 2 ERTXT.MAC Figure 3 ERMSG.MAC Figure 4 ERQIO.MAC Figure 5 QIODF.MAC 3. The two files to make available on ARIS are ERROR.MAC and ERDEF.MAC *********** Reporting Errors One standard function of operating systems which RSX performs poorly is processing errors from system directives or I/O requests. Errors are reported by RSX by returning a negative error code in either the Directive Status Word ($DSW) or the I/O Status Block. There is no further mechanism to let the application turn the error value into some constructive message to the user or invoke exception handlers for various conditions. In contrast, VMS provides an excellent mechanism for handling system errors. The default processing for the LIB$SIGNAL system call outputs the appropriate error message to the user. Depending on the severity of the error, either the image exits or control is returned to after the LIB$SIGNAL call. A program may establish exception handlers to perform any needed special processing. Finally, applications can define their own unique error codes and matching messages using the MESSAGE utility. Implementing the VMS signal mechanism is certainly made easier by a 32-bit virtual address space. But is is possible to put together a RSX error package which provides error messages at low overhead. The RSX distribution kit includes a file named [1,2]QIOSYM.MSG. This file is made up of 64 character fixed-length records, one for each I/O and directive error code. Records 1 through 128 match up to I/O error codes -1 through -128. The remaining records in the file match directive errors. These records are indexed by adding 128 to the absolute value of the directive error. QIOSYM.MSG has the messages we want to output for errors. Now all we need is a mechanism to read the appropriate record from QIOSYM and output to the user terminal. Buried in PIP is a set of routines which do just this. However, the routines are not general purpose enough for our requirements. The error package must be unobstrusive. You want to be able to use the package with existing applications without thinking about it. The packet must be small and require no special task build options. Several problems must be solved to met these goals. One problem is what logical unit numbers should be used to read QIOSYM.MSG and output the error message. If specific logical unit numbers are used, there is almost certainly to be conflicts with other uses. Floating numbers could be used but then you have to be sure which numbers are free, add an error package initialization routine and adjust the task build command files for the new units. Fortunately, TKB provides us a clean mechanism to allocate logical units for special uses. The definition of certain reserved global symbols in the root segment of a task causes TKB to allocate additional logical unit numbers and store the numbers in the words referenced by the symbols. This mechanism is used to allocate the logical units used by the overlay runtime system and ODT as shown below: .NOVLY::.WORD 0 ;Overlay LUN .ODTL1::.WORD 0 ;ODT TI: .ODTL2::.WORD 0 ;ODT CL: The error package uses the same technique to allocate its two logical units. The package uses the special symbols reserved for user software: .USLU1 and .USLU2. These symbols are declared in the module @@@ERLUN@@ (figure 1). For more information on reserved symbols, see Appendix E of the Task Builder Manual. Another problem is how to read QIOSYM.MSG without the overhead of FCS or RMS. The solution is to issue the QIO's directly to the file system. The module @@@ERTXT@@ (figure 2) shows how this is done. After assigning one of our special logical units to the system disk (LB:), the routine finds the directory [1,2] in the master file directory by using the filename 001002.DIR. The results of this lookup are used to find the file QIOSYM.MSG which is then opened for read access. The record number is divided by eight to find which block number to read. Finally, the QIOSYM.MSG file is deaccessed. The above steps are exactly the same sequence of QIO's which would be issued by FCS or RMS to read a record from QIOSYM.MSG. All file protection mechanism are still in effect so no system security is compromised. @@@ERMSG@@ (figure 3) is the common error routine. It outputs a Fortran style error message. A typical fatal error message for a QIO error would look as follows: KATIE -- Exiting due to QIO error -71 Too many outstanding messages Lun: 2 Device: QC0: At PC 003456 The error package handles fours classes of errors: directive, QIO, FCS, and user-declared or program errors. The first line gives the task name, error class, and error number. The next line is the corresponding text from either QIOSYM.MSG or the caller. The third line depends on the type of error. For QIO errors, the line specifies the logical and devices assigned to the unit. FCS errors also display the current filename. The final line types the program counter at the point where the error was detected. @@@ERQIO@@ (Figure 4) shows how ERTXT and ERMSG are called to process QIO errors. There are similar modules for the other three classes of errors. These is no RMS support because I have not found any text file similar to QIOSYM.MSG for RMS errors. The last step is to add calls to the error package from the application code. A set of macros is provided to make the package easy to use in assembly language programs. The definition of @@@QIOWRN@@ and @@@QIOERR@@ (figure 5) illustrate the features the macro definitions. The macros begin by checking the I/O status and skipping error processing if the I/O completed with success. Notice how MACRO-11 will autonatically general a label if the @@@?defadr@@ argument is blank. The directive and FCS error macros check for errors by branch to defadr if the carry bit is clear. Both directives and FCS use the carry bit set to signal an error. Not all errors are illegal. For instance, you might expect to get an end-of-file error (IE.EOF) when reading from a terminal. The QIOWRN and QIOERR macros will check the error against an optional condition list which conists of error code, branch address pairs. For example, the following sequence issues a read to a terminal and checks for several non-fatal errors. This sequence also shows how the DIRERR and QIOERR macros are used together to check for QIO completion. QIOW$S #IO.RVB,#1,#1,,#IOS,,<#BUF,#80.> DIRERR QIOERR IOS,#1,<,> The directive and FCS error macros also use condition lists to handle non-fatal conditions. Directive errors are checked against $DSW and FCS errors are compared to F.ERR(R0). Each error class has two macros. The ERR form declares fatal errors and will exit the task. The WRN form will return control, optionally jumping to the @@@contin@@ address if it is specified. The error package makes it simple to check every FCS call, directive, and QIO for errors and to output constructive messages when errors are detected. By putting the various modules into SYSLIB.OLB and the macro definitions into SYSMAC.SML, the only special programming needed to use the package is to declare the macros and add the macro definitions to the code. There is also a Fortran callable interface to process directive and QIO errors. The package is available from ARIS. For your convience, all source modules have been concantentated to the file ERROR.MAC. You will need to split the modules apart when you copy ERROR.MAC to your system The macro definitions are in the file ERDEF.MDF. The error package has also been submitted to the DECUS Fall 1986 RSX SIG tape in account [346,100] (along with other odds and ends from my system). This tape should be available around February 1987 from your Local User Group or the National DECUS library.