CHAPTER VAX PAGESWAPPER - January 1986 - Volume 7 Number 6 Editor's Workfile . . . . . . . . . . . . . . . VAX-3 Network Information via Undocumented $QIO Calls VAX-4 VAX/VMS System Dump Analyzer Tutorial . . . . VAX-16 VAX System SIG Committee List . . . . . . . . VAX-58 INPUT/OUTPUT . . . . . . . . . . . . . . . . . VAX-61 Forms at the End INPUT/OUTPUT Submission Form . . . . . . . . . VAX-63 System Improvement Request Submission Form . . VAX-65 PAGESWAPPER - January 1986 - Volume 7 Number 6 General material for publication in the Pageswapper should be sent (US mail only -- no "express" services please) to: Larry Kilgallen, PAGESWAPPER Editor Box 81, MIT Station Cambridge, MA 02139-0901 USA Preference is given to material submitted as machine-readable text (best is Runoff source). Line length should not exceed 64 characters. Please do not submit program source, as that is better distributed on the VAX SIG tape. Change of address, reports of non-receipt, and other circulation correspondence should be sent to: DECUS U.S. Chapter Attention: Publications Department 249 Northboro Road (BPO2) Marlborough, MA 01752 USA Only if discrepancies of the mailing system are reported can they be analyzed and corrected. VAX-2 PAGESWAPPER - January 1986 - Volume 7 Number 6 Editor's Workfile Editor's Workfile by Larry Kilgallen, Pageswapper Editor To anyone who cringes - at Stephen Simm's article in this issue documenting QIO calls which DEC has left undocumented, ESPECIALLY anyone from DEC who cringes: Remember that there would be no need for articles such as these if there were supported interfaces from VMS for getting information about the network environment. In the case of these QIO calls there is also the NMLSHR interface which because it parallels DECnet NML channel protocols would seem to be as cast in concrete as one can get without user documentation. But even NMLSHR is not documented. The end of the story - I guess my trial with ordering from the DEC Electronic Store has ended, because four months after placing the order for Pascal documentation I have received an INVOICE, indicating that DEC tried to ship it to a post office box via UPS. Jeers to UPS for accepting what they cannot deliver, but special jeers to the Electronic Store for ignoring the specific shipping directions included in my letter reinstating the order after they lost track of it. Based on previous experience with DECdirect, I will never see the stuff, and if UPS returns it to the shipping point, DEC will not figure it out to stop the "you haven't paid our invoice" process. Meanwhile I can go off to the DEC Bookstore in Bedford and buy it where I tried to originally in July. VAX-3 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls Network Information via Undocumented $QIO Calls Stephen R Simm Phoenix Data Systems, Inc 80 Wolf Road Albany, NY 12205 518-459-6202 Abstract Information on the DECnet network is easily available thru NCP, SHOW NETWORK and a few other commands. Outside of this handful of commands no documented methods exist to retrieve network-related information. And no method is suitable for inclusion into a program image -- ignoring a particularly ugly kludge involving the /OUTPUT quaifier that I'll not detail here. Undocumented methods of access to such information are available thru the $QIO interface to the NETACP. Just what is a network ACP? VMS utilizes Ancillary Control Processes (ACP) for working with various devices. ACP's are implemented to consolidate code that would otherwise be duplicated in several device drivers or when the complexity of certain functions appears unreasonable for inclusion into a device driver. Typical applications for ACP's include file structure operations, communications servers and computer controlled peripherals. The DECnet NETACP provides the NETDRIVER with information on the network in much the way same the disk ACP provides the DUDRIVER information on the file structure. (see note 1) Those familiar with network operations involving inter-node non-transparent communications have undoubtedly encountered the $QIO function code IO$_ACPCONTROL (see note 2) and the mysterious NFB structure used to declare known objects. The NFB (Network Function Block) is loaded with a couple of values and the image magically becomes known to the network software. Of course no other uses of the NFB are documented by Digital. Load the NFB (with the simplified structure shown in the networking examples manual) with the following values: struct { unsigned char fct = NFB$C_DECLNAME; VAX-4 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls unsigned long int flags = 0; } and the specified name is magically declared known to the network software. This is about as much of the NETACP interface as is documented by Digital. (see note 3) Most NFB symbol definitions used by DECnet include the stock Digital prefix code (NFB$ in this case), the variable classification (such as C, T, B or L), an underscore, the target database, another underscore (why is an underscore still a shifted character on all the keyboards?) and the data field in question. And once some of the more useful obscure codes (see note 4) become known the $QIO IO$_ACPCONTROL interface is trivial to use. This VAX C language structure shows what the NFB really looks like: /* | network function block (NFB) structure definition from VMS v4.2 | Sys$Library:LIB.MLB $NFBDEF definitons. | (see note 5 for the field definitions) */ struct nfbstruct { unsigned char nfb$b_fct, nfb$b_flags, nfb$b_database, nfb$b_oper; unsigned long int nfb$l_srch_key, nfb$l_srch2_key; unsigned char nfb$b_oper2, nfb$b_mbz1; unsigned short int nfb$w_cell_size; unsigned long int nfb$l_fldid[NFB_RQST]; }; In addition to a descriptor pointing to the NFB, several other items are required on the $QIO call. Descriptors referencing the match key structure and the return buffer are required. Pointers to the I/O status block (iosb) and the return length longword are required, as well. The return buffer descriptor and the pointers to the return length and iosb are undoubtedly quite familiar to most readers. The match key structure is specific to the NETACP $QIO call. It is a collection of values used by the searches to determine what value(s) is to be returned. It also provides storage for search context information between multiple $QIO calls. An example of the match key structure: struct nfbkey { unsigned long int p4_count, srch, srch2; unsigned short int start; VAX-5 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls unsigned char ctx[NFB$C_CTX_SIZE]; }; Information placed in the return buffer is in one of three formats: a boolean value stored in a longword, a longword value or an ASCIC string. (a string with a word-sized count of characters followed by the string.) The following C code loads the NFB and KEY structures with the codes required to perform a request for a list of the currently reachable nodes: /* | set up the NFB data block for the NETACP $QIO call. Search | key fields (SRCH, SRCH2) with a value of zero are assumed to | be NFB$C_WILDCARD. If fewer FLDID calls are made than the NFB | is sized for ((4 * number of requests) + NFB$C_LENGTH) the value | NFB$C_ENDOFLIST should be used to short-circuit the search. | | NFB$C_FC_SHOW indicates this is a "SHOW" request, | NFB$M_MULT allow multiple returns per $QIO call, | NFB$C_DB_NDI calls for the use of the local node's database, | NFB$C_NDI_REA is a reachable node search request, | NFB$C_OP_EQL matches performed by NFB$C_NDI_REA, | NFB$C_NDI_LOO is a secondary search for loop nodes | NFB$C_OP_NEQ excludes NFB$C_NDI_LOO loopnodes, | nfb$b_mbz1 must be zero, | nfb$w_cell_size is zero for our purposes here, | NFB$C_NDI_NNA returns the node name. nfb$l_fldid[0] is increased | when multiple pieces of information per matched condition(s) is | requested. */ nfb.nfb$b_fct = NFB$C_FC_SHOW; nfb.nfb$b_flags = NFB$M_MULT; nfb.nfb$b_database = NFB$C_DB_NDI; nfb.nfb$l_srch_key = NFB$C_NDI_REA; nfb.nfb$b_oper = NFB$C_OP_EQL; nfb.nfb$l_srch2_key = NFB$C_NDI_LOO; nfb.nfb$b_oper2 = NFB$C_OP_NEQ; nfb.nfb$b_mbz1 = 0; nfb.nfb$w_cell_size = 0; nfb.nfb$l_fldid[0] = NFB$C_NDI_NNA; /* | load the match key in question into the key buffer. */ nfbkey.p4_count = 0; nfbkey.srch = 1; nfbkey.srch2 = 1; nfbkey.start = 0; VAX-6 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls And now for the code sequence that actually calls the NETACP (see note 6): /* | first $ASSIGN a channel to the network pseudo device NET:. Then | check for such snags as a non-existant network or lack of NETMBX. | Issue the $QIOW call with ACPCONTROL to chat with the NETACP. | Check for more errors. Remember to $DEASSGN the channel and check | ACP generated for errors. */ retstat = SYS$ASSIGN(&net_desc,&chan,0,0); if (retstat != SS$_NORMAL) exit(retstat); func = IO$_ACPCONTROL; retstat = SYS$QIOW( 0, chan, func, &iosb, 0, 0, &nfb_desc, &key_desc, &retlen, &buffer_desc, 0, 0); if (retstat != SS$_NORMAL) { /* | $QIO error handling here. Note the $QIO call can SUCCEED but the | ACP can return a failure status in the IOSB return status field. */ } retstat = SYS$DASSGN(chan); if (iosb.condition_value != SS$_NORMAL) { /* | The ACP/IOSB return code is a standard VAX/VMS return code which | can be evaluated using the debugger's EXAMINE/CONDITION command. */ } else { /* | (see note 7) */ } VMS version 4.2 provides a method of checking the origin of network terminals based on logicals in the process's job table. Finding out where a process originated can be difficult (unless you happen to know the name of the process's job logical table happens to be the prefix LNM$JOB_ in front of the hexidecimal location of the process's job information block (JIB)). Obviously the local node must also be running VMS version 4.2 or better. VAX-7 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls Or you can load an NFB block with a request for a search of the LLI database. Here is an example: /* | this search is for a single logical link hardcoded in the key | buffer and will return three items on successful completion. | The return buffer can be considerably smaller than previous | examples, though the length of the NFB structure is set up | longer ((4 * number of requests) + NFB$C_LENGTH + 4). | The extra 4 bytes are required for the NFB$C_ENDOFLIST longword | used here. Dropping both the NFB$C_ENDOFLIST and the extra 4 | bytes would perform admirably. */ nfb.nfb$b_fct = NFB$C_FC_SHOW; nfb.nfb$b_flags = NFB$M_NOCTX; nfb.nfb$b_database = NFB$C_DB_LLI; nfb.nfb$b_oper = NFB$C_OP_EQL; nfb.nfb$l_srch_key = NFB$C_LLI_LLN; nfb.nfb$l_srch2_key = 0; nfb.nfb$b_oper2 = 0; nfb.nfb$b_mbz1 = 0; nfb.nfb$w_cell_size = 0; nfb.nfb$l_fldid[0] = NFB$C_LLI_PNA; nfb.nfb$l_fldid[1] = NFB$C_LLI_PNN; nfb.nfb$l_fldid[2] = NFB$C_LLI_RID; nfb.nfb$l_fldid[3] = NFB$C_ENDOFLIST; /* | For demonstration purposes hardcode the link (here 7192) in | question into the key buffer. */ nfbkey.p4_count = 0; nfbkey.srch = 7192; nfbkey.srch2 = 0; nfbkey.start = 0; All information contained in this article is UNSUPPORTED, UNDOCUMENTED and SUBJECT TO CHANGE by Digital. (read: use it at your own risk) Calls to the NETACP NFB facility are quite widespread throughout VMS (see note 8) but could conceivably be rewritten for any update to VAX/VMS or DECnet/VAX. (Phase V?). If anyone is interested in obtaining complete machine readable source (written in VAX C) of the two programs mentioned in the article please contact the author at the above address or telephone number. 1. I've deliberately overlooked a number of differences in the implementation of the VMS version 4 XQP and the older v3 disk ACP's. The XQP operates multi-threaded and within the context of the caller's process while VAX-8 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls the ACP is single threaded and is contained within the content of a seperate system process. They both perform the same function. 2. the ACPCONTROL function code causes the ACP to become involved in the I/O transfer being initiated. Since most $QIO I/O requests have little need of the ACP it is generally bypassed entirely for performance reasons. This $QIO request, however, wants to talk to whoever is in charge. 3. See Guide to Networking on VAX/VMS, section 8.6.2.10. 4. The target database codes defined in the current VMS v4.2 NFBDEF module (and equivalent English translations) are as follows: NFB$C_DB_LNI local node information NFB$C_DB_NDI common node information NFB$C_DB_OBI object information NFB$C_DB_CRI circuit information NFB$C_DB_PLI line information NFB$C_DB_EFI event logging filters NFB$C_DB_ESI event logging sinks NFB$C_DB_LLI logical links NFB$C_DB_XNI x.25 networks NFB$C_DB_XGI x.25 groups NFB$C_DB_XDI x.25 DTE's NFB$C_DB_XS5 x.25 servers NFB$C_DB_XD5 x.25 destinations NFB$C_DB_XS9 x.29 servers NFB$C_DB_XD9 x.29 destinations NFB$C_DB_XTI x.25 trace facility NFB$C_DB_XTT x.25 tracepoints NFB$C_DB_SPI server process NFB$C_DB_AJI adjecency information NFB$C_DB_ARI area information (on AREA routers only) NFB$C_DB_SDI service (DLE) information NFB$C_DB_XAI x.25 access database Valid comparison operation codes are: NFB$C_OP_EQL equal NFB$C_OP_GTRU greater-than unsigned NFB$C_OP_LSSU less-than unsigned NFB$C_OP_NEQ not equal Here is a complete (as of VMS 4.2) list of the function codes used in the network. If anyone has an experience with any of the NFB$_FC_ codes other than SHOW please let me know what happened. NFB$_DECLNAME declare name NFB$_DELCOBJ declare object VAX-9 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls NFB$_DELCSERV declare server process available NFB$_LOGEVENT NFB$_READEVENT NFB$_FC_DELETE delete an entry from the database NFB$_FC_SHOW return specified field values NFB$_FC_SET set/modify the field values NFB$_FC_CLEAR clear specified field values NFB$_FC_ZERCOU zero counters (and optionally read) NFB$_FC_LOOP loop - used only by PSI to loop x.25 lines And definitions of the NFB item codes: NDI Database definitions (Information on Common Nodes) BOOLEAN return values (returned in longword-sized fields) NFB$_NDI_LCK conditionally writeable parameters are locked NFB$_NDI_LOO set if CNF is for a loopback node NFB$_NDI_REA set if node is reachable LONGWORD returns values NFB$_NDI_TAD uses local node address for the local NDI (ADD uses 0) NFB$_NDI_CTA absolute due time for counters NFB$_NDI_ADD address NFB$_NDI_CTI counter timer NFB$_NDI_ACL active links NFB$_NDI_DEL delay NFB$_NDI_DTY destination type NFB$_NDI_DCO destination cost NFB$_NDI_DHO destination hops NFB$_NDI_SDV service device NFB$_NDI_CPU CPU type NFB$_NDI_STY software type NFB$_NDI_DAD dump address NFB$_NDI_DCT dump count NFB$_NDI_OHO host NFB$_NDI_IHO host NFB$_NDI_ACC access swicth (inbound, outbound, etc) NFB$_NDI_PRX (obsolete) node proxy parameter NFB$_NDI_NND next node address NFB$_NDI_SNV service node version NFB$_NDI_INB async line - inbound node type STRING return values NFB$_NDI_COL collating fields NFB$_NDI_HAC node address/loopline name combo NFB$_NDI_CNT counters NFB$_NDI_NNA node name VAX-10 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls NFB$_NDI_SLI service line NFB$_NDI_SPA service password NFB$_NDI_LOA load file NFB$_NDI_SLO secondary loader NFB$_NDI_TLO tertiary loader NFB$_NDI_SID software id NFB$_NDI_DUM dump file NFB$_NDI_SDU secondary dumper NFB$_NDI_NLI loopback line NFB$_NDI_DLI destination line NFB$_NDI_PUS privileged user ID NFB$_NDI_PAC priv account NFB$_NDI_PPW priv password (requires BYPASS) NFB$_NDI_NUS non-priv user ID NFB$_NDI_NAC non-priv account NFB$_NDI_NPW non-priv password (BYPASS) NFB$_NDI_RPA receive password NFB$_NDI_TPA transmit password NFB$_NDI_DFL diagnostic load file NFB$_NDI_HWA hardware NI address (ROM) NFB$_NDI_LPA loop assistant NI address NFB$_NDI_NNN next node name (goes with NND) LNI database (Local Node Information) BOOLEAN return values (returned in longword sized fields) NFB$_LNI_LCK set if conditionally writable fields aren't NFB$_LNI_SUP set if area numbers are to be suppressed LONGWORD return values NFB$_LNI_ADD address NFB$_LNI_ACL total number of active links NFB$_LNI_ITI incoming timer NFB$_LNI_OTI outgoing timer NFB$_LNI_STA state NFB$_LNI_MLK maximum links NFB$_LNI_DFA delay factor NFB$_LNI_DWE delay weight NFB$_LNI_IAT inactivity timer NFB$_LNI_RFA retransmit factor NFB$_LNI_ETY executor type NFB$_LNI_RTI routing timer NFB$_LNI_RSI routing suppression timer NFB$_LNI_SAD sub address (lower word = lower limit, upper = upper limit) NFB$_LNI_MAD maximum address NFB$_LNI_MLN maximum lines NFB$_LNI_MCO maximum cost NFB$_LNI_MHO max hops NFB$_LNI_MVI max visits NFB$_LNI_MBU max buffers VAX-11 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls NFB$_LNI_BUS forwarding buffer size NFB$_LNI_LPC loop count NFB$_LNI_LPL loop length NFB$_LNI_LPD loop data type NFB$_LNI_DAC default access switch (inbound, outbound, etc) NFB$_LNI_DPX default proxy access (inbound, outbound, etc) NFB$_LNI_PIQ pipeline quota NFB$_LNI_LPH loop help type given to loop requestors NFB$_LNI_BRT broadcast routing timer NFB$_LNI_MAR max areas NFB$_LNI_MBE max nonrouters on NI NFB$_LNI_MBR max routers on NI NFB$_LNI_AMC area max cost NFB$_LNI_AMH area max hops NFB$_LNI_SBS segment buffer size NFB$_LNI_ALI alias local node address (cluster address) STRING returns NFB$_LNI_COL collating field NFB$_LNI_NAM local node name NFB$_LNI_CNT counters NFB$_LNI_IDE identification NFB$_LNI_MVE management version NFB$_LNI_NVE NSP version NFB$_LNI_RVE routing version NFB$_LNI_PHA physical (current) NI address LLI database (Local Link Information) BOOLEAN return values (returned in longword sized fields) NFB$_LLI_LCK conditionally writable fields locked LONGWORD returns NFB$_LLI_DLY round trip delay NFB$_LLI_STA state NFB$_LLI_LLN local link number NFB$_LLI_RLN remote link number NFB$_LLI_PNA partner's node address NFB$_LLI_PID external process id NFB$_LLI_IPID internal process id NFB$_LLI_XWB pointer to XWB NFB$_LLI_CNT counters STRINGS NFB$_LLI_COL collation sequence NFB$_LLI_USR username NFB$_LLI_PRC process name NFB$_LLI_PNN partner's node name VAX-12 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls NFB$_LLI_RID partner's process id AJI parameters (Adjacency information) BOOLEAN return values (longword sized) NFB$_AJI_LCK conditionally writable fields locked NFB$_AJI_REA node reachable LONGWORD return NFB$_AJI_ADD node address NFB$_AJI_TYP node type NFB$_AJI_LIT listen timer for this adjacency NFB$_AJI_BLO partner's block size NFB$_AJI_RPR partner's router priority on NI STRING return NFB$_AJI_COL collating field NFB$_AJI_NNA nodename NFB$_AJI_CIR circuit name AREA (Area Routing Informatioon - Phase IV Level 2 AREA routers only) BOOLEAN returns (longword sized) NFB$_ARI_LCK conditionally writable fields locked NFB$_ARI_REA reachable LONGWORD return values NFB$_ARI_ADD address NFB$_ARI_DCO destination cost NFB$_ARI_DHO destination hops NFB$_ARI_NND next node address STRING returns NFB$_ARI_COL collating field NFB$_ARI_DLI circuit for normal traffic to area 5. Definitions of the NFB structure's fields: nfb$b_fct the desired function code nfb$b_flags operation flags nfb$b_database the target database nfb$b_oper the match operator nfb$l_srch_key primary search key nfb$l_srch2_key secondary search key nfb$b_oper2 secondary match operator nfb$b_mbz1 must be zero VAX-13 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls nfb$w_cell_size your guess or mine? nfb$l_fldid[NFB_RQST] item request codes 6. The $ASSIGN and $DASSGN calls to the _NET: device are required. They assign a channel to the network device thru which communications will occur. The $ASSIGN command to NET: requires NETMBX privilege. A number of error status codes can be returned by the $ASSIGN call. See the documentation in the Guide to Networking on VAX/VMS under the non-transparent communications section for further information on the return codes. 7. The returned information for this example can be unpacked with the following subroutine: unpack_nodes(bufadr) char bufadr[]; { /* | The format of the returned information is a word-length | count of the number of bytes in the node's name followed | by the actual node name. The next node name occurs two | past the length of the previous node name. The two bytes | being the length of the next node name... */ unsigned short int bufsiz = 0; unsigned long int recbas = 0, not_done = TRUE; char node[7]; while ( not_done) { /* | the next statement is BOTH an assign and a comparision. | if bufadr[recbas] returns zero to bufsiz the comparison | returns false. */ if (bufsiz = (unsigned short int) bufadr[recbas]) { if (( not_done) && ( !recbas)) printf( "Currently Reachable Nodes:\n"); strncpy( node, &(bufadr[recbas + 2]), bufsiz); node[bufsiz] = '\0'; recbas = recbas + bufsiz + 2; printf( " %s\n", node); } else not_done = FALSE; } } VAX-14 PAGESWAPPER - January 1986 - Volume 7 Number 6 Network Information via Undocumented $QIO Calls 8. The prettiest -- also the clearest -- section of NETACP $QIO code I've seen anywhere in VMS is buried down in the bowls of the LOGINOUT utility. (INITUSER module, SET_NODE_NAME routine. Halvorsen?) This NETACP/$QIO interface came into being around the Spring of 1982 under what appears to be early version 3 VMS. VAX-15 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial VAX/VMS System Dump Analyzer Tutorial Jamie Hanrahan Simpact Associates San Diego, California ABSTRACT This article is derived from the "SDA Tutorial" session at the Spring '85 Symposium. It describes how to use the VAX/VMS System Dump Analyzer (SDA) to examine a running VMS system or to determine the cause of a system crash. Some background information on the VMS bugcheck mechanism is included, along with several examples showing how actual system crashes were analyzed. INTRODUCTION: WHY USE SDA? The VAX/VMS System Dump Analyzer (SDA) is a powerful utility for analyzing system failures and for examining the "live", running system. Although SDA is primarily thought of as a tool for the systems programmer, and some of the things it can show you are indeed only meaningful if you have a good working knowledge of VMS internals, the knowledgeable system manager or applications programmer will find many uses for it also. There are many things SDA can tell you about your system that just aren't easily accessible by any other means. SDA can also be useful for learning about the system. For _______ instance, if you're studying the internals manual (VAX/VMS _________ ___ ____ __________ Internals and Data Structures by Kenah and Bate, or the "IDSM"), it's very helpful to look at the system with SDA and confirm that the pointers, data structures, and so forth really do look the way the book says they do. This is also a good way to gain experience with SDA before you have to use it to look at a crash. This paper will show you how to use SDA to answer a number of different types of questions about your VAX/VMS system, without assuming extensive knowledge of VMS internals on your part. (I am assuming, though, that you have a copy of the IDSM handy.) I'll also show you how you can use SDA to associate system crashes with software components such as foreign device drivers. On a more advanced level, I'll cover the use of SDA in analyzing VAX-16 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial some actual crash dumps. I'll include brief review of VMS's bugcheck mechanism so that you can see why the stack looks the way it does after a crash. It's worth remembering that, for all its power, all SDA really does is let you look at memory. Fortunately SDA knows a great deal about how to find things in the VMS system and about how the various data structures are laid out, so it can display things in (relatively) easy-to-read form rather than as a long table of hexadecimal longwords. (You can get the table of longwords if you want, of course.) There are built-in commands for looking at the data structures which SDA's authors thought were most important. There is also a command that will generate ___ a reasonably-formatted display for any data structure in the system, as long as SDA knows the symbolic names for the offsets to the fields within the structure -- more on this later. This discussion is based on SDA as included with VMS Versions 4.0 and 4.1. I see from our (as yet uninstalled) 4.2 kit that there is a new version of SDA; it offers more of the specialized SHOW commands, more options on SHOW PROCESS, and a few other enhancements. All of the information presented here, however, is still valid under 4.2, with the possible exception of some of the hexadecimal addresses and offset values. PRIVILEGES AND QUOTAS You will need the Change Mode to Kernel (CMKRNL) privilege to use SDA to look at the live system (ANALYZE/SYSTEM); you will need read access to the dump file (which is by default only accessible from system UICs) to look at a crash dump (ANALYZE/CRASH). SDA is not installed with CMKRNL privilege, and the dump file is normally set to world-no-access, because allowing nonprivileged users to use SDA is a security risk. Among other things, it will let them see usernames and __ _____ passwords, in clear, in the typeahead buffers associated with terminals if they look at the right time. For both uses of SDA, you will also need read access to the system symbol table file, SYS$SYSTEM:SYS.STB. This is essen- tially a machine-readable form of the system map file, SYS$SYSTEM:SYS.MAP. Like the map file, it was produced when the VMS executive was linked and is distributed with every VMS system. SDA reads this file whenever it's run (this is the reason for the delay before it gives you its first prompt). SDA knows the symbolic names of the various fields in the executive data area (see Appendix A of the IDSM); it uses the system symbol table to find the virtual addresses for each of these symbols. It can then find everything else in the executive by VAX-17 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial following pointers from this area. For looking at dump files, your process should have a paging file quota of at least 3000 more than the size of the dump file in blocks, and the VIRTUALPAGECNT SYSGEN parameter, which determines the maximum number of virtual pages that can be mapped in any process's P0 plus P1 regions, must be at least the size of the dump file (in blocks) plus 2000. These large values are required because SDA maps the entire dump file into your process's virtual address space rather than reading it with RMS. CRASH DUMPS Allocating The Dump File You or your system manager should do some things to allow crash dumps to be taken even if you never intend to run SDA yourself. If you have room on your disk for a dump file, it must be called SYS$SYSTEM:SYSDUMP.DMP and should have four more blocks than your physical memory has pages. (Remember to enlarge the dump file when you upgrade your memory!) It should be set /NOBACKUP, the owner UIC should be [1,4], and only system and owner UICs should have access to it. Finally, the dump file must be reasonably contiguous, as the memory-dumping code can't handle window turns. The SYSGEN utility has a CREATE command which can create or extend the dump file (and page and swap files). A /CONTIGUOUS qualifier is available for the command. You should use this qualifier when you try to create or extend any of these files; only if there is insufficient contiguous space on the disk to make the file contiguous should you use the command without the qualifier. If the file is noncontiguous, SYSGEN checks it to ensure that it doesn't have too many extents. Note that a newly-created dump file (or extension to a dump file) won't be seen by the system until the next boot. If you don't have room for the dump file on your system disk, you can get along without one. The system will then write the dump to the primary paging file, SYS$SYSTEM:PAGEFILE.SYS, which must be the size of: Physical memory in pages, plus four _______ blocks, plus however large it would have to be if you weren't using it for the dump file. This has several serious implications which will be discussed in following sections. VAX-18 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Writing the Dump File If the SYSGEN parameter DUMPBUG is set to a 1 (the default), the system will copy physical memory into the dump file (or paging file), block for block, whenever the system crashes or is shut down by operator request. The extra four blocks in the file allow for a header which contains the bugcheck information (registers, reason for crash, date and time of crash, etc.). There is a flag bit in the dump header that is cleared when a ___ non-operator requested shutdown -- i.e. a crash -- occurs and the file is written. SDA And System Startup You should place commands in your systems's SYSTARTUP.COM file to do a first-level analysis of the crash -- enough to let you decide whether the crash was your fault or something you should complain to DEC about. Here are the commands recommended by the SDA manual (in the Utilities binder of the Version 4 documentation set): $ ANALYZE/CRASH SYS$SYSTEM:SYSDUMP.DMP COPY SYS$SYSTEM:SAVEDUMP.DMP SET OUTPUT LPA0:SYSDUMP.LIS SHOW CRASH SHOW STACK SHOW SUMMARY SHOW PROCESS/PCB/PHD/REG SHOW SYMBOL/ALL EXIT When invoked from the system startup command procedure, SDA knows that it only needs to run if the aforementioned flag bit in the dump header is clear; if it's set, it just exits without executing any of the commands. The COPY command copies the dump to another file so that if the system crashes again the previous dump will not be lost. (There is nothing special about the name of the dump copy file; use any name, and any device and directory, that you want.) The COPY command also sets the flag bit in the dump header to indicate that the dump has been saved. SDA will thus execute these commands only on the first startup after a crash. If the dump was written to the paging file, and the SYSGEN parameter SAVEDUMP is set to 1 (as it should be if you're using the paging file for the dump; if it isn't, you might as well set VAX-19 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial DUMPBUG to 0 and not do dumps at all), the blocks in the paging file which are occupied by the dump will not be available for use by the pager until the SDA COPY command has set the flag bit in the dump header. It is most important, therefore, that your system startup command procedure use SDA to copy the dump. Copying the dump file with the DCL COPY or BACKUP command will not set the flag bit and will not release the paging file blocks. The SET OUTPUT command routes all of the output from the commands that follow to the line printer. Change the line printer device name if necessary, and remember that if the printer is owned by a queue, this will only work if the device has been set /SPOOLED as well. The SHOW commands display, in order: The bugcheck information; the contents of the current stack; a list of all of the processes on the system; the process control block, process header, and registers of the process that was current (i.e. running) at the time of the crash; and the values of all of the symbols known to SDA. (I question whether that last command is really necessary, as it produces a huge amount of output and the same information is in the system map file in a more convenient form.) Quotas for the System Startup Process Section 2 described the quota and SYSGEN parameter needs of ANALYZE/CRASH; the system startup process must comply with these needs just as any other process must. The paging file quota used to be a problem under Version 3.x. The system startup process's quotas were taken from the "PQL_Dquota" SYSGEN parameters, and AUTOGEN didn't bother setting PQL_DPGFLQUOTA to allow for dump analysis. So, if you got an "exceeded quota" message from the ANALYZE/CRASH command in your system startup command procedure, the cure was to increase the value of the PQL_DPGFLQUOTA parameter (following the same rules as were given for the paging file quota in Section 2). Under Version 4 of VMS the startup process's quotas are automatically set high enough (apparently based on other parameters; I haven't checked the source), so this has ceased to be a concern. The VIRTUALPAGECNT parameter must still be looked at, however. If the following message %SYSTEM-F-VASFULL, virtual address space is full VAX-20 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ever appears during a system startup, chances are it came from the ANALYZE/CRASH command in SYSTARTUP.COM. It means that your VIRTUALPAGECNT is set too low. What To Do After A Crash When a crash occurs you should, at minimum, save the console bugcheck output and write a copy of the dump file to some medium that will be convenient to store or to mail, such as mag tape. (One wonders how many tapeless sites bother to send crash dumps to DEC on RL02 packs.) Note that if you write this tape by using BACKUP to copy the "real" system dump file (SYS$SYSTEM:SYSDUMP.DMP), you must use the /IGNORE=NOBACKUP qualifier on your BACKUP command. The dump file is created with the nobackup bit set so that its contents will not be saved on an ordinary backup of your system disk; the file's presence is noted along with all its attributes, but the contents are not copied. If you forget about this when writing your dump tape, DEC will not find the resulting tape to be particularly useful. Copies of the dump file made with the SDA COPY command do not have the nobackup bit set, so writing tapes from them is not a problem. If you think the crash was caused by faulty DEC-supplied software or hardware, send the console bugcheck output and the dump tape to DEC along with a completed Software Performance _______ ______ ________ Report (SPR) form. Each copy of the VAX/VMS System Dispatch contains a set of guidelines for submitting an SPR. Chances are, though, you would like to do a little investigation of the crash yourself, if only to figure out whether or not the crash was DEC's fault. In the following sections we'll look at the various SDA commands and see how to use them both to analyze failures and to glean information from a running system. SDA COMMANDS 1: LOOKING AT THE SYSTEM VAX-21 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial EXAMINE command This command (without qualifiers) is the simplest and most straightforward SDA command. It shows you the contents of one or more longwords in virtual address space. As shown in Table 1, you can specify either a single address, a starting and ending address, or a starting address and a length. You can even omit the address; it will default to the next byte after the location or area you displayed last. Figure 1 shows what happens when you EXAMINE a single location and a range. In the second example, the addresses in the right- hand column of the display refer to the leftmost byte in the ASCII display, and to the rightmost byte in the hex display. SDA (like everything else in VMS) arranges its ASCII displays with the byte addresses increasing from left to right, while in the hexadecimal displays the byte addresses increase from right to left -- both within each longword and from one longword to the next. Binary numbers are thus shown with the least significant byte on the right, which is where it should be -- a longword containing the value 1 looks like 00000001, not 01000000. (Recall that in the VAX architecture the address of ___ any data item or structure, regardless of the data format, is always the address of the lowest-addressed byte.) When you're looking at a dump file, you're restricted to EXAMINEing those virtual pages that were in physical memory at the time the dump was taken. You'll get a "not in physical memory" message if you try to look at something that isn't mapped. Most of the time this isn't a problem, because the code and data responsible for a system crash are usually (but not, it must be admitted, always) in memory at the time of the crash. Table 1: EXAMINE Command Formats ________________________________________________________________ Command Qualifiers Function ________________________________________________________________ EXAMINE [address] Examine one longword (defaults to next byte after previously-examined area) EX start_addr:end_addr Examine range of addresses given bounds EX start_addr;length Examine range given start and length /INSTR Disassembles instructions /TIME Interprets quadword time /PSL Interprets longword as PSL /CONDITION Interprets lw as cond. value VAX-22 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ _ SDA> ex 12300 00012300: 2120294C "L) !" SDA> ex 12300;40 35210001 230E010E 00194641 2120294C L) !AF.....#..!5 00012300 204C5538 21203D20 43413921 20205755 UW !9AC = !8UL 00012310 54000123 2F010E00 3D29254C 55212820 (!UL%)=.../#..T 00012320 20646573 75206563 61707320 6C61746F otal space used 00012330 Figure 1: EXAMINE Output ________________________________________________________________ EXAMINE Qualifiers As shown in Table 1, several qualifiers can be applied to the EXAMINE command. These direct SDA to interpret the contents of the displayed locations in a special way rather than just displaying them in hex and ASCII. We will illustrate the use of several of these in a later section; for now, here is a summary. One of the most useful is EXAMINE/INSTRUCTION, which attempts to disassemble and display the instruction(s) found at the address(es) you specify. This command may produce garbage, however, if you point it at a location that is not in fact the first byte of an actual instruction. (On rare occasions it actually admits that it can't translate the instruction.) A common pitfall here is to do an EX/INS on the entry point of a procedure, forgetting that the entry point contains a register save mask rather than an opcode -- use EX/INS procname+2 for correct results. EX/TIME will interpret a signed quadword binary number as either an absolute or delta time, as appropriate, and will display the time in ASCII form. EX/PSL will interpret a longword as a Processor Status Longword, breaking it out into current and previous access mode, interrupt stack bit, interrupt priority level, condition code bits, etc. This is most handy when you're looking at the kernel or interrupt stack, as these frequently contain one or more PC/PSL pairs that were pushed onto the stack by exceptions or interrupts. EX/CONDITION will display the message from the system message file corresponding to the value of the longword at the examined location. This is also useful when looking at stack contents, VAX-23 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial as the stack will often contain a signal array whose second longword will be a condition code value. Table 2: Operators Supported in SDA Expressions ________________________________________________________________ Operator Meaning ________________________________________________________________ unary - negate following value unary @ indirect reference G (unary) 80000000+ H (unary) 7FFE0000+ binary + - * / @ add, subtract, multiply, divide, shift ________________________________________________________________ SDA Expressions In the examples in Figure 1 we typed in actual virtual addresses to be EXAMINEd. This quickly gets tedious. Fortunately, addresses (and other operands) to SDA commands can be ___________ expressions of considerable complexity. Operators Table 2 shows the operators that can be used in SDA expressions. In addition to the standard arithmetic ones (unary and binary "+" and "-", and binary "*" and "/"), SDA provides the following: The unary "@" operator specifies indirection. For instance, EXAMINE @200 examines the longword whose address is found at location 200. The binary "@" operator performs an arithmetic shift on its first operand. The second operand specifies the number of bits and the direction (positive = shift left, negative = shift right). VAX-24 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Typing a G or H in front of a number adds 80000000 or 7FFE0000 to it. This is extremely convenient for specifying system-space or control region addresses. For instance, 80002E7D may be typed as G2E7D. The precedence rules for SDA's operators are adopted from standard algebra: All the unary operators first, then multiply, divide and shift, and finally addition and subtraction, going left-to-right within a precedence level. You can override these rules with parentheses if necessary. Operands Each operand in an SDA expression can be either a number or a symbol. SDA assumes that all numbers are in hex unless prefixed with ^O (for octal) or ^D (for decimal). SDA symbols follow the same syntax rules as standard VAX/VMS symbols, and in fact all of the symbols in the system symbol table file (SYS.STB) are known to SDA. For instance, the first instruction of the rescheduling entry point of the VMS scheduler is at the location called SCH$RESCHED; if you want to look at it you can just type SDA> EX/INS SCH$RESCHED and SDA will respond with MPH$RESCHED: MTPR #08,#12 (Notice two things: First, SDA displayed the address of this instruction as a symbol, not in hex, and second, the symbol it picked wasn't the one we typed. We'll explain this shortly.) The READ command tells SDA to read another symbol table file and add the symbols found therein to its list. For instance, SDA> READ SYS$SYSTEM:SYSDEF.STB reads the file that defines the symbolic names for the fields for the most common VMS data structures; this information is needed by the FORMAT command, to be described. Any other symbol table file may be read in this manner. If you find that the symbols for some of the structures you want to look at aren't known to SDA even after it's read SYSDEF.STB, you can build your own files to define them. A symbol table file essentially is just an object file with only global symbol definition records, so all you need to do is generate an object VAX-25 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial file that globally defines the symbols you want. For instance, to let SDA know about the symbols that define the "xyz" data structure, build a small MACRO source file (I hesitate to call it a "program") and assemble it as follows: $ CREATE xyzDEF.MAR .LIBRARY /SYS$LIBRARY:LIB/ $xyzDEF GLOBAL .END ^Z $ MACRO xyzDEF replacing "xyz" with the name of the data structure you're interested in. Then use the following command at the SDA prompt: SDA> READ xyzDEF.OBJ You can also define symbols "manually" with the DEFINE command: SDA> DEFINE symbol expression The expression can be any valid SDA expression. "Automatic" Symbols Finally, SDA knows about several symbols whose values change according to the current context. For lack of an official term, I have dubbed these "automatic" symbols. They are listed in Table 3. SDA knows the names of the general registers R0 through R11, AP, FP, PC, and PSL, but not SP -- you have to use ISP, KSP, ESP, SSP, or USP to specify the stack you want (interrupt, kernel, executive, etc.). The base and length registers for the P0 and P1 regions are also known: P0BR, P1BR, P0LR, and P1LR. When the system crashes, all of the machine's registers are recorded in the dump header; SDA fetches them and stores them in internal locations. The values of the symbols such as R5, P0LR, etc., are actually psuedo-addresses (in S1 space!) that point to these internal locations. So you can say SDA> EX R5 VAX-26 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Table 3: "Automatic" Symbols ________________________________________________________________ Symbol Meaning ________________________________________________________________ . (period) Current location (set by EXamine) @. Last value displayed R0-R11, AP, FP, PC, PSL General registers KSP, ESP, SSP, USP Stack pointers P0BR, P0LR, P1BR, P1LR Base and length regs for P0 & P1 regions xxDRIVER Address of DPT of xxDRIVER UCB, DDB, DDT, CRB, Addresses of I/O data structures from ORB, IRP, VCB, PDT, most recent SHOW DEVICE output CDDB ________________________________________________________________ to look at the contents of R5. (You're actually looking at the internal location where R5's value, as found in the dump header, is kept.) If you want to look at the location that R5 points to, you can type SDA> EX @R5 and if you want to look at the location eight bytes beyond that in memory, type SDA> EX @R5+8 The period (.) or "dot" is, as it is in the MACRO assembler, the current location pointer. Its value is usually the address of the last location EXAMINEd. There is no Q-register (for last- displayed-value) but you can get the same result with "@.". SDA will automatically define several symbols of the form xxDRIVER -- one for each driver that is loaded into the system. The first two letters are generally the first two letters of the names of the devices serviced by the driver. The value of each such symbol is the address of the corresponding driver prologue table (DPT). Finally, SDA's SHOW DEVICE command defines symbols that point to the I/O data structures for the device you're looking at. This is an undocumented feature, but it's extremely convenient. If you are debugging a device driver, you will find it very helpful to do a SHOW DEVICE ddcu command early in your dialogue with VAX-27 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial SDA. Relating Values to Symbols SDA attempts to interpret many of the values it displays as offsets from known symbols. The values which SDA displays in this fashion are: Addresses in the output of EX/INS and EX , operands in the output of EX/INS, and the contents of the stack in the output of SHOW STACK (to be described). The offset must be nonnegative and must be no greater than 0FFF. If several symbols qualify, the one with the smallest offset is used. If there are more than one with the same smallest offset, the first one in alphabetical sequence is used. This is why, in the EX/INSTRUCTION example earlier, SDA used a different symbol ___ than the one we'd typed in. There are two names for the scheduler's rescheduling entry point, MPH$RESCHED and SCH$RESCHED, and SDA picked the one that came first in its table. Of course, sometimes the symbols SDA displays in this manner are related to the displayed values only by coincidence. For instance, the command SDA> EX 300 produces the display BUG$_NOTVCBUCB: 00000000 "...." because the value of the symbol BUG$_NOTVCBUCB just happens to be 300 hex. Symbols vs. Numbers Since a hexadecimal number such as A100 or FAB also complies with the syntax rules for a symbol, there can be some confusion between the two. SDA checks any such input against its symbol table before interpreting it as a number. If you are unlucky enough to have a defined symbol that looks just like (but has a different value than) a number you want to type in, you can force SDA to interpret your input as a number by putting a "0" in front of it -- e.g., type "0FAB" instead of "FAB". VAX-28 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial This ambiguity also causes trouble if you mistype a symbol, particularly if the first few characters of the symbol happen to be a valid hex number. The error messages you get in such cases are often only vaguely related to the input. This is just something you have to get used to. ________________________________________________________________ SDA> format 80182c80 %SDA-E-NOSYMBOLS, no "UCB" symbols found to format this block SDA> read sys$system:sysdef SDA> format 80182c80 80182C80 UCB$L_FQFL 800029D0 UCB$L_RQFL UCB$W_MB_SEED UCB$W_UNIT_SEED 80182C84 UCB$L_FQBL 800029D0 UCB$L_RQBL 80182C88 UCB$W_SIZE 021C 80182C8A UCB$B_TYPE 10 80182C8B UCB$B_FIPL 08 80182C8C UCB$L_ASTQFL 800E7B34 UCB$L_FPC UCB$T_PARTNER 80182C90 UCB$L_ASTQBL 80198AF0 UCB$L_FR3 80182C94 UCB$L_FIRST 8002B600 . . . Figure 2: Using FORMAT on a UCB ________________________________________________________________ FORMAT Command We now know enough to make effective use of the FORMAT command. This command lets you interpret data structures for which SDA has no built-in command (or for which the built-in command is incomplete): SDA> FORMAT [/TYPE=typ] location If /TYPE is not specified, SDA looks at the byte at location+0A, looks for a symbol of the form DYN$C_typ with the same value as the byte, and, if found, uses all of the symbols it finds of the form typ$x_name (or typ_x_name, for user-defined structures) to interpret the data structure. VAX-29 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Figures 2, 3, and 4 show how FORMAT is used. In Figure 2 we have the address of a Unit Control Block (UCB) and try to use FORMAT to look at it. SDA goes to the TYPE field (the byte at offset 0A in almost all VMS data structures is the TYPE field) and finds the value 10 (hex); it then looks at the symbols (from SYS.STB) of the form DYN$C_xxx and finds that the symbol DYN$C_UCB has the value 10 (hex), so it knows that the structure in question is a UCB. Then it looks for symbols of the form UCB$x_name, but it doesn't find any because they're defined in SYSDEF.STB -- which we forgot to read. We read the file and type the FORMAT command again, and the UCB spills out on the terminal. Notice that SDA uses the field-type character in each symbol (the character between the "$" and the "_" to know how many bytes wide each field is. ________________________________________________________________ SDA> format @sch$gq_cebhd 801E3200 CEB$L_CEBFL 801DE7C0 801E3204 CEB$L_CEBBL 80002210 801E3208 CEB$W_SIZE 0050 801E320A CEB$B_TYPE 04 801E320B CEB$B_STS 00 801E320C CEB$L_PID 0003000F 801E3210 CEB$L_EFC 00000000 . . . SDA> format @. 801DE7C0 CEB$L_CEBFL 80002210 801DE7C4 CEB$L_CEBBL 801E3200 801DE7C8 CEB$W_SIZE 0050 801DE7CA CEB$B_TYPE 04 801DE7CB CEB$B_STS 00 801DE7CC CEB$L_PID 0003000F 801DE7D0 CEB$L_EFC 00000000 . . . SDA> FORMAT @. %SDA-E-INVBLKTYP, invalid block type in specified block SDA> FORMAT @. 801E3200 CEB$L_CEBFL 801DE7C0 801E3204 CEB$L_CEBBL 80002210 801E3208 CEB$W_SIZE 0050 . . . Figure 3: Looking at Common Event Flag Clusters ________________________________________________________________ VAX-30 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial In Figure 3 we are using SDA to look at common event flag blocks, or CEBs. There is no way to do this via a DCL command, but the IDSM (Section 12.1.2) tells us that all of the CEBs in the system are linked into a queue; the queue header quadword is called SCH$GQ_CEBHD. So we format the structure the queue header points to, and sure enough, it's a CEB. The actual event flags are in the field called CEB$L_EFC. We can look at the UIC and cluster name (EFCNAM) fields and see if it's the CEB we want (these are omitted from Figure 3 to conserve space). If not, we just look at the next one. After a FORMAT command, "dot" is set to the starting address of the structure; when structures are in queues, the first two longwords in the structure are used for the forward and backward link, respectively, so we can look at the next CEB in the system very easily by typing SDA> FORMAT @. The last CEB in the queue (the second one, in this case) points "forward" to the queue header. When we repeat the FORMAT @. and see the "invalid block type" message (that means that there was no DYN$C_typ symbol whose value matched the type field of the addressed structure), we know we've looped around to the queue header -- the header is not itself part of a CEB. If we want to start around the queue once more we can simply type FORMAT @. again. In Figure 4 we are looking at the system's timer queue. The IDSM (Section 11.3.2) tells us that the timer queue header is called EXE$GL_TQFL, so we use the FORMAT command on that symbol and the first timer queue element (TQE) appears. We keep searching through the queue until, perhaps, the TQE's PID field matches the PID of the process whose request we're interested in (remember that this is the internal PID). When we find the right TQE, we use EX/TIME to find out when the request is due. (If you do this on a live system, remember that the timer queue is continually changing. ANALYZE/SYSTEM does not grab a "snapshot" of the system when it is started; it looks at the live system as each command is typed, and does no synchronization between commands or even within a command. It is therefore not uncommon, when looking at the live system, to see what appear to be inconsistencies -- broken queues, invalid pointers, and so on.) The FORMAT command uses the size field of a structure to automatically determine its length in bytes; however, it will not display a part of the structure for which it has no defined symbols. For example, it will not display all of an overly-long UCB unless you generate and read a .OBJ file that defines the fields in it. VAX-31 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial SDA COMMANDS 2: ANALYZING CRASHES We are now ready to look at the commands and techniques that may be used to examine and, hopefully, analyze crash dumps. VAX-32 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ SDA> format @exe$gl_tqfl 80002B60 TQE$L_TQFL 801DC660 80002B64 TQE$L_TQBL 80002B58 80002B68 TQE$W_SIZE 0000 80002B6A TQE$B_TYPE 0F 80002B6B TQE$B_RQTYPE 05 80002B6C TQE$L_FPC 8000A1FC TQE$L_PID . . . SDA> format @. 801DC660 TQE$L_TQFL 801E39E0 801DC664 TQE$L_TQBL 80002B60 801DC668 TQE$W_SIZE 0030 801DC66A TQE$B_TYPE 0F 801DC66B TQE$B_RQTYPE 05 801DC66C TQE$L_FPC 80105B55 TQE$L_PID . . . SDA> FORMAT @. 801E39E0 TQE$L_TQFL 801E0200 801E39E4 TQE$L_TQBL 801DC660 801E39E8 TQE$W_SIZE 0030 801E39EA TQE$B_TYPE 0F 801E39EB TQE$B_RQTYPE 00 801E39EC TQE$L_FPC 0009002D TQE$L_PID 801E39F0 TQE$L_AST 7FFA867F TQE$L_FR3 801E39F4 TQE$L_ASTPRM 7FFE33DC TQE$L_FR4 801E39F8 TQE$Q_TIME C99D4B80 801E39FC 008DD627 801E3A00 TQE$Q_DELTA 00000000 801E3A04 00000001 801E3A08 TQE$B_RMOD 42 801E3A09 TQE$B_EFN 1F 801E3A0A 0000 801E3A0C TQE$L_RQPID 0009002D TQE$C_LENGTH SDA> e/time .+tqe$q_time 22-MAY-1985 16:23:29.08 Figure 4: FORMATting Timer Queue Elements ________________________________________________________________ VAX-33 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ SDA> show crash System crash information ------------------------ Time of system crash: 24-MAY-1985 12:55:07.53 Version of system: VAX/VMS VERSION V4.1 Reason for BUGCHECK exception: INVPTEFMT, Invalid page table entry format Process currently executing: NULL Current IPL: 8 (decimal) General registers: R0 = 801D7B84 R1 = 8002A220 R2 = 00000022 R3 = 0440FFD0 R4 = 00000402 R5 = 80146240 R6 = 800029D0 R7 = 00000000 R8 = 00000000 R9 = 00000000 R10 = 00000000 R11 = 00000000 AP = 00000000 FP = 00000000 SP = 801BA7C8 PC = 8000DBEC PSL = 04080001 P0BR = 80000000 PCBB = 0029BDA0 ACCS = 00008001 P0LR = 00000000 SCBB = 002F3A00 SBIFS = 00000000 P1BR = 7F802000 ASTLVL = 00000004 SBISC = 00000000 P1LR = 00200000 SISR = 00000000 SBIMT = 00000000 SBR = 002F6000 ICCS = 800000C1 SBIER = 00000000 SLR = 00002800 ICR = FFFFFCE7 SBITA = 00000000 TODR = 59EB8132 SBIS = 00000000 ISP = 801BA7C8 KSP = 80000C40 ESP = 00000000 SSP = 00000000 USP = 00000000 Figure 5: Sample Output from SHOW CRASH ________________________________________________________________ SHOW CRASH The output of this command is similar to the console bugcheck display. (See Figure 5.) It displays the date and time of the crash, the reason for the crash, and the contents of the general and privileged registers. VAX-34 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ SDA> show stack Current operating stack ----------------------- Current operating stack (INTERRUPT): 801BA7A8 00000000 801BA7AC 00000000 801BA7B0 00000000 801BA7B4 00000000 801BA7B8 00000000 801BA7BC 801BA7C0 801BA7C0 8000DBEC IOC$LOADUBAMAPN 801BA7C4 04080001 SP => 801BA7C8 8000DBB9 IOC$LOADUBAMAP+054 801BA7CC 80150B30 801BA7D0 8002AC00 801BA7D4 800C346A ZYDRIVER+B4A 801BA7D8 8000A0C0 EXE$FORKDSPTH+024 801BA7DC 00000000 801BA7E0 00000000 801BA7E4 00000000 801BA7E8 00000000 801BA7EC 00000000 801BA7F0 00000000 801BA7F4 00000000 801BA7F8 80008B1F EXE$NULLPROC 801BA7FC 00000000 Figure 6: Sample SHOW STACK Output ________________________________________________________________ SHOW STACK command Figure 6 shows the output of the SHOW STACK command during an ANALYZE/CRASH operation. SDA looks at the PSL that was saved in the dump header to determine which stack was in use at the time of the crash; it then looks at the corresponding saved stack pointer to find the address of the stack. (You can also type SHOW STACK/KERNEL, SHOW STACK/EXEC, etc., to look at any stack you like.) Recall that stacks in the VAX "grow" from high addresses to low -- the lowest-addressed longwords in the stack represent the things that were most recently pushed onto it. SDA also shows you the eight longwords above the top of the stack; the significance of these will be explained later when we describe bugchecks. VAX-35 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Note the symbols and offsets that are displayed to the right of the stack contents; these are interpretations of the contents of the stack, not its addresses. For instance, reading across on the third line of the display: The fourth longword on the stack (counting from the stack pointer) was at address 801BA7D4; the contents of this longword are 800C346A, and this value is 0B4A greater than the value of the symbol ZYDRIVER. You can also give a starting and ending address, or a starting address and number of bytes, to SHOW STACK; you can thereby display any area of memory you like in stack format, whether it actually is a stack or not. The utility of this will be seen later. Interpreting the Stack After A Crash If you want to determine the reason for a crash, it is imperative that you be able to interpret the saved stack contents. In this section I will present a brief review of the VMS exception and bugcheck mechanisms which cause the stack to look the way it does. NOTE: This discussion makes frequent reference to the text and illustrations in the VAX/VMS documentation and in the IDSM. It is essential that you follow these pointers while reading this material, as it is not intended to be self-contained! Exceptions _____ In analyzing crashes you must remember that every system failure _________ involves, sooner or later, an exception -- in the VAX architecture sense of the word: A condition that is encountered during the execution of an instruction which prevents the instruction from completing. Page faults, attempts to divide by zero, and access violations are all examples of exceptions. Exceptions in the VAX are much like interrupts in that they cause control to be transferred to a routine designed to handle them by way of an entry in the System Control Block. As with an interrupt, when an exception occurs, the VAX pushes the PC and PSL onto the stack. (The saved PC will point to either the failing instruction or to the next instruction after it, _____ depending on whether the particular exception is a fault or a ____ trap, respectively.) VAX-36 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial The processor may, depending on the type of exception, push one or more additional longwords onto the stack that further describe the exception. For instance, for a page fault or access violation, the additional longwords contain the faulting virtual address and a reason mask. When an exception occurs in normal, user-mode code, VMS either handles the exception itself (by resolving a page fault, for instance) or converts the stack contents into signal and mechanism arrays which are then passed to user-written condition handlers, which may be able to "fix up" the problem. For a complete description of exceptions and how VMS handles ___ ____________ ________ them, refer to Chapter 9 of the VAX Architecture Handbook, Chapter 4 and Section 8.2 of the IDSM, and Chapter 10 of the ______ ________ _________ ______ Version 4 System Services Reference Manual (SSRM). Here I will give a brief review of how exceptions cause the system to crash and why the stack looks the way it does after a crash occurs. Bugchecks Ultimately, every crash involves an exception caused by the execution of a bugcheck "instruction". This "instruction" appears in the source code as a macro call of the form BUG_CHECK reason, severity Execution of this macro occurs as a result of a consistency check -- i.e., when VMS decides that it's encountered a "can't happen" or "shouldn't happen" condition. The reason code indicates the type of problem that has been detected, and the severity code tells how bad it is (fatal, error, warning). The macro generates a two-byte opcode of FEFF followed by a word containing the reason and severity codes. (The codes are, of course, defined by symbolic names which are associated with message text, so the reason can be displayed in text form on the console bugcheck output and by SDA.) The VAX processor doesn't know anything about opcode FEFF other than that it's not defined (and that the "instruction"'s length is four bytes), so when it encounters this "instruction" it signals an "opcode reserved to Digital" exception. As with every exception, the reserved opcode trap causes the current PC and PSL to be saved on the stack and control to be passed to an exception-specific routine located via the appropriate entry in the system control block. (Since it's a trap, not a fault, the saved PC reflects the address of the next instruction after the bugcheck.) The routine in VMS that handles opcode-reserved-to-Digital exceptions checks the VAX-37 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial offending opcode to see if it's a bugcheck "instruction"; if it is, control is passed to a routine called EXE$BUG_CHECK. EXE$BUG_CHECK checks the severity field in the bugcheck instruction and, if it's fatal, brings the system down. It is this routine that copies physical memory and register contents to the dump file (or paging file) and writes the bugcheck information to the console. The value of the current stack pointer register is modified so that it points to the last ______ longword that was pushed on the stack before the reserved opcode exception occurred. So when looking at the stack with SDA, you will see the PC/PSL pair representing the bugcheck exception just "above" the longword pointed to by the stack pointer. System crashes can be divided into three broad categories. There are no official names for these as far as I know; I'll refer to them as "inline" bugchecks, "illegal exception" bugchecks, and "hybrid" bugchecks (which combine some aspects of the other two). Knowing what kind of bugcheck you are looking at is essential if you are to efficiently analyze the crash. We'll look at "inline" bugchecks first. "Inline" Bugchecks An "inline" bugcheck is one for which the BUG_CHECK macro appears "in line" in the instruction stream rather than in an exception handler. (Bugchecks within exception handlers are described in the next two sections.) One example is the QUEUEMPTY bugcheck in the scheduler, a listing of which appears in Section 10.3 of the IDSM. When a crash of this sort occurs, the PC/PSL pair that's just "above" the top of the stack will point to the location immediately following the bugcheck instruction in the system routine where the problem was detected. Following this (at and below the top of the stack, as indicated by the SP value displayed by SDA) you will generally find the saved values of the PC and other registers from the code that led up to the routine that detected the problem. An Example: A Driver-Related Crash Figures 5 and 6 were taken from the SDA output for a crash of this type (which I have not, incidentally, found the reason for). The second longword above the top of the stack tells us VAX-38 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial that the bugcheck was generated at IOC$LOADUBAMAPN-4. The SDA command EX/INS IOC$LOADUBAMAPN-4 returns the following: IOC$PTETOPFN+010: BUG_CHECK #01D4 So we know to look in routine IOC$PTETOPFN to find out under what conditions it executes this instruction. The system map file tells us that this routine is in module LOADMREG, so we look in the fiche for LOADMREG.LIS under facility SYS. SDA also shows that the longword at the top of the stack is equal to IOC$LOADUBAMAP+54. When looking at stack displays, it is important to remember that every JSB instruction pushes the return PC onto the stack. Of course, not all longwords on the stack that happen to look like system space addresses will represent return PCs. But when SDA says that such a longword's value is close to the entry point of a system routine, that is a fairly good indication that the instruction just prior to that location (six bytes prior for JSBs with absolute addresses, variable for other forms) is a Jump- or Branch-to-Subroutine (JSB or BSBx), and the longword was pushed by the execution of that instruction. Reading down the stack, then, we see that IOC$PTETOPFN was called by the instruction just prior to IOC$LOADUBAMAP+54. The code for IOC$LOADUBAMAP (also in module LOADMREG) begins by pushing R4 and R3 on the stack (because it's going to modify them), so we ignore -- for now -- the next two longwords in the stack. (But remember that these contain saved values of R3 and R4, which may turn out to be important later.) IOC$LOADUBAMAP was apparently called from the instruction preceding ZYDRIVER+B4A. ZYDRIVER is a driver I wrote for a foreign device. This is a pretty clear indication that something is wrong with the driver, or at least that the crash was associated with something that the driver was doing. ZYDRIVER was in turn called (reading down one more longword) from the instruction preceding EXE$FORKDSPTH+024 -- a location within the fork dispatcher. Just what is going on inside ZYDRIVER? Recall that the SDA "automatic" symbol ZYDRIVER is the address of the driver prologue table, which is not directly useful for finding things in the source listing. In Figure 7 we use the SDA SHOW DEVICE command to display the unit control block for the device in question; this defines (among others) the symbol DDT to be equal to the address of ZYDRIVER's driver dispatch table. This is good because all of the address offsets displayed by the assembler in a typical driver listing are relative to the DDT -- VAX-39 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial the DDTAB macro which builds the DDT generates a new .PSECT, causing the assembler's location counter to be cleared. After doing the SHOW DEVICE we issue another SHOW STACK command, and we see that the saved PC from the driver's JSB is pointing to the instruction at offset 0ADA from the start of the Driver Dispatch Table (DDT). (The two longwords between this one and the one on the top of the stack are register values that were pushed by IOC$LOADUBAMAP.) Now we can go to the driver listing (Figure 8) and find that, sure enough, at offset 0AD4 (just prior to that shown on the stack; remember that JSBs and BSBs push the address to return to, not the address of their own opcodes), there's a LOADUBA macro. LOADUBA expands to JSB G^IOC$LOADUBAMAP VAX-40 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ SDA> show dev zya0 ZYA0 Unknown UCB address: 80146240 Device status: 00000110 online,bsy Characteristics: 0C450000 shr,avl,elg,idv,odv 00000000 Owner UIC [000000,000000] Operation count 117 PID 00000000 Error count 0 Class/Type 20/FF Reference count 1 ... Def. buf. size 0 BOFF 0010 DEVDEPEND 0000000E Byte count FF80 . . . SDA> show stack Current operating stack ----------------------- Current operating stack (INTERRUPT): 801BA7A8 00000000 801BA7AC 00000000 801BA7B0 00000000 801BA7B4 00000000 801BA7B8 00000000 801BA7BC 801BA7C0 801BA7C0 8000DBEC IOC$LOADUBAMAPN 801BA7C4 04080001 SP => 801BA7C8 8000DBB9 IOC$LOADUBAMAP+054 801BA7CC 80150B30 IRP 801BA7D0 8002AC00 801BA7D4 800C346A DDT+ADA 801BA7D8 8000A0C0 EXE$FORKDSPTH+024 801BA7DC 00000000 801BA7E0 00000000 801BA7E4 00000000 801BA7E8 00000000 801BA7EC 00000000 801BA7F0 00000000 801BA7F4 00000000 801BA7F8 80008B1F EXE$NULLPROC 801BA7FC 00000000 Figure 7: Using SHOW DEVICE to Define Device-Related Symbols ________________________________________________________________ VAX-41 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ 0AD4 LOADUBA 0ADA MOVZWL UCB$W_BOFF(R5),R1 Figure 8: Excerpt from ZYDRIVER.LIS ________________________________________________________________ Now, again, we've found a rather superficial explanation of the ___ problem. The real question is, why did IOC$PTETOPFN report an error? A DMA driver is supposed to check all the pages involved in the transfer for accessibility and lock them into physical memory, all in the context of the process that requested the transfer -- long before we get to the LOADUBA macro. If there was any problem with any of that, it should have reported the error back to the user and never tried to start the transfer. There is a clue in the SHOW DEVICE output in Figure 7: The transfer size, indicated by the "Byte count" field, is huge. Either the driver or the buffer-check-and-lock routines which the driver calls are not behaving properly with this value for the buffer size. The immediate problem was solved by having the user correct the $QIO call to specify the right transfer size (128 bytes), but I have not yet had the time to find out why the error wasn't detected sooner, in a more graceful manner. For this discussion, though, the moral is: If you see the name of a device driver in the SHOW STACK output, the crash was almost certainly the result of something that driver did (or failed to do). "Illegal Exception" Bugchecks The second type of bugcheck is associated with an exception (such as an access violation or a reserved operand trap) that occurs in an illegal context (when executing on the interrupt stack, or on the kernel stack at IPL 3 or above). Such exceptions should never occur, as exceptions represent errors, and code executing in system context is expected to be error- free. VMS will crash with an "illegal system service exception" bugcheck when this occurs. The difference between this type of bugcheck and an "inline" bugcheck is that the code that checks for the inconsistency is inside a system-wide exception-handling routine rather than in the routine that caused the problem. This difference causes the stack to look quite different than it does in the case of "inline" bugchecks. The system-wide routine is called EXE$EXCEPTION (in module EXCEPTION.MAR, in facility SYS); it is VAX-42 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial invoked for all exceptions that might reasonably be fielded by user-written condition handlers. This routine executes a bugcheck instruction if the saved PSL shows that the machine was executing either on the interrupt stack or at IPL 3 or above when the exception occurred. (The bugcheck macro appears at location EXE$EXCEPTION+43 in Version 4.) The stack looks different than for "inline" bugchecks because after this bugcheck instruction is "executed", there are two exceptions outstanding: The original one that caused us to get into the exception-handling code, and the reserved opcode exception. Just as with the "inline" bugchecks, the reserved opcode routine will determine that the second exception was caused by a bugcheck instruction and will pass control to EXE$BUG_CHECK, and the system will be brought down. As in the case of the "inline" bugchecks, the PC/PSL pair pushed by the bugcheck instruction will be on the stack just above the top of the stack (as indicated by SDA). The saved PC will be reported by SDA as being equal to EXE$EXCEPTION+47 -- the location of the bugcheck instruction plus its size. At and below the top of the stack will be information describing the original exception (the one that caused EXE$EXCEPTION to execute in the first place). This information will be in the form of a signal array and a mechanism array, as described in Chapter 10 of the SSRM. The mechanism array will be at the top of the stack and always begins with a longword containing the value 4; the signal array will be beneath the mechanism array, separated from it by one longword containing either a 1 or a 2 (the signal/stop code; see Chapter 4 of the IDSM). The first longword of the signal array will have a value of 3 or more, depending on the type of exception; this indicates the number of following longwords. Table 10-1 in the SSRM describes all possible formats of the signal array. Figure 4-4 in the IDSM shows how the mechanism array, the signal/stop code, and the signal array are arranged on the stack. In this type of crash, the second longword and the last two longwords of the signal array are arguably the most important information on the stack. The second longword contains a condition value that identifies the type of exception -- for instance, a value of C (hex), which is the value of the symbol SS$_ACCVIO, denotes an access violation. The last two longwords of the signal array are the PC and PSL that were pushed when the ________ original exception occurred. Depending on the type of exception (trap or fault; Table 10-1 in the SSRM tells which are which) the PC will either be the address of the excepting instruction or that of the next instruction after it. As with "inline" bugchecks, there may be saved PCs and other registers that were pushed on the stack by the code leading up to instruction that generated the exception. VAX-43 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ SDA> show stack Current operating stack ----------------------- Current operating stack (KERNEL): 7FFE7D7C 7FFBFC08 7FFE7D80 7FFBFC08 7FFE7D84 7FFE0270 PIO$GW_IIOIMPA 7FFE7D88 7FFE9C6C 7FFE7D8C 7FFE7DE4 CTL$GL_KSTKBAS+5E4 7FFE7D90 7FFE7D94 CTL$GL_KSTKBAS+594 7FFE7D94 80004862 EXE$EXCEPTION+047 7FFE7D98 00080009 { SP=> 7FFE7D9C 00000004 mech. { 7FFE7DA0 7FFE7DE4 CTL$GL_KSTKBAS+5E4 array { 7FFE7DA4 FFFFFFFD { 7FFE7DA8 80002BA8 IOC$GL_MUTEX { 7FFE7DAC 7FFDD719 7FFE7DB0 00000001 { 7FFE7DB4 00000005 <- size of signal array { 7FFE7DB8 0000000C <- condition code signal { 7FFE7DBC 00000000 <- reason mask array { 7FFE7DC0 0000004C <- faulting virt addr { 7FFE7DC4 8000AEDE SCH$UNLOCK+052 <- PC { 7FFE7DC8 00480008 <- PSL 7FFE7DCC 80002BA8 IOC$GL_MUTEX 7FFE7DD0 800E9220 7FFE7DD4 00000002 7FFE7DD8 8001081C IOC$UNLOCK+00C 7FFE7DDC 00000001 7FFE7DE0 00400004 7FFE7DE4 00000000 7FFE7DE8 00000000 7FFE7DEC 7FFE9C6C 7FFE7DF0 7FFE9C3C 7FFE7DF4 8000FDCE EXE$CMODEXEC+176 7FFE7DF8 7FFEDEE6 SYS$DASSGN+006 7FFE7DFC 01400000 SDA> ex/cond h7db8 %SYSTEM-F-ACCVIO, access violation, reason mask=!XB, ... Figure 9: Analyzing An Illegal Exception Bugcheck ________________________________________________________________ VAX-44 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Example: Access Violation from System Code Figure 9 shows the SDA output for a crash that (providentially) occurred while I was preparing this talk for DECUS. The value of EXE$EXCEPTION+47 in the bugcheck PC/PSL pair (just above the top of the stack) identify this as an "illegal exception" bugcheck; I have identified the mechanism and signal arrays on the stack in the figure. The second longword (condition name field) in the signal array is a C (hex); the EX/COND command in SDA tells us (if we didn't know already) condition code means that an access violation occurred. Table 10-1 in the SSRM tells us that for access violations the third and fourth longwords of the signal array contain a "reason mask" and the virtual address to which access was attempted, respectively. In our signal array we see a reason mask of 0 (indicating that it was a protection code violation rather than a length violation, that it was the operand and not the page table entry mapping the operand that wasn't accessible, and that it was a read rather than a modify access) and a faulting virtual address of 4C. This latter value indicates definite problems, as the first page of virtual address space (addresses 0 through 1FF) is always unused by default. (This convention _____ was adopted so that errors of this sort would cause access violations rather than strange results.) Finally, the signal array contains the address of the instruction that incurred the access violation. SDA tells us that this address is equal to SCH$UNLOCK+52. We know this is the address of the bad instruction and not the instruction after it because Table 10-1 of the SSRM says that access violations are faults, not traps. (Again: For faults, the saved PC is the address of the faulting instruction; for traps, it's the address ____ of the next instruction.) ________________________________________________________________ Symbol Value Defined By Referenced By ... ------ ----- ---------- ----------------- SCH$SCHED 8000A6CA-R SCHED INIT ... SCH$SWAPACBS 8000A03A-R ASTDEL SYSENQDEQ SCH$SWPWAKE 8000A632-R RSE ALLOCPFN ... SCH$UNLOCK 8000AE8C-R MUTEX EXSUBROUT ... SCH$UNWAIT 8000A3CA-R RSE SCH$V_MPW 00000002 SDAT ALLOCPFN ... Figure 10: Excerpt from SYS.MAP Showing Location of SCH$UNLOCK ________________________________________________________________ CMPL (SP),PCB$L_EFWM(R4) ; is process waiting for this mutex? VAX-45 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Figure 11: Instruction at SCH$UNLOCK+52 ________________________________________________________________ The next likely step is to look at the system map file to see where to find the source code for SCH$UNLOCK. Figure 10 is an excerpt from the symbols-by-name section of the map; it tells us that the symbol SCH$UNLOCK is defined by the module called MUTEX. We go to the source fiche, look up module MUTEX.MAR in facility SYS, and use the offset of 52 (hex) from the label SCH$UNLOCK to find the offending instruction (shown in Figure 11). Now, what's wrong with this instruction? Which operand couldn't be accessed? In instructions that read one operand and write another, such as MOVL A, B the reason mask will tell you -- a read access indicates the first operand, a modify access the second. In the CMPL instruction, though, both operands are read-access. Probably it wasn't the first operand as the stack pointer seems to be ok (and SDA reports that the last longword pushed before the access violation occurred was indeed the address of a mutex, which is reasonable). So it was probably the second operand. The symbol PCB$L_EFWM can't be wrong; about the only way an operand like this can give trouble is if the register doesn't point to the right data structure (in this case, a PCB). We ask SDA to show us the value of R4: SDA> ex r4 R4: 00000000 "...." and we've found the second layer of the problem. The faulting virtual address of 4C is equal to the value of the symbol PCB$L_EFWM which is used as the displacement from R4 -- and R4 is zero. ___ Now, why was R4 set to 0 when it should have (according to the code) been pointing to a process control block (PCB)? The fiche says that R4 was loaded by the instruction MOVL (R3),R4 and that R3 in turn got its value from MOVAL W^SCH$GQ_MWAIT,R3 which together have the same effect on R4 as: MOVL W^SCH$GQ_MWAIT,R4 VAX-46 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial ________________________________________________________________ +-----------------+ | forward link | ::SCH$GQ_state +-----------------+ | backward link | +--------+--------+ | state | n PCBs | +--------+--------+ Figure 12: Wait State Queue Header ________________________________________________________________ SDA> show stack sch$gq_mwait;c 80002180 00000000 80002184 80002180 SCH$GQ_MWAIT 80002188 00020000 Figure 13: MWAIT Queue Header in Crashed System ________________________________________________________________ MWAIT is a process wait state; to understand what's going on here we need to know a little bit about scheduler wait states in general. For each wait state there is a structure of the format shown in Figure 12. (For more details, see Chapter 10 of the IDSM.) The address of the structure is given by a symbol of the form SCH$GQ_state (the naming convention for "state" here is not entirely consistent), and the first two longwords of the structure are used as a queue header. When a process enters a wait state its process control block (PCB) is linked to the end of this queue. If there are any processes in the queue, therefore, these longwords will both point to PCBs. If the queue is empty, both longwords will point to the first longword of the queue header. The code we are looking at in SCH$UNWAIT is trying to scan the MWAIT queue to find all the PCBs whose event flag wait mask fields match the address of the mutex that is being released. When we use SDA to look at the queue header in the crashed system, (see Figure 13), the problem is apparent: The forward link longword of the queue header (at address 80002180) is zero! (Note that we used the SHOW STACK command rather than a simple EXAMINE so that SDA would show us the symbolic names of the values in the headers.) This could be considered the third layer of the problem: Some piece of code, somewhere, wrote a zero on the MWAIT queue header. This seems very strange because queue headers are only supposed to be written with INSQUE and _____ REMQUE instructions, which should never put zeroes in them. Getting to the fourth layer will involve figuring out which piece of code it was. We could make a start by asking SDA which process was current at the time of the crash and what image it was running. (This information is included in the console VAX-47 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial bugcheck output; it can also be obtained from SDA's SHOW SUMMARY command, to be described.) If it's something uninformative like SHOW.EXE (as it was in this case), we can look at the associated terminal's typeahead buffer to find the entire command that initiated the image. (The address of the typeahead buffer is in the field called UCB$L_TT_TYPAHD in the terminal's UCB.) It is possible, of course, that the offending image was long gone by the time the system had occasion to call SCH$UNWAIT, in which case we will likely be unable to find out what happened. (Postscript: It turns out that this was a known bug in Version 4.1 of VMS; The SHOW DEVICE command would sometimes clobber the MWAIT queue header. The code in question should not have been referencing the header; it just happened that an incorrectly restored register happened to point at it.) "Hybrid" Bugchecks As I mentioned earlier, there is some overlap between the "inline" and "illegal exception" bugchecks. These "hybrid" bugchecks involve consistency checks that are made by exception- specific code, rather than by the system-wide routine, EXE$EXCEPTION. Some exceptions, such as page faults, are handled by routines that do not pass control to EXE$EXCEPTION. The exception- specific routines for these exceptions -- the page fault handler, for example -- include the code that determines whether or not the exception is allowable under the current circumstances. (For instance, page faults are not allowed at IPL 3 or above.) Again, the problem is signalled via a bugcheck instruction. These differ from "illegal exception" bugchecks in several important ways. First, the bugcheck reason code is specific to the original exception, so the console bugcheck output can say something like "Page fault above IPL 2" rather than just "Illegal system service exception". Second, the system doesn't expect user-written condition handlers to deal with these types of exceptions, so it doesn't bother converting the exception information on the stack into signal and mechanism arrays. Underneath the PC/PSL pair for the bugcheck exception -- that is, at and below the top of the stack -- you will find whatever registers were saved by the exception-specific routine before it noticed that it was running in system context. These will be followed by whatever the hardware pushed on the stack when the original exception occurred -- including, of course, the PC and PSL at the time of VAX-48 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial the exception. ________________________________________________________________ +-----------------+ | bugcheck PC + 4 | (EXE$POWERFAIL+B88) +-----------------+ | bugcheck PSL | +-----------------+ SP=> | R4 | <= top of stack as +-----------------+ reported by SDA | R5 | +-----------------+ | reason mask | +-----------------+ | virtual address | +-----------------+ | faulting PC | +-----------------+ | faulting PSL | +-----------------+ | | <= top of stack before +-----------------+ illegal page fault | | Figure 14: Stack Format for Page Fault Above IPL 2 ________________________________________________________________ Third, the location of the bugcheck instruction (four less than the value of the second longword above the top of the stack) will reflect a location within an exception-handling routine other than EXE$EXCEPTION. If you have trouble interpreting the stack for this type of crash, find the indicated routine in the VMS source; the comments in the routine header will give a good description of the contents of the stack when the routine is entered. The code will tell you what else the routine pushes before it induces the bugcheck; this will be of aid in interpreting the saved stack. Example: Page Fault at IPL 2 or Above Figure 14 shows the format of the stack for one of the more common bugchecks of this type, "page fault above IPL 2". This information was derived from the source code for the page fault handler (see PAGEFAULT.LIS in facility SYS in the source fiche). Just above the top of the stack is the PC/PSL pair reflecting the bugcheck instruction in the pager, PAGEFAULT.MAR. (SDA will report the PC as being equal to EXE$POWERFAIL+B88 because the pager follows the powerfailure code in memory, and the bugcheck VAX-49 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial instruction is the first thing in the pager -- it's branched to from a later point.) From there, the stack contains, in order: The contents of R4 and R5 just before the page fault occurred (the pager saves them because it's going to modify them); a reason mask describing the type of page fault (see Table 10-1 in the SSRM); the virtual address to which access was being attempted; and the PC and PSL at the time of the page fault. Since page faults are (as their name implies) faults rather than traps, this PC value is the address of the faulting instruction. This makes it fairly easy to find the faulting instruction and figure out which module it's in. Finding out why the instruction caused a page fault when it shouldn't have will of course be more difficult. Example: Machine Check Another type of "hybrid" bugcheck that occurs frequently during driver debugging is the machine check. Unfortunately, the stack formats for machine checks are different for the different types of VAX CPUs. Chapter 4 of the IDSM has some information about machine checks; for a complete description, covering all VAX processors, see the comments at the beginning of EXCEPTION.LIS in facility SYS in the source fiche. The usual cause of a machine check (barring bugs in VMS) is a device driver that attempts illegal references to I/O space (longword references to Unibus device registers, for instance). As always, look for a PC/PSL pair on the stack; this will point to the instruction that caused the machine check. Then follow the chain of old PCs and other values on the stack to determine why the offending instruction caused the problem. OTHER COMMANDS Looking at Processes Table 4 shows the SDA commands that let you look at processes in the running or crashed system. You can specify the process to look at either via its name (which, unlike the process name argument to system services, does not have to specify a process within your UIC group) or its "index". You can provide the internal PID, the external PID, or just the low-order word of VAX-50 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial the internal PID for the "index". If you don't specify a process on your first SHOW PROCESS command, SDA selects the current process in the system. Whichever process you look at then becomes the default process for subsequent SHOW PROCESS commands, until you explicitly select another (either via SHOW PROCESS or SET PROCESS). As you can see from the qualifiers, there is a great deal of information that can be obtained from this command. The /CHANNEL qualifer will tell you what devices a process has assigned channels to and, for file-structured devices, which files the process has open. The /PAGE_TABLES qualifier lets you look at the page table entries for a range of virtual addresses (or for the entire P1 and P1 page tables if you don't specify a range); put your terminal in 132-column mode for this one. If you're having trouble with the lock manager, SHOW PROCESS/LOCKS may provide some clues. There is a /RMS qualifier for looking at process-specific RMS data structures, and SET and SHOW RMS commands for selecting and listing which structures the /RMS qualifer will display. And so forth. VAX-51 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Table 4: SDA Commands for Examining Processes ________________________________________________________________ Command Qualifiers Function ________________________________________________________________ SHOW PROCESS [name] /INDEX=nn select process for display (nn = EPID, PID, or low-order word of PID) /SYSTEM selects "system process" /PCB software PCB /PHD process header /PROCESS_SECTION_TABLE /PAGE_TABLES [range] [/P0] [/P1] /WORKING_SET working set list /RMS RMS data structures /CHANNEL device & file information /LOCKS resource locks /REGISTERS (from PHD) SET PROCESS [name] Sets default for next SHOW PROCESS /INDEX=nn /SYSTEM SET RMS Set and show options for SHOW RMS SHOW PROCESS/RMS SHOW SUMMARY Like DCL SHOW SYSTEM /IMAGE ________________________________________________________________ The SHOW SUMMARY command produces a display similar to that of DCL's SHOW SYSTEM. If you add the /IMAGE qualifier, it will display the full name of the image file (if any) that each process is running. Unbeknownst to many people, there is a dummy "system process" hiding in VMS. It has a PCB and a process header, and many of the fields and areas therein are used for their usual purposes, but for the system at large. For instance, the working set list of the "system process" is the system working set list, its "process section table" is in fact the system-wide global section table, and the region that would be the P0 page table in an ordinary process is used for the system (S0) and global page tables. And at least one bit of performance information is kept here: System page faults are "charged" to this "process". (In other words, MONITOR looks at the PHD$L_PAGEFLTS field in the "system process" PHD to determine the system page fault rate.) You can select this "system process" for display in SDA with the /SYSTEM qualifier. VAX-52 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial (No, the people who have been telling you that VMS itself is not a process haven't been lying. The PCB for the "system process" is never in any of the scheduler's queues, and it is pointed to _________ by the longword following the last active entry in the PCB vector, so the "system process" is never scheduled to run and never appears in any of the normal system displays. The "system process" is really just a convenient artifice that lets the system working set list, page table entries, and so forth be handled by almost the same code that deals with those structures in real processes. Section 14.3 of the IDSM describes the use of the "system process" in more detail.) Memory Management Data Table 5 shows the SDA commands that allow you to look at system- wide memory management structures. Although you can look at the system and global page tables by looking at the "system process", the SHOW PAGE_TABLE command will likely be more useful. There is also a command for examining the Page Frame Number (PFN) data base, either for all of pageable memory or for a range of PFNs. Your terminal should be set to 132-column mode for either of these. Table 5: SDA Commands for Displaying Memory Management Data ________________________________________________________________ Command Qualifiers Function ________________________________________________________________ SHOW PAGE_TABLE [range] shows PTEs /GLOBAL in global page table /SYSTEM in system page table /ALL (default) in both SHOW PFN_DATA [pfn] shows PFN data base for physical pages /SYSTEM selects entire PFN data base /FREE selects free page list only /MODIFIED selects modified page list only /BAD selects bad page list only /ALL selects all of the above ________________________________________________________________ VAX-53 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial Table 6: Miscellaneous SHOW Commands ________________________________________________________________ Command Qualifier Function ________________________________________________________________ SHOW DEVICE devnam Display I/O data base /ADDRESS=addr Select device via UCB address SHOW POOL Displays nonpaged and/or paged pool SHOW RESOURCE Displays resource data base SHOW LOCK Displays lock data base VALIDATE QUEUE Checks queue for integrity ________________________________________________________________ Other SHOWs Table 6 lists some of the other specialized SHOW commands. We have already met SHOW DEVICE, but it's worth mentioning that it can display not only UCBs but also all of the other structures in the I/O data base. If you give it a complete device name such as "ZYA0:", it will display only the UCB for that unit, but if you give it just "ZYA", it will show you all of the structures for that controller followed by all of the UCBs for units under the controller. Specifying just a device type such as "ZY" will produce a display of the controller and unit structures for all units under all controllers of that type, and omitting the device name completely gives you all of that for every device on the system. You can also specify a particular unit via its UCB address with the /ADDRESS qualifier. There are too many qualifiers to SHOW/POOL to list in the table; ___ _________ ______ consult the SDA Reference Manual, page SDA-71. You can display the entire pool, or just the LRPs, IRPs, or SRPs, or just the paged pool, or you can select what you want to look at by providing a range of addresses. You can look at entire blocks or just at the headers, and you can selectively look only at blocks of a particular type. SHOW LOCK and SHOW RESOURCE will be useful to those who are using the VMS Lock Manager. If you are having problems with doubly-linked lists (queues), VALIDATE QUEUE may be helpful. It scans through such a queue to check that all the pointers are mutually consistent; if they are, it reports how many entries are in the queue. If they VAX-54 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial aren't, it reports a problem, but it can't be too specific about the problem because it really has no way of determining which pointer is the bad one. Still, using VALIDATE QUEUE on the header of a suspect queue is usually more efficient than following the queue "by hand" to see whether or not it's broken. Table 7: Other SDA Commands ________________________________________________________________ Command Qualifiers Function ________________________________________________________________ @file Read commands from file.COM DEFINE /KEY Create user-defined keys KP0 or REPEAT Repeat last command EVALUATE expr Calculator SHOW SYMBOL symb Show value of a symbol /ALL Show all symbols beginning with symb SEARCH range=expression Search memory for longword-aligned value HELP On-line help SET LOG Copy commands and output to file (SET NOLOG to cancel) SET OUTPUT Redirect output to file (SET OUTPUT SYS$OUTPUT to cancel) ________________________________________________________________ Bells and Whistles SDA has a number of features to make life easier for the user. Just like everywhere else in Version 4, one-line command editing is in effect. So, for instance, when we were scanning through queues of CEBs and TQEs in the earlier examples, we didn't need to keep typing "FORMAT @." to get to the next block; after having typed it once, we could just hit the up-arrow key followed by a RETURN. VAX-55 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial SDA looks for the logical name SDA$INIT when it is started; if the name is found, it reads commands from the file the name points to before prompting the user for a command. This is, of course, very convenient when you find yourself repeatedly using the same commands (such as READ SYS$SYSTEM:SYSDEF) every time you invoke SDA. Table 7 lists the commands in the "make life easier" category. First on the list is the "@" command which, as most experienced VMS users will guess, causes SDA to execute a file of commands. Just as in DCL and the new Symbolic Debugger, SDA supports user- defined keys with multiple keypad states. The description of ___ _________ ______ this feature in the SDA Reference Manual is somewhat sketchy, but the feature does work. Unlike the Symbolic Debugger, SDA does not appear to predefine any keys other than KP0 (which recalls the last command). REPEAT does the same thing as KP0, but since it's made up of ordinary characters it can be used in a command procedure (for instance, to step through a chain of data structures). The EVALUATE command lets you dispense with your programmer's calculator (at least while you're in SDA). It displays results in both decimal and hex. The /CONDITION qualifer causes SDA to display the system error message text, if any, associated with the calculated result. If you just want to know the value of a symbol, you can use the EVALUATE command on it. SHOW SYMBOL also lets you look at the value of a symbol and, if the symbol represents a valid address, at the contents of the addressed location. You can also type a partial symbol name and the /ALL qualifier, and SDA will report on all of the symbols that begin with the characters you provided. (This is another command that needs a wide display.) The SEARCH command is less useful than it could be, as it will only match on longword-sized, longword-aligned values. Naturally, SDA has extensive on-line HELP. Finally, there are two commands that are useful for documenting ____ your SDA session. The SET LOG command will send a copy of both your commands and SDA's responses (excepting error messages) to the designated file or device; SET NOLOG turns off the copying. _________ SET OUTPUT redirects SDA's output to the designated file, which is formatted for a printer. To point the output back at the terminal (and close the output file), use SET OUTPUT SYS$OUTPUT. VAX-56 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX/VMS System Dump Analyzer Tutorial CONCLUSION We have covered a lot of information, and very little of it will "sink in" unless you put it into practice. If you anticipate _______ ever needing to use SDA, I strongly encourage you to get used to using it ahead of time. As far as I know, it is impossible to crash the system with SDA, so feel free to experiment. (This did not used to be the case. In an earlier version of VMS SDA on the live system would let you look at the Unibus I/O page using longword-sized references, causing an immediate crash!) Of course, as with most other tools, you will find more and more uses for SDA as you become more and more familiar with it. I hope I've made it clear that SDA is useful for troubleshooting application-related problems as well as system crashes; having a knowledgeable SDA user at your site will make all of your programmers more effective and will increase your system's productivity, even if you never install a line of user-written kernel-mode code. SDA is one of the best "windows" available into the black box that is VMS. You owe it to yourself and to the other people you work with to learn how to use that window effectively. REFERENCES _______ _________ ___ Kenah, Lawrence J., and Bate, Simon F., VAX/VMS Internals and ____ __________ Data Structures, Digital Press, Maynard, MA 1984 (DEC order number EY-00014-DP). _______ ______ ____ ________ _________ ______ VAX/VMS System Dump Analyzer Reference Manual, Digital Equipment Corporation, Maynard, MA 1984 (DEC order number AA-Z429A-TE; _______ ____ _________ _____________ part of QLZZ4-GZ-V4.0, VAX/VMS V4.0 Utilities Documentation _____ Kit). ___ ____________ ________ VAX Architecture Handbook, Digital Equipment Corporation, Maynard, MA 1981. _______ ______ ________ _________ ______ VAX/VMS System Services Reference Manual, Digital Equipment Corporation, Maynard, MA 1984 (DEC order number AA-D018C-TE). VAX-57 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX System SIG Committee List VAX System SIG Committee List As of October 28, 1985 Osman K. Ahmad - TOPS-VAX Association of American Railroads Technical Center, Research and Test Department 3140 South Federal Street Chicago, IL 60616 Joe Angelico - Assistant Symposium Coordinator US Coast Guard CCGD8(DT) Hale Boggs Federal Building 500 Camp Street, New Orleans, LA 70130 Elizabeth Bailey - Volunteer Coordinator 222 CEB Tennessee Valley Authority Muscle Shoals, AL 35660 June Baker - Planning Computer Sciences Corporation 6565 Arlington Boulevard Falls Church, VA 22046 Joe L. Bingham - Librarian Mantech International 2320 Mill Road Alexandria, VA 22314 Bob Boyd - Commercial GE Microelectronics Center MS 2P-04 Post Office Box 13409 Research Triangle Park, NC 27709 C. Douglas Brown - Security Sandia Labs Division 2644 P.O. Box 5800 Albuquerque, NM 87185 Jack Cundiff - Assistant Symposium Coordinator Horry-Georgetown Post Office Box 1966 Conway, SC 29526 Tom Danforth - Handout Editor Woods Hole Oceanographic Institute Woods Hole, MA 02543 VAX-58 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX System SIG Committee List Jim Downward - Migration and Host Development, VAXintosh KMS Fusion Incorporated 3941 Research Park Drive Ann Arbor MI 48106 Jane Furze - Campground 3830 West Cochise Phoenix, AZ 85064 Dennis Frayne - Real Time/Process Control McDonnell Douglas 5301 Bolsa Avenue Huntington Beach, CA 92646 Carl E. Friedberg - Internals In House Systems 165 William Street New York, NY 10038 Don Golden - Publications Coordinator c/o Shell Development Company, D-2132 Westhollow Research Center Post Office Box 13480 Houston, TX 77001 Gary Grebus - System Improvement Request Battelle Columbis Labs Room 11-6011 505 King Avenue Columbus, OH 43201-2693 B. Hancock - Network Dimension Data Systems, Incorporated 2510 Limestone Lane Garland, TX 75040 Jeffrey S. Jalbert - Historian J C C Post Office Box 381 Granville, OH 43023 614-587-0157 Ken Johnson - VAXcluster Working Group Meridian Technology Corporation Post Office Box 2006 St. Louis, MO 63011 Ray Kaplan - VAXeln Pivotal Incorporated 6892 East Dorado Court Ticson, AZ 85715 VAX-59 PAGESWAPPER - January 1986 - Volume 7 Number 6 VAX System SIG Committee List Lawrence J. Kilgallen - Newsletter Editor Box 81, MIT Station Cambridge, MA 02139-0901 Margaret Knox - Chair Computation Center University of Texas Austin, Texas 78712 Ross W. Miller - Vice Chair and Working Group Coordinator Online Data Processing, Inc. N 637 Hamilton Spokane, WA 99202 Eugene Pal - Multiprocessor US Army CAORA (ATOR-CAT-C) Fort Leavenworth, KA Thomas Provost - Hardware MIT/LNS Bates Linac Facility Post Office Box 846 Middleton, MA 01949 Susan Rehse - System Management Lockheed Missiles 3251 Hanover Street Palo Alto, CA 94301-1187 Bob Robbins - Advisor Array Computer Consultants 5364 Woodvale Drive Sarasota, FL 33582 Larry Robertson - Real Time/Process Control Bear Computer Systems Inc. 5651 Case Avenue North Hollywood, CA David Schmidt - LUG Coordinator Management Sciences Associates 5100 Centre Avenue Pittsburgh, PA 15232 Al Siegel - Advisor Battelle Memorial Institute 505 King Avenue Columbus, OH 43201-2693 D. Slater - Artificial Intelligence Institute for Defense Analysis 1801 North Beavregard Street Alexandria, VA 22314 VAX-60 PAGESWAPPER - January 1986 - Volume 7 Number 6 INPUT/OUTPUT INPUT/OUTPUT A SIG Information Interchange A form for INPUT/OUTPUT submissions is available at the back of the issue. INPUT/OUTPUT 477 Caption: Using incoming modems as outgoing modems Message: How does one dial OUT through a VAX using what is normally an incoming modem port from another terminal hardwired to the VAX? We have tried Kermit and redefining process logical. We would like to avoid writing macro software. We have DF03/DF112 modems and VMS V4.2. Contact: Karl Minninger Clark County Health District 625 Shadow Lane Box 4426 Las Vegas, NV 89127 Telephone (702) 383-1219 Date: November 5, 1985 INPUT/OUTPUT 478 Caption: Data Administration Tools Message: Recently appointed Data Administrator looking for software tools to assist in managing data as a corporate resource. Our shop has a 5 node VAX cluster and 3 remote nodes, all with Datatrieve, CDD, and Rdb. Wishlist: User accessible catalog of all data element definitions; logical design diagramming; normalization of data elements; tools to audit data for adherence to standards; etc. Contact: Gary S. Fix Aerojet Strategic Propulsion Company Post Office Box 15699C Building T1960-1, Department 2522 Sacramento, CA 95813 VAX-61 PAGESWAPPER - January 1986 - Volume 7 Number 6 INPUT/OUTPUT Telephone (916) 355-5061 Date: November 14, 1985 INPUT/OUTPUT 479 Caption: Geographically based data Message: The following will be used in a classroom setting. I am interested in combining census data, election data, and other variables to analyze the election results in a single city. The data would be aggregated to the precinct level. I am searching for software which can be used to collect this information into a database and print it in the form of both maps and statistical analysis. The software would be used by students with little computer background to analyze selected local elections. I would also like to use the same approach to analyzing the delivery of public services. What is the most appropriate software for the task which will run on a VAX 785? Contact: Michael P. Kirby Associate Professor Rhodes College 2000 North Parkway Memphis, TN 38112 Telephone (901) 726-3842 Date: November 17, 1985 VAX-62 PAGESWAPPER - January 1986 - Volume 7 Number 6 INPUT/OUTPUT Submission Form INPUT/OUTPUT Submission Form A SIG Information Interchange Please reprint in the next issue of the Pageswapper If this is a reply to a previous I/O, which number? ________ Caption: ______________________________________________________ Message: ______________________________________________________ ________________________________________________________________ ________________________________________________________________ ________________________________________________________________ ________________________________________________________________ ________________________________________________________________ ________________________________________________________________ Contact: Name _______________________________________________________ Address ____________________________________________________ ____________________________________________________________ ____________________________________________________________ ____________________________________________________________ Telephone ____________________________ Signature _____________________________ Date ________________ Mail this form to: Larry Kilgallen, PAGESWAPPER Editor Box 81, MIT Station, Cambridge, MA 02139-0901, USA PAGESWAPPER - January 1986 - Volume 7 Number 6 INPUT/OUTPUT Submission Form Tear out to submit an I/O item Larry Kilgallen, PAGESWAPPER Editor Box 81, MIT Station Cambridge, MA 02139-0901 USA PAGESWAPPER - January 1986 - Volume 7 Number 6 System Improvement Request Submission Form System Improvement Request Submission Form Page 1 of _____ ________________________________________________________________ Submittor: Firm: Address: Phone: ________________________________________________________________ How to write an SIR: Describe the capability you would like to see available on VAX systems. Be as specific as possible. Please don't assume we know how it's done on the XYZ system. Justify why the capability would be useful and give an example of its use. If you wish, suggest a possible implementation of your request. ________________________________________________________________ Abstract (Please limit to four lines): ________________________________________________________________ Description and examples (use additional pages if required) PAGESWAPPER - January 1986 - Volume 7 Number 6 System Improvement Request Submission Form Tear out to submit an SIR Gary L. Grebus Battelle Columbus Laboratories Room 11-6011 505 King Avenue Columbus, Ohio 43201-2693 USA