.TITLE LIB_LOG_SIGNALS Condition Handler to log signals .IDENT /V04.00/ ;++LIBLOGSIG.MAR ; ; Facility: ; Fermilab Accelerator Control System - ACNET ; ; Abstract: ; The condition handler in this module serves as a generalized ; signal logger for detached processes (usually). This condition ; handler eventually gets control and uses the status code and the PC ; of the LIB$STOP call (or the signal location) to generate a message ; sent to OPCOM to be routed to the system console and the Operator ; log file. ; ; Environment: ; User mode condition handler. In FERMILIB.OLB object library. ;-- ; Author: F. Nagy Fermilab Accelerator Controls ; Modification History: ; ; V01.00 10-Jun-83 FJN Adapted from BUGCHKLOG and NETBUGCHK in ACNET ; V02.00 26-Jan-83 FJN Modified to allow for "PSL=!XL" like new ; version of BUGCHKLOG ; V02.01 27-Jan-83 FJN Handle FAO arguments similar to $PUTMSG for ; now (check for SS$_... or RMS$_... messages) ; V03.00 16-Apr-83 FJN Use $PUTMSG to output the entire message ; (in pieces) to the Operator Log; make the ; condition handler re-entrant once again ; V04.00 12-Sep-83 FJN Change NOESTB parameter to a general flags ; parameter ; .PAGE .SUBTITLE Declarations ; ; Include Files: ; ; NONE ; ; Library Macros: ; .NOCROSS $SSDEF ;System completion codes $RMSDEF ;VAX-11 RMS completion codes $CHFDEF ;Condition Handling Facility defs. $JPIDEF ;Job/process information codes $OPCDEF ;Operator Communications Codes $SFDEF ;Stack Frame offsets $STSDEF ;Condition codes fields $DSCDEF ;Descriptor definitions .CROSS ; ; Local Macros: ; ; ;Setup temporary buffer on stack ; of given length, return pointer in ; in register ptr. ; .MACRO TMP.BUF length,ptr MOVZBL #length,ptr ;Get length (in bytes) SUBL2 ptr,SP ;Allocate stack for buffer MOVAB (SP),ptr ;Get pointer to buffer .ENDM TMP.BUF ; ;Setup temporary buffer descriptor on ; stack. Address of the buffer is ; given by buffer and length by buflen ; Return pointer to descriptor in dptr ; .MACRO TMP.DESCR buflen,buffer,dptr CLRQ -(SP) ;Allocate quadword for descriptor MOVZBW #buflen,- ;Buffer length DSC$W_LENGTH(SP) ; into the descriptor MOVAB buffer,- ;Buffer pointer DSC$A_POINTER(SP) ; into the descirptor MOVAQ (SP),dptr ;Return pointer to descriptor .ENDM TMP.DESCR ; ; Equated Symbols: ; ; NONE ; ; Argument list offsets ; nargs = 0 ;Number of arguments in list msgad1 = 4 ;Address of string descriptor of the ; FAO input string for message #1 msgad2 = 8 ;Address of string descriptor of the ; FAO input string for message #2 onmadr = 12 ;Address of longword (only lower 24 ; bits used) of target operator mask flags = 16 ;Flags controlling condition handler namlen = 40 ;Length of buffer for signal name txtlen = 128 ;Length of buffer for signal text msglen = 128 ;Length of buffer for OPCOM message ;Flag bit: flg_v_noestb = 0 ;Do not establish condition handler flg_v_nostr1 = 1 ;No OPCOM message using ctrstr1 flg_v_nostr2 = 2 ;No OPCOM messages using ctrstr2 flg_v_noinfo = 3 ;No INFORMATIONAL messages to OPCOM .PAGE .SUBTITLE Local storage for string pointers ; ; Read/write (inpure) local data program section ; .PSECT _LIB_DATA,PIC,USR,CON,REL,LCL,NOSHR,NOEXE,WRT,RD .SHOW BINARY OPR_MSG1_FMT: ;Address of control string (FAO input) .ADDRESS DFT_OPMSG1 ; for report message #1 OPR_MSG2_FMT: ;Address of control string (FAO input) .ADDRESS DFT_OPMSG2 ; for report message #2 CALL_FLAGS: ;Control flags from setup call .LONG 0 DFT_TXT1: ;Default text (follows process name) .ASCII / signalled !AS. PC=!XL/ ; for message #1 DFT_LEN1 = . - DFT_TXT1 DFT_TXT2: ;Default text (follows process name) .ASCII /: !AS/ ; for message #2 DFT_LEN2 = . - DFT_TXT2 DFT_OPMSG1: ;Default Operator format #1 descriptor .LONG DFT_LEN1+15 .ADDRESS DFT_TEXT1 DFT_OPMSG2: ;Default Operator format #2 descriptor .LONG DFT_LEN2+15 .ADDRESS DFT_TEXT2 DFT_TEXT1: ;Format #1 text buffer .BLKB DFT_LEN1+15 DFT_TEXT2: ;Format #2 text buffer .BLKB DFT_LEN2+15 ASSUME OPC$B_MS_TYPE EQ 0 ;Assume OPCOM message type is 1st byte ASSUME OPC$B_MS_TARGET EQ - ;Assume OPCOM message dest. flags are ; in the next 3 bytes. ASSUME OPC$L_MS_RQSTID EQ - ;Assume OPCOM message request id is in ; second longword of OPCOM message ASSUME OPC$L_MS_TEXT EQ - ;Assume OPCOM message text after above GET_NAME: ;Get process name for default formats $GETJPI itmlst=10$ 10$: .WORD 15 ;Length of buffer for process name .WORD JPI$_PRCNAM ;Process name code .ADDRESS DFT_TEXT1 ;Address of output buffer .ADDRESS DFT_OPMSG1 ;Address of return length word .LONG JPI$C_LISTEND OP_TGT_TYP: ;Operator message request code and .LONG OPC$_RQ_RQST!^XFFFFFF00 ; bit mask selecting all operators ; ; Program section for code and read-only data ; .PSECT _LIB_CODE,PIC,USR,CON,REL,LCL,SHR,EXE,NOWRT,RD .PAGE .SUBTITLE Initialize logging condition handler ;+ LIB_LOG_SIGNALS ; Initialize and (by default) establish a condition handler to log ; signals to system operator(s) and the operator log file. ; ; CALL LIB_LOG_SIGNALS( [ctstr1] [,ctstr2] [,tgtops] [,flags] ) ; ; ctstr1 ... ; ctstr2 $FAO input control strings used to setup the report ; string. See the "Control_Strings" subtopic for more ; information. Passed by descriptor. ; ; tgtops longword in which the low order 24 bits are the bit mask ; describing which system operators the report message ; is sent to. Default is all operators. Passed by ; reference. ; ; flags control bits passed by value. Default is 0 (all bits ; are OFF). See subtopic "Flags" for more detail. ; ; LIB_LOG_SIGNALS will not generate a message for OPCOM if the signal ; is SS$_OPRABORT. ;2 Control_Strings ; The default $FAO control string used to format the first report ; message is " Bugcheck !AS. PC=!XL" ( ; is replaced by the actual process name). A user-supplied control ; string must also include a "!AS" FAO directive to insert the signal ; name text (given as the address of a string descriptor) and a "!XL" ; directive (or equivalent) to insert the address where the signal was ; generated (usually the next byte after the CALL to LIB$STOP or ; LIB$SIGNAL). ; ; The user-specified control string for the first report message may ; also include an additional a "!XL" directive to insert the process ; status longword in the output. Thus an example of the ctstr1 control ; string could be: ; ; "DINGOXX aborted with !AS at PC=!XL and PSL=!XL" ; ; The default $FAO control string used to format the second and ; succeeding report messages is ": !AS" where the ; "!AS" directive in this case is used to insert the signal description ; text as provided by the $PUTMSG service. Any user-supplied control ; string (ctstr2) must also include a "!AS" directive. ; ;2 Recommendations ; The recommended practice is to turn off the first report message ; which uses the clstr1 control string (set the nostr1 flag to 1). ; The signal information is then processed using $PUTMSG and an ; action routine outputs each text line (from $PUTMSG) using the ; second control string. This sometimes results in multiple OPCOM ; messages for same process in response to one signal; this is ; equivalent to the multiple status signals which appear on your ; terminal sometimes (first line starts with "%", the succeeding ; lines start with "-" to indicate subordinate messages). ; ;2 Flags ; The bits of the longword flags parameter have the following uses: ; ; Bit# Flag Use ; ---- ---- --- ; 0 noestb 0 (the default) in this flag causes the routine ; LIB_SIGLOGGER to be setup as the condition ; handler for the outer procedure (caller of the ; LIB_LOG_SIGNALS procedure). Set to 1 to disable ; this action (see LIB_SIGLOGGER subtopic). ; ; 1 nostr1 If 1, then the first OPCOM message (using the ; ctstr1 control string) is skipped. ; ; 2 nostr2 If 1, then the OPCOM messages using the ctstr2 ; control string are not sent. ; ; 3 noinfo If 1, then INFORMATIONAL and SUCCESS messages will ; not be displayed via OPCOM. ;- ;+0LIB_LOG_SIGNALS ; ; Functional Description: ; Establishes the condition handler (LIB_SIGLOGGER) for the outer ; procedure. Can redefine the report message text and the destination ; operator bit mask used in the condition handler. ; ; Calling Sequence: ; CALL LIB_LOG_SIGNALS( {msg1ad {,msg2ad {,onmadr {,flags}}}} ) ; ; Input Parameters: ; msg1ad(AP) - address of a string descriptor for the $FAO control ; string used to assemble the first report message. ; msg2ad(AP) - address of a string descriptor for the $FAO control ; string used to assemble the second report message. ; onmadr(AP) - address of a longword in which the low order 24 bits ; are the bit mask defining the target operators for the ; report message. ; flags(AP) - value is array of flag bits. ; ; Implicit Inputs: ; NONE ; ; Output Parameters: ; R0 - completion status code ; ; Implicit Outputs: ; OPERATOR_MSG1_FORMAT - setup as the address of an $FAO control string ; OPERATOR_MSG2_FORMAT - setup as the address of an $FAO control string ; MSG_BUFFER - operator names bit mask copied to here ; CALL_FLAGS - flags parameter stored here ; ; Condition Codes: ; NONE ; ; Side Effects: ; Unless flags(AP) bit 0 is 0, then the address of LIB_SIGLOGGER will be ; stored as the condition handler of the outer procedure. ; If no user-specified string is provided, the process name is gotten ; and used to form a default string. ;- .ENTRY LIB_LOG_SIGNALS,^M MOVL @SF$L_SAVE_FP(FP),R1 ;Save old "condition handler" setting MOVAB W^LIB_SIGLOGGER,- ;Establish error reporting @SF$L_SAVE_FP(FP) ; condition handler for the caller ; ; Setup default strings using process name ; $GETJPI_G GET_NAME ;Get process name MOVZWL DFT_OPMSG1,R6 ;Get length of process name text ADDW2 #DFT_LEN1,DFT_OPMSG1 ;Add in length of fixed text ADDL3 R6,DFT_OPMSG1+4,R3 ;Get pointer past process name text MOVC3 #DFT_LEN1,DFT_TXT1,(R3) ;Concatenate fixed text to process name MOVC3 R6,@DFT_OPMSG1+4,@DFT_OPMSG2+4 ;Move process name to second fmt ADDW3 R6,#DFT_LEN2,DFT_OPMSG2 ;Add in length of fixed text ADDL3 R6,DFT_OPMSG2+4,R3 ;Get pointer past process name text MOVC3 #DFT_LEN2,DFT_TXT2,(R3) ;Concatenate fixed text to process name CLRL CALL_FLAGS ;Reset flags to default value ; TSTB nargs(AP) ;Check argument count BEQL 9$ ;If no arguments, just exit ; CASEB nargs(AP),S^#1,S^#3 ;Branch on number of arguments 2$: .SIGNED_WORD 10$-2$ ;Just 1 argument .SIGNED_WORD 20$-2$ ;Just 2 arguments .SIGNED_WORD 30$-2$ ;Just 3 arguments .SIGNED_WORD 40$-2$ ;All 4 arguments ;Fall through if more than 3 arguments 40$: MOVL flags(AP),CALL_FLAGS ;Store call flags for later use ASSUME flg_v_noestb EQ 0 BLBC flags(AP),30$ ;If disable bit is off, skip cleanup MOVL R1,@SF$L_SAVE_FP(FP) ;Setup disabled, restore old setting ; of caller's condition handler vector ; 30$: MOVL onmadr(AP),R0 ;Get address of operator names mask BEQL 10$ ;If defaulted, leave current setting INSV (R0),#8,#24,- ;Store 24 bits of operators' mask OP_TGT_TYP ; 20$: MOVL msgad2(AP),R0 ;Get address of control string descr. BNEQ 15$ ;If none given, setup default string MOVAQ DFT_OPMSG2,R0 15$: MOVL R0,OPR_MSG2_FMT ;Save control string descr. address ; 10$: MOVL msgad1(AP),R0 ;Get address of control string descr. BNEQ 5$ ;If none given, setup default string MOVAQ DFT_OPMSG1,R0 5$: MOVL R0,OPR_MSG1_FMT ;Save control string descr. address 9$: RET .PAGE .SUBTITLE Condition Handler to log signals ;+2 LIB_SIGLOGGER ; The condition handler for reporting the signals to the system ; operators is called LIB_SIGLOGGER. It is called with the normal ; condition handler arguments (the signal array address and the ; mechanism array address) as described in the VMS documentation. ; It uses internal storage (setup by LIB_LOG_SIGNALS) to access the ; current target operator mask and the report message control string ; descriptor addresses. ; ; Normally LIB_LOG_SIGNALS automatically establishes this as the ; condition handler for the outer procedure (the procedure which ; calls LIB_LOG_SIGNALS). Usually this outer procedure is the main ; procedure (program entry point). This action is disabled with the ; noestb flag. For languages like VAX PASCAL or VAX C or if you are ; using your own condition handler, the noestb flag should be set and ; LIB_SIGLOGGER established externally by you (either by calling ; LIB_SIGLOGGER in your own condition handler, using LIB$ESTABLISH or ; its equivalent (for VAX PASCAL or C, for instance) to establish ; LIB_SIGLOGGER as a condition handler. ; ; As a condition handler, LIB_SIGLOGGER takes no actions on signals, ; except to resignal all conditions whether or not it sends a message ; to OPCOM for a particular signal. ;- ;+0LIB_SIGLOGGER ; ; Functional Description: ; This routine is a condition handler. It reports signals to the system ; operator(s) via OPCOM and the $SNDOPR system service. The reports ; include the signal name (gotten with $GETMSG) and the signal PC ; (usually the location after a CALL to LIB$STOP). ; ; Calling Sequence: ; status = LIB_SIGLOGGER( signal-array-address, mechanism-array-address ) ; ; Input Parameters: ; CHF$L_SIGARGLST(AP) - address of the signal array which includes (among ; other things) the signal name and the PC. ; CHF$L_MCHARGLST(AP) - address of the mechanism array ; ; Implicit Inputs: ; OPR_MSG1_FMT - address of descriptor for control string for $FAO ; for message #1 ; OP_TGT_TYP - $SNDOPR request code and target operators bit mask ; CALL_FLAGS - control flags for messages ; ; Output Parameters: ; R0 - completion status code ; ; Implicit Outputs: ; NONE ; ; Condition Codes: ; SS$_RESIGNAL - resignal the condition ; ; Side Effects: ; The condition is re-signaled as this condition handler performs no ; corrective actions, serving only to provide notification to the ; operator(s) of a failure in a (usually) detached process. ; ;- .ENTRY LIB_SIGLOGGER,^M MOVL CHF$L_SIGARGLST(AP),R2 ;Get the address of the signal array CMPW CHF$L_SIG_NAME(R2),- ;Check for operator requested abort #SS$_OPRABORT BNEQ 5$ ;Did operator stop the network process? 4$: MOVZWL #SS$_RESIGNAL,R0 ;Resignal the message RET ; 5$: BLBC CHF$L_SIG_NAME(R2),10$ ;Continue on if WARNING or >=ERROR BBS #flg_v_noinfo,- ;For SUCCESS or INFORMATIONAL signal CALL_FLAGS,4$ ; skip OPCOM output if NOINFO flag ; is set! ; ; Do first message, roughly " signalled . PC=" ; (with provision for "PSL="...) unless NOSTR1 control flag is set. ; 10$: BBC #flg_v_nostr1,- ;Check NOSTR1 flag, CALL_FLAGS,11$ ; if set skip message #1 BRW 19$ ; 11$: TMP.BUF namlen,R6 ;Set temporary signal name buffer TMP.DESCR namlen,(R6),R6 ;Setup pointer to name buffer TMP.BUF ,R5 ;Setup tmp. buffer for 1st msg TMP.DESCR ,(R5),R4 ; and descriptor for $SNDOPR TMP.DESCR msglen,OPC$L_MS_TEXT(R5),R3 ; and another for the text $GETMSG_S - msgid=CHF$L_SIG_NAME(R2),- ;Get name of the signal into msglen=DSC$W_LENGTH(R6),- ; the name buffer bufadr=(R6),flags=#<^B1110> SUBL3 #1,CHF$L_SIG_ARGS(R2),R1 ;Get index to PC in signal array $FAO_S - ;Make report text using control string ctrstr=@OPR_MSG1_FMT,- ;Message #1 control string outlen=DSC$W_LENGTH(R3),- ;Return string length outbuf=(R3),- ;Returned string buffer (on stack) p1=R6,- ;Input of signal name text p2=(R2)[R1],- ;PC of signal p3=4(R2)[R1] ; and the following PSL of the signal ADDW3 #OPC$L_MS_TEXT,- ;Length of OPCOM message (with text) DSC$W_LENGTH(R3),- DSC$W_LENGTH(R4) MOVL OP_TGT_TYP,- ;Setup request code and target bit mask OPC$B_MS_TYPE(R5) CLRL OPC$L_MS_RQSTID(R5) ;No reply so clear id $SNDOPR_S (R4) ;Send message #1 to the operator! ; 19$: BBS #flg_v_nostr2,- ;Check NOSTR2 control bit CALL_FLAGS,29$ ; if set, skip messages 2... ; ; Do series of second messages, each roughly ": " ; by calling $PUTMSG and doing the $SNDOPR's from the action routine. Copy ; message vector onto temporary memory, but leave PC and PSL out of longword ; count for the message vector. ; MOVL CHF$L_SIG_ARGS(R2),R1 ;Get count of signal longwords 20$: MOVL (R2)[R1],-(SP) ;Copy to local stack SOBGTR R1,20$ ;Loop to copy all of signal array ; except the count of its longwords SUBL3 #2,CHF$L_SIG_ARGS(R2),- ;Store count of message vector -(SP) ; longwords without counting PC/PSL MOVAL (SP),R2 ;Get pointer to message vector $PUTMSG_S msgvec=(R2),actrtn=SIGLOG_ACTION ; 29$: MOVZWL #SS$_RESIGNAL,R0 ;Resignal the message RET .PAGE .SUBTITLE Action routine for $PUTMSG ;+/SIGLOG_ACTION ; ; Functional Description: ; Action routine for $PUTMSG, called for each message. Formats up a ; OPCOM message and sends to the operator(s). ; ; Calling Sequence: ; CALLS SIGLOG_ACTION(test, param) ; ; Input Parameters: ; 4(AP) - address of message text string descriptor ; 8(AP) - action routine parameter, ignored. ; ; Implicit Inputs: ; OPR_MSG2_FMT - address of descriptor for control string for $FAO ; for message #2 ; OP_TGT_TYP - OPCOM request code and operator target bit mask ; ; Output Parameters: ; R0 - returned as FALSE (0) to prevent $PUTMSG from printing text at ; this time. ; ; Implicit Outputs: ; NONE ; ; Condition Codes: ; NONE ; ; Side Effects: ; NONE ;- SIGLOG_ACTION: .WORD ^M TMP.BUF ,R5 ;Setup temporary buffer for OPCOM TMP.DESCR ,(R5),R4 ; and descriptor for $SNDOPR TMP.DESCR msglen,OPC$L_MS_TEXT(R5),R3 ; and another for the text $FAO_S - ;Use $FAO to setup text to print ctrstr=@OPR_MSG2_FMT,- ; ignoring string truncation errors outlen=DSC$W_LENGTH(R3),- outbuf=(R3),- p1=4(AP) ;Address of message text string descr. ADDW3 #OPC$L_MS_TEXT,- ;Setup length of OPCOM message DSC$W_LENGTH(R3),- DSC$W_LENGTH(R4) MOVL OP_TGT_TYP,- ;Setup request code and target bit mask OPC$B_MS_TYPE(R5) CLRL OPC$L_MS_RQSTID(R5) ;No reply so clear id $SNDOPR_S (R4) ;Send message to operator ; CLRL R0 ;Don't have $PUTMSG print the message RET .END