!TITLE Testing New Subsystems ! This section addressses the practicalities of testing a new subsystem. ! In particular, it draws attention to the difficulties of testing code ! which initially has no access to the terminal I/O procedures and which ! cannot satisfactorily diagnose programming errors (that is, until ! correct operation of the contingency mechanisms has been mastered). ! ! We first describe in more detail the fields in the user record which ! are specially relevant to this situation, namely: ! ! Field DSFI TYPE value ! Base file name 0 ! Director version number 8 ! Director monitor level 16 ! Contingency monitor level 17 ! Director monitor filename 19 ! Test basefile name 35 ! ! Director monitor level and contingency monitor level are cleared to ! zero following an IPL. !<Test basefile name ! We have stated that "basefile name" specifies the name of the object ! file that is to be entered as the "subsystem", and that the version ! residing on a fixed site on the System disc is used if that name is ! null. If the "test basefile name", is non-null, it overrides the ! setting of "basefile name", even if the latter is null, for the next ! invocation. Thus if the subsystem under test fails disastrously the ! next log-on will yield the default or specified subsystem, which can ! then be used to study the failure and remake the test subsystem. !> endoflist !<Director monitor filename ! The Director monitor filename, if non-null, specifies a file belonging ! to the process owner, into which Director places the following: ! * Process failure messages not diagnosed by the subsystem. ! * Extra monitoring of Director procedure entries (see 'Director ! monitor level'), or extra monitoring of contingencies. ! * Text specified, by the process, to Director procedure DPRINTSTRING ! * The contents of areas of store, printed by DDUMP. ! ! This monitoring file, which must not exceed 512 Kbytes in size, is ! used in a circular manner. !> !<Contingency monitor level ! For the case of being unable to satisfy references to Director ! procedures, and for other programming errors not otherwise diagnosable, ! the field "contingency monitor level" will be useful. This ! field is zeroed at IPL, it can be set by a call of Director procedure ! DSFI (TYPE=17). Bits in this word have meanings as follows: ! ! Bit value Meaning and use ! 1 Print a routine trace-back on the occurrence of a ! contingency, with contents of stack frames. ! 2 Print text describing the contingency in words and codes ! ("CLASS/SUBCLASS"). ! 4 Print a hexadecimal dump of the stack segment. ! 8 2**3 Print a hexadecimal dump of Director GLA. ! 16 Print the contents of the virtual memory (relating ! segment number to filename and to disc address). ! 32 Print a de-assembly from the code segment of the area ! around the value of the PC register at the time of the ! contingency. ! 64 Print out the machine registers. ! ! A useful value for this field is 99. ! ! In order to diagnose the situation in which a subsystem has been unable ! to satisfy its references to Director procedures, it is useful to have ! a recognisable pattern in the places where the System Call descriptors ! are intended to be placed. With the contingency monitor level 64, that ! pattern will be found in the printing of the machine registers DR0 and ! DR1 if the filling of the System Call descriptor was unsuccessful. ! ! The contingency monitor level field can also be set by typing, at the ! Oper console, a command of the form: ! n/SIGMON m 0 ! where n is the process number (as displayed on the Oper screen) ! m is an integer specifying the required value of the field, ! as above. !> !<Director monitor level ! If Director monitor level is set non-zero, see SETDIRMON, a ! message is written to Dirlog after each Director procedure called, ! giving the values of the parameters supplied and the result returned. !> !<Director version ! A System disc has four fixed sites (256 Kbytes each), for up to four ! versions of Director. Site zero is used by default. Setting the ! Director version field causes the next invocation of the process to use ! the specified Director version (0, 1, 2 or 3) rather than the default ! version (0). This facility should only be used after consultation with ! the System Manager, as the contents of a given Director site cannot ! always be guaranteed to be valid. !> list !<DDUMP externalroutine DDUMP(integer START, FINISH, CH, LIM) ! ! Prints a hexadecimal dump from virtual address START to virtual address ! FINISH to DIRLOG. The dump has either 16 if LIM = 16, or 32 bytes per ! line. !> INTEGER SAVELOGACT, SAME, ADR, J, K, A, L, SAMEAS STRING (31)ZEROES SAVELOGACT = LOG ACTION LOG ACTION = LOG ACTION & (¬DT) ! START = START & (¬3) FINISH = FINISH & (¬3) LIM = 32 UNLESS LIM = 16 ! SAME = 0; ! number of consecutive lines which are the same ADR = START & (¬(LIM - 1)); ! start of first 'line' ! WHILE ADR < FINISH CYCLE K = ADR + LIM - 4; ! useful number ! A = ADR; ! validation limits L = LIM IF ADR < START C THEN L = L - (START - ADR) AND A = START IF ADR + LIM > FINISH C THEN L = L - (ADR + LIM - FINISH) IF VAL(A, L, 0, 0) = 0 C THEN WRS("Address Validation Fails") AND -> OUT ! IF START + LIM <= ADR <= FINISH - LIM START ! at least one whole line before and still to do SAMEAS = SAME + 1 ZEROES = "ZEROES" CYCLE J = ADR, 4, K SAMEAS = 0 AND EXIT UNLESS INTEGER(J-LIM) = INTEGER(J) ZEROES = "SAME AS ABOVE" UNLESS INTEGER(J) = 0 REPEAT SAME = SAMEAS FINISH ELSE SAME = 0 ! IF SAME < 2 START ; ! print address of line PRINTSTRING("(") PRHEX(ADR) PRINTSTRING(") ") FINISH ! WRS(ZEROES) IF SAME = 1 ! IF SAME = 0 START CYCLE J = ADR, 4, K PRINTSTRING(" ") IF START <= J < FINISH C THEN PRHEX(INTEGER(J)) C ELSE SPACES(8) REPEAT SPACES(2) CYCLE J = ADR, 1, K + 3 CH = 32 IF START <= J < FINISH START CH = BYTEINTEGER(J) CH = 32 UNLESS 32 < CH < 126 FINISH PRINTSYMBOL(CH) REPEAT NEWLINE FINISH ADR = ADR + LIM REPEAT OUT: LOG ACTION = SAVELOGACT END ; ! DDUMP ! !----------------------------------------------------------------------- ! !<DPRINTSTRING externalroutine DPRINTSTRING(string (255)S) ! ! Allows a privileged process to write a string to DIRLOG. !> PRINTSTRING(S) IF DTRYING << 27 < 0 END ; ! OF DPRINTSTRING ! !----------------------------------------------------------------------- ! SYSTEMROUTINE PRINTFL(LONGREAL X,INTEGER A,B) END ; ! PRINTFL ! !----------------------------------------------------------------------- ! ROUTINE PRINTSYMBOL(INTEGER CH) CONSTINTEGER CH MAX = 655360; ! MAX NO OF CHS TO BE WRITTEN TO DIRLOG BY ONE PROCESS CONSTINTEGER SPOOL AT BYTES = 60000; ! SPOOLING OF DIRLOG TRIGGERED WHEN NO OF BYTES AVAILABLE EXCEEDS THIS VALUE CONSTINTEGER SEMANO = (1 << 31) ! 1 ! CONSTINTEGER MAX LINE = 132; ! excluding NL character OWNSTRING (MAX LINE + 1) LINE OWNINTEGER LOG I = 1, CH COUNT = 0, SUPPRESS NL = NO ! STRING (MAX LINE + 1) OUTLINE INTEGER I, BYTES, LEN, MUST TELL DIRECT, SAVE LOGACT INTEGER ULOG, DIRLOG, MAINLOG, DAT, USE SEMA, IVE GOT SEMA; ! BOOLEANS INTEGER SEMADR, J RECORD (FHDRF)NAME H RECORD (DIRCOMF)NAME DIRCOM RECORD (PARMF) P CH = CH & 255 RETURN IF SUPPRESS NL = YES AND (CH = NL OR CH = ' ') RETURN UNLESS CH = NL OR 32<= CH <=126 ! SAVE LOGACT = LOG ACTION DAT = SAVE LOGACT & DT ! IF LINE = "" START ; ! start of line SUPPRESS NL = NO UNLESS DAT = NO C THEN LINE="DT: ".DATE." ".TIME." ".PROCUSER." ".ITOS(PROCESS)." " FINISH ! LINE = LINE.TOSTRING(CH) LEN = LENGTH(LINE) IF LEN = MAX LINE START LINE = LINE.SNL LEN = LEN + 1 CH = NL FINISH RETURN UNLESS CH = NL ! ! Output the string ! ! Move string to allow recursion (for monitor printing) SUPPRESS NL = YES OUTLINE = LINE LINE = "" ULOG = SAVE LOGACT & WRTOF DIRLOG = SAVE LOGACT & DLOG MAINLOG = SAVE LOGACT & LOG IF DIRLOG#NO AND VAL(DIRLOGAD, DIRLOG KB<<10, W, 0)=0 C THEN DIRLOG=NO AND MAINLOG = YES ! ! Remove dirlog monitoring to avoid screw-ups over the dirlog semaphore. LOG ACTION = LOG ACTION & (¬DLOG) ! ! Take sema if appropriate IVE GOT SEMA = NO ! *STLN_I ! IF I >> 18 = SIG STACK SEG OR DIRLOG = NO C THEN USE SEMA = NO C ELSE USE SEMA = YES ! IF USE SEMA = YES AND GOT SEMA = NO START DIRCOM == RECORD(SYSAD(DIRCOM KEY, -1)) SEMADR = ADDR(DIRCOM_DIRLOGSEMA) J = PP(SEMADR, SEMANO,"PRINTSYMBOL") IVE GOT SEMA = YES IF J=0 FINISH ! ! Move string to appropriate destinations J = STRING TO FILE(LEN, ADDR(OUTLINE)+1, FILE1AD) UNLESS ULOG = NO J = STRING TO FILE(LEN, ADDR(OUTLINE)+1, DIRLOGAD) UNLESS DIRLOG = NO ! UNLESS MAINLOG = NO START CYCLE J = 1, 1, LEN CH = CHARNO(OUTLINE, J) BYTEINTEGER(OUTPAD + LOG I) = CH IF LOG I = 31 OR CH = NL START BYTEINTEGER(OUTPAD) = LOG I *OUT_1 LOG I = 1 FINISH ELSE LOG I = LOG I + 1 REPEAT FINISH ! ! Is DIRLOG full enough to require spooling? MUST TELL DIRECT = NO UNLESS DIRLOG = NO START H == RECORD(DIRLOGAD) BYTES = H_NEXT CYCLIC - H_READ TO IF BYTES < 0 C THEN BYTES = BYTES + (H_NEXT FREE BYTE - H_TXT REL ST) IF BYTES > SPOOL AT BYTES AND H_SEMA = 0 START MUST TELL DIRECT = YES H_SEMA = -1; ! to show that SOMEONE is telling DIRECT FINISH CH COUNT = CH COUNT + LEN IF CH COUNT > CH MAX AND PROCESS # 1 START SAVE LOGACT = SAVE LOGACT & (¬DLOG) DOPER2("TOO MUCH OUTPUT") FINISH FINISH IF IVE GOT SEMA = YES THEN VV(SEMADR, SEMANO) IF MUST TELL DIRECT = YES START P = 0 P_DEST = X'FFFF0028' J = DPON3I("DIRECT", P, 0, 1, PON AND CONTINUE) FINISH LOG ACTION = SAVE LOGACT END ; ! PRINTSYMBOL ! !----------------------------------------------------------------------- ! EXTERNALROUTINE PRHEX(INTEGER I) PRINTSTRING(HTOS(I,8)) END ; ! PRHEX ! !----------------------------------------------------------------------- ! EXTERNALROUTINE PREC(STRING (255)S, RECORD (PARMF)NAME P, INTEGER N) INTEGER A,I PRINTSTRING(S) A = ADDR(P) CYCLE I = 0, 4, 28 PRHEX(INTEGER(A + I)) SPACE REPEAT NEWLINE IF N = 0 END ; ! OF PREC ! !----------------------------------------------------------------------- ! SYSTEMROUTINE WRITE(INTEGER I,PL) INTEGER SIGN STRING (31) S SIGN = ' ' IF I<0 START SIGN = '-' IF I=X'80000000' THEN I=X'7FFFFFFF' ELSE I=-I FINISH S=ITOS(I) IF LENGTH(S)<PL THEN SPACES(PL-LENGTH(S)) PRINTSYMBOL(SIGN) PRINTSTRING(S) END ; ! WRITE ! !----------------------------------------------------------------------- ! SYSTEMROUTINE IOCP(INTEGER EP,N) INTEGER NUM,SYM,J !%CONSTSTRING(15)%ARRAY IM(0:17)= %C ! 'INVALID', ! 'READSYMBOL', ! 'NEXTSYMBOL', ! 'PRINTSYMBOL', ! 'READCH', ! 'PRINTCH', ! 'RECONSTRUCT', ! 'PRINTSTRING', ! 'SELECTINPUT', ! 'SELECTOUTPUT', ! 'ISO CARD', ! 'CHOP CUR OUT', ! 'SET INMARG', ! 'SET OUTMARG', ! 'SET READ ADDR', ! 'PRINTSTRING', ! 'CLOSE STREAM', ! 'MULSYMBOL' SWITCH IO(0:17) EP=0 UNLESS 0<EP<=17 -> IO(EP) IO(3): ! PRINTSYMBOL(N) IO(5): ! PRINTCH(N) PRINTSYMBOL(N) RETURN IO(7): ! PRINTSTRING IO(15): ! PRINTSTRING (ONLY VALID CHARS ALLOWED) J=0; NUM=BYTEINTEGER(N) WHILE J<NUM CYCLE J=J+1 PRINTSYMBOL(BYTEINTEGER(N+J)) REPEAT RETURN IO(17): ! MULSYMBOL NUM=(N>>8) & 255 SYM=N&255 J=0 WHILE J<NUM CYCLE PRINTSYMBOL(SYM) J=J+1 REPEAT RETURN IO(0): IO(1):IO(2):IO(4):IO(6):IO(8):IO(9): IO(10):IO(11):IO(12):IO(13):IO(14):IO(16): WRSN("ILLEGAL CALL ON IOCP, EP =", EP) END ; ! IOCP ! !----------------------------------------------------------------------- ! EXTERNALROUTINE SYMBOLS(INTEGER N, SYMBOL) IF 0 < N < 256 AND 0 <= SYMBOL < 256 C THEN IOCP(17, (N << 8) ! SYMBOL) END ! ! !<SETDIRMON ! %externalroutine SETDIRMON(%string(255)S) ! ! If S is null or is the single character '0', Director monitoring is ! switched off, else it is switched on. When monitoring is on, a record ! is written to Dirlog for each Director procedure called giving the ! parameters used and its result. !> ! !-------------------end-of-included-text--------------------------------- !