HER An unhandled VMS exception simply writes the condition, signal arguments, stack contents, and register dump to the standard output. This is seldom useful in production software, because: The user doesn't even notice the exception. Even if they do, they aren't aware of the implications. Even if they are, they don't know that they should copy the dump. Even if they do, they aren't quick enough. Even if they are, they don't remember to inform you. Even if they do . . . IT'S STILL NOT ENOUGH TO HELP YOU FIND THE BUG. So i wrote a relatively simple condition handler to solve all of the problems listed above. It traps any status desired, captures the data described below (some via $getjpi() and $getsyi() calls, some via a user-written system service named HOLMES), and logs it to a file named HARDWARE_EXCEPTION.RPT (in the login directory, if such is defined). The data written out includes: process information ========================================================================== the original condition which caused the exception names (user, process, account, terminal) times (login, cpu) image filespec default directory privileges (current, default, authorized, image) quotas (limit, count) working set (default, quota, extent, peak) system information ========================================================================== names (node, architecture, hardware, hardware model) times (boot, current) VMS version free global pages free global sections call stack ========================================================================== PC of each frame registers for each frame arguments in each frame [1] open file information [2] ========================================================================== channel number access (section, read, write, exclusive) resultant filespec or full device name activated image information [2] ========================================================================== channel number imagename (maybe filename, maybe logical name) ident (from LINK command) creation date (from LINK command) current "installed" state (a.k.a. "known file" state) if applicable how linked (/debug, /traceback, /sysexe or sys.stb) global section major & minor idents virtual address range current patches if any (ECO numbers) [3] active timers information [2] ========================================================================== type (normal, system subroutine, wake entry) (repeat) (cpu-based) event flag number AST routine address request identification (also the AST parameter) expiration date/time active locks information [2] ========================================================================== lock id parent id (or zero) resource name (part printable, part binary . . . ugh) octal group number from UIC (or the word "system") access mode (user, super, exec, kernel) currently granted mode (nl, cr, pr, cw, pw, ex) currently requested mode (nl, cr, pr, cw, pw, ex) request state (granted, converting, waiting) value block contents (four unsigned longwords) [1] not very reliable on ALPHA machines [2] written to the file only if the HOLMES package (q.v.) is installed [3] not applicable on ALPHA machines, since there is no PATCH.EXE for them Examples for each architecture are provided in the SAMPLE_AXP_EXCEPTION.RPT and SAMPLE_VAX_EXCEPTION.RPT files. It would be nice to take advantage of any images linked /TRACEBACK to mimic that output --- including module names, function names, and line numbers --- but I just don't have time to decipher the TBK files in the [Vxx.TRACE.LIS] source listings. Sorry, I would very much like to do this, but not yet. Of course this makes life easier for the Technical Support employees; all of the information about which images, versions, and patches are all nicely written out for them to a single file automatically so that all they have to do is download that one .RPT back to me. I, too, find it incredibly useful when debugging an access violation or some similar exception during development, because I now have each image's virtual address range written down for me; a hex subtraction against the offending PC and a quick offset against the addresses listed in the .MAP file, and I've narrowed down the guilty instruction exactly, even in a dynamically-loaded shareable image. This directory contains the source code and option files for both images and a sample program demonstrating a call. There are two implementation methods available: a condition handler that you can establish directly named HER_HandleException(), and a function your handler can call named HER_ReportException(). ok dpm --- David P. Murphy mailto:murphy@connor.datametrics.com (work) systems programmer mailto:dpm@access.digex.net (personal) http://www.access.digex.net/~dpm COGITO ERGO DISCLAIMUM ftp://ftp.access.digex.net/pub/access/dpm HOLMES Many VMS systems programmers have found the "SHOW PROCESS /CHANNEL" and "SHOW PROCESS /IMAGES" commands within the System Analyzer very useful at one time or another. Unfortunately, they can only be issued *by* a privileged process *for* an active process --- which is seldom practical. My company has many clients running many different programs, and when a problem occurs there is simply no time to dial up or even prompt a local supervisor through the steps; I wanted my handlers to capture this information for me. So I've written some C and MACRO32 code (the latter with assistance from Brian J. Schenkenberger, a.k.a. "vaxman") to create two shareable images which write the desired output to a disk file at any time from within my programs. The information about "open files" (actually channels) is displayed as chan flags filespec ---- ------ --------------------------------------------------- 10 ( ) DKA100: 20 ( r ) _CHRIS$DKA100:[PUBLIC.HER]HERTEST.EXE;1 30 (sr ) _CHRIS$DKA100:[SYSCOMMON.SYSLIB]UVMTHRTL.EXE;1 40 ( ) RTA1: 50 ( ) RTA1: 60 (sr ) _CHRIS$DKA100:[SYSCOMMON.SYSLIB]LIBRTL.EXE;1 70 (sr ) _CHRIS$DKA100:[SYSCOMMON.SYSLIB]VAXCRTL.EXE;1 80 ( ) RTA1: 90 ( rw ) _CHRIS$DKA100:[USER.MURPHY]HARDWARE_EXCEPTION.RPT;1 A0 (sr ) _CHRIS$DKA100:[SYSCOMMON.SYSMSG]VAXCMSG.EXE;1 B0 ( r ) _CHRIS$DKA100:[PUBLIC.HOLMES]SHERLOCK.EXE;1 C0 (sr ) _CHRIS$DKA100:[PUBLIC.HOLMES]MYCROFT.EXE;2 r = read access s = section file w = write access x = exclusive access the information about "images" is displayed (scrunched to fit 80 columns) as chan name version linked codes gs ident address patch ---- --------------- ------- ------------ ----- -------- ----------- ----- 20 HERTEST V1.0 23-JUL 13:31 0,0 200: 35FF 1,2 30 MTHRTL V05-005 12-OCT 04:24 IOHS 129,12 3600:2D5FF 60 LIBRTL V05-001 12-OCT 04:20 IOHS 1,14 2D600:46BFF 70 VAXCRTL V05-001 12-OCT 04:32 IOHS 4,3 46C00:5E7FF A0 VAXCMSG V04-007 12-OCT 04:57 IOHS 0,0 7F800:805FF B0 SHERLOCK_HOLMES V1.0 23-JUL 14:03 0,0 80600:817FF C0 MYCROFT_HOLMES V1.0 23-JUL 14:02 IOHSP 1,0 81800:829FF and the information about "locks" is displayed (scrunched to fit 80 columns) as lockid parent resource grp access gr rq state valueblock -------- ------- ------------ --- ------ -- -- ------- ------------------- 5C0000B5 1000000 LMF$_VAX-VMS sys exec NL PW granted 0 0 0 0 2F0001BB 0 TEST_ONE sys user CR CR granted 0 0 0 0 200001F4 0 TEST_THREE 100 user EX EX granted 0 0 0 0 260001F6 0 TEST_TWO 100 user NL NL granted 0 0 0 0 10001FD 0 TEST_FOUR 100 user PW EX granted 1111 2222 3333 4444 30001FE 0 RMS$... sys exec EX NL granted 0 0 0 0 50001FF 30001FE APPENDER sys exec PW NL granted 0 0 0 0 2000202 30001FE .... sys exec NL EX granted 71 0 0 0 This package contains the source code and build procedure for both images and a sample program demonstrating a call. Since the open-files and activated-images information requires access, and access is required to find all of the existing-locks information, I decided to make two images: the more privileged image would be written in MACRO32 as a user-written system service which would gather the data, while the non-privileged image would be written in C as a dynamically-loaded shareable image for the simple reason that I did not want to link all of my programs against the privileged image. They are named MYCROFT and SHERLOCK respectively (Mycroft Holmes was Sherlock's smarter brother, which I found appropriate). The calling application invokes either of the two universal entry points in SHERLOCK, which in turn call several entry points in MYCROFT. +----------+ lib$find_image_symbol() +--------------+ | MAIN.EXE | ---------------------------> | SHERLOCK.EXE | +----------+ +--------------+ | linked V against +-------------+ | MYCROFT.EXE | installed /PROTECT +-------------+ The BUILD.COM procedure will attempt to compile any source modules whose matching object file is missing, then link the three images in "production" mode (i.e., no debug and no traceback). All necessary object files are included in the package for both VAX and AXP machines to avoid having to recompile. Images are also included in the package, but these should be avoided since the MYCROFT.EXE shareable is system-version dependent. After successfully building the images, the STARTUP.COM file must be run to define the logical names and install the images. Note that MYCROFT.EXE, as a protected shareable image, must be INSTALLed --- in fact, it must be INSTALLed with the /PROTECT qualifier. SHERLOCK.EXE, as a normal shareable image, does not have to be INSTALLed, unless of course the main executable which loads it is itself INSTALLed with privileges. Note that the logical names MYCROFT_HOLMES and SHERLOCK_HOLMES are defined by the STARTUP.COM procedure as executive-mode logicals in the system table; this is not *absolutely* necessary but is the canonical method. ok dpm --- David P. Murphy mailto:murphy@connor.datametrics.com (work) systems programmer mailto:dpm@access.digex.net (personal) http://www.access.digex.net/~dpm COGITO ERGO DISCLAIMUM ftp://ftp.access.digex.net/pub/access/dpm