A transaction approach to error handling - includes related article on error definition - Technical
Bruce A. RafnelThe transaction-based recovery concept used in databases can be applied to commercial applications to help provide more reusable and maintainable programs.
Commercial programs contain two major paths: a forward path that does the work and a reverse path that rolls back the work when errors are detected. Typically, these paths are so tightly bound together that both paths are difficult to read. Code that is difficult to read results in code that is difficult to write, debug, enhance, and reuse.
For example, in the object-oriented programming methodology, one reason why objects are not as reusable as they should be is that they are tightly bound together at the error-handling level. Many times error codes even give clues about how an object is implemented.
The solution is to handle errors in programs as they are handied in a database transaction* recovery mechanism. In a database transaction, the transaction either executes in its entirety or, if an error is detected in any of its operations, it is totally canceled as if it had never executed. If an error is found, all work is automatically rolled back to the beginning of the transaction.
Error Handling
Software developers have sometimes been dismayed by how difficult commercial programs are to maintain and design, compared to programs they developed in school. Someone typically points out that programs developed in school were "toys," which assumed perfect inputs and hardware with unlimited memory and disk space. In addition, most software engineers have very little formal training in error-handling methods. Typically, software developers learned error handling by example or by trial and error, and they use the traditional error-handling model: check for an error, find an error, and return an error code.
Many formal design processes, such as structured analysis and structured design, recommend that errors be ignored during design because they are an implementation detail. It seems that this implementation detail can take up to one third of the code in commercial programs. This is not just code added around algorithms, but code placed directly in the middle of the algorithms. The resulting programs are difficult to read, debug, and reuse.
Exception handling, or error handling, has a large academic base and many of the ideas given in this paper are probably not new. However, most of the ideas presented here are based on 15 years of observations and experiences with a lot of good feedback from experienced programmers. This paper will describe a programming style that separates most of the error-handling process from the main algorithms.
Mixed Forward and Reverse Path Problem
The two major paths in commercial programs are shown in Fig. 1. The forward path is the path doing the work that the program is designed for. The reverse path is the error-handling code needed to keep the forward path working correctly. It does this by detecting problems, fixing them, and rolling back partially completed work to a point where the algorithm can continue forward again.
Tramp Error Problem
Often an intermediate function in a program has to stop what it is doing in the middle of the algorithm because a function it called cannot complete its designed task. This can lead to "tramp errors."* Tramp errors are errors in functions that are not directly related to the current function.
Tramp errors are the result of a real error occurring in a lower-level function. For example, function A() calls function B(). Function B() needs some memory, so it calls the malloc() memory allocation function. The malloc() function returns an out-of-memory error. This is a real error for the malloc() function. Function B() does not know how to get more memory, so it has to stop and pass the error hack to function A(). From the perspective of function B() and probably function A(), an out-of-memory error is a tramp error.
Tramp errors prevent functions from being the black boxes they were designed to be. In the above example, notice that function A() now knows something about how function B() is implemented.
Tramp errors are really part of error recovery and not part of error detection because if the real errors could be corrected immediately, tramp errors would not occur.
Unreadable Code and Poor Reuse
Mixed forward and reverse paths and tramp errors combine to obscure the main forward path of the program, which is doing the real work. The correction and recovery parts of error handling are the main areas that obscure the code. Most of the detection and reporting code can be put in separate functions.
Because of tramp errors, almost every function has to handle errors generated by all lower-level functions called. This can cause tight data coupling which makes code reuse more difficult.
Transaction Error-Handling Solution
To solve the above problems, two things need to be done: separate the forward processing path from the reverse error-processing path and use context independent error codes. This method of error handling is very similar to the way databases handle error recovery. Transactions are used to control the rollback process when a group of database operations cannot be completed successfully.
Separate the Paths
The traditional defensive way of programming is to assume that a function may have failed to complete its designed task, resulting in a lot of error-handling code to check for the errors and to roll back partially completed work. This is what we have in Fig. 1.
Reverse this assumption and assume that returning functions have completed their designed tasks successfully. If the function or any of the functions it calls has errors, it will pass processing control to a recovery point defined by the programmer. In other words, transaction points are defined so that if there are any problems, the work will be rolled back to those points and the processing will proceed forward again.
With this approach, there is no need to check for errors after each function call, and the forward path is not cluttered with tramp error-detection code. Only error-detection code for real errors remains, and most of the error-correction and recovery code is clustered around the beginning and end of the transactions (see Fig. 2).
Because errors are processed separately from where they are detected, the error codes need to hold the context of the error.
Context Independent Error Codes
Error codes that provide more information than just an error number are context independent error codes. Information such as what function generated the error, the state that caused the error, the recommended correction, and the error severity must be encoded in the error code so that it can be corrected in a location separate from the forward processing path.
Usually contexts of errors are encoded for error-reporting functions. For example, the names of the program, function, error type, and error code are saved and reported later. However, sophisticated encoding schemes are rarely used because with traditional error handling, the context of the error is already known because checking is done right after a call to the offending function.
With transaction error handling, the recovery process is separated from the forward processing path so context independent error codes are required. This may involve the creation of unique error codes across a whole application or system (with the codes bound at compile time). An alternative would be to assign code ranges or other unique identifiers to functions at run time.
Code Readability and Reuse
The transaction approach makes programs easier to read because the reverse error process paths are visually separated from the forward process paths.
The transaction error-handling style makes it possible to create some general error-recovery interfaces so that functions (modules or objects) will only be loosely connected at the error handling level. This is possible because the number of tramp errors used to control the recovery process is reduced and only the real errors need to be handled.
Implementation
The following are some ideas about how to start developing a transaction error-handling library. The list is not exhaustive and there are some problem areas, but it does offer some concrete ideas for building a transaction error-handling mechanism.
Transaction Control Management
Some language support is needed to implement the mechanism that controls error recovery. Languages like HP's PascalMODCAL have a try/recover feature that can be used to support a transaction error-handling style. The try/recover statement defines error-recovery code to be executed if an execution error is detected within a particular area of a program. Fig. 3 shows the flow of control for a try/recover statement.
For other languages a feature usually called a "global goto" must be used. This feature allows a lower-level function and all other functions above it to exit to a point defined in a higher-level function without passing error-code flags through aH the other functions. In C this is done with the setimp and longimp library routines. The setjmp function saves its environment stack when it is called, and longimp restores the environment saved by setjmp. The examples given later in this article are written in C and show how these functions are used.
The new C++ exception-handling feature(2) provides an excellent foundation for a transaction-based error handler. Reference 3 also describes how to add C++ error-handling functions to regular C programs. However, overuse of the C++ exception-handling feature could lead to code that is just as cluttered as the traditional error-handling style. Transaction boundaries for objects must be designed with the same care that goes into the design of an object's interface.
If the language is missing a global goto (or multithreaded) feature, macros or other wrapper* functions can be used to build recovery processes that are mostly invisible. Wrapper functions are described in more detail later.
Some of the features that might be considered for a transaction error-handling package include:
* Allowing nested transactions by keeping the transaction
begin points on a stack
* Allowing functions to share a common transaction stack
* Allowing functions to define their own transactions with a common transaction stack or allowing functions to define their own transaction stack for special cases
* Defining special transaction points to handle errors in common categories (For example, abort the whole program, restart the whole program, close all files and restart, close current file and restart, and release all memory not needed and restart.)
* Making provisions for the transaction error handling to be turned on and off (When it is off, a function returns error codes in the traditional way.)
* Defining expected errors for some functions by masking out the errors needed. (This feature can be simulated by turning off transaction error handling, but then unexpected errors will also have to be managed.)
Transaction Data Management
Recovery involves more than just rolling back functions because there may be some intermediate work that needs to be undone. This may involve releasing unneeded memory or changing global variables back to the values they had at the beginning of the transaction.
Memory. Memory is best managed with a mechanism similar to the mark/release memory feature provided in some implementations of the Pascal programming language. The mark/ release procedures allow dynamic allocation and deallocation of memory in an executing Pascal program.
The C language functions malloc() and free(), in conjunction with a stack of pointers to keep track of the memory allocated, provide the best features for allocating and freeing memory. With these features, a mark function can be called just before the program transaction's start point to mark the current stack point. If a longimp() goes to this recovery point, a release function is called to free any memory allocated after the mark point.
A commit function, which indicates the successful completion of a transaction in the database context, is needed at the end of a program transaction to remove pointers from the mark/release stack. Nested transactions, however, need to be considered. A simple solution would be to have each transaction keep its own mark/release stack.
Globals. Global variables (and other static variables) can be rolled back with a strategy similar to the memory management problem. Just before a transaction's begin point the states of all the globals that might be changed in a transaction are saved on a stack. This allows transactions to be nested.
Context Independent Error Codes. The traditional error-handling style of checking error codes after each function call automatically gives errors a context. The transaction error-handling style needs to provide this context information in another way.
The biggest challenge here is that error codes alone are not very useful. For example, 97 could be the letter "a" (ASCII code), the digits "6" and "1" (BCD format), index 97 into a message array, the 97th error, an out-of-memory error, a disk-full error, a divide-by-zero error, and so forth.
To decode an error code the source of the error must be known. Some information that may need to be saved when an error occurs includes the machine name, program name, process number, module name, function name, and of course, the error code. This information needs to be sent only when it is necessary to roll back a transaction.
The amount of information that has to be saved is dependent on the location of the transaction recovery point and the run-time environment. For example, a client-server application may need more information than a simple PC application. Each recovery point can usually find higher-level context information fairly easily. For example, the names of the machine, program, module, and function can easily be passed down to a lower-level recovery point. However, lower-level context information cannot be collected because the function that had the error would no longer be active.
Implementation Summary
The following are some points to consider when implementing a transaction error-handling scheme: Put the rollback points (if any) at the beginning of functions Put error detection and default substitution at the beginning of functions Put some error-detection code in the middle of functions to check intermediate values Put error-detection code at the end of functions to validate the results Do not put error-handling code for managing rollbacks in the middle of a function.
Examples
Traditional Error-Handling Style. The following example program, which reads a binary formatted file, is coded with a common error-handling style. The code would have been more cluttered without the aExitErr() and aRetErr() macros to manage the error reporting and recovery. This example uses the simple error-recovery process: detect error, report error, and exit. However, notice how much error-handling code is mixed in with the algorithm.
/* read.c-Read a binary formatted file */ /* This program reads and prints a binary file that has the */ /* following structure: */ /* */ /* Record type code (The last record has a value of O) */ /* Size Number of characters in Msg */ /* Msg 0 to 2048 characters */ /* Record type code */ /* Size */ /* Msg */ /* . */ /* . */ /* . */ #define aExitErr(pMsg, pErr) puts(pMsg); exit(pErt) #define aRetErr(pMsg, pErt) puts(pMsg); return(pErr) typedel struct { long Type; int Size; } aFileHead; /* */ /* Forward Algorithm: */ /* */ /* Main */ /* 1. Open the file. */ /* 2. Call the Read process. */ /* 3. Close the file. */ /* */ main(){ int Err; FILE * InFile; if ((InFile = fopen("file.bin", "rb")) == NULL){ aExitErr("Error: Could not open: file.bin",1 ); } if ((Err = aRead(InFile))!= O){ aExitErr("Error: While reading: file.bin", 2); } if (fclose(InFile){ aExitErr("Error: Closing: file.bin", 9); } }/* main()*/ /* Forward Algorithm continued: */ /* */ /* Read Process */ /* 1. Read the Type and Size values. */ /* 2. If Type = O, exit. */ /* 3. Read Size number of characters into the */ /* Msg variable. */ /* 4. Print the Msg. */ /* 5. Go to step 1. */ /* */ int aRead(pHandle) FILE * pHandle; { int Err, N; char * Msg; long RecNum; aFileHead RecHead; if ((Msg = (char *)maIIoc(2048))== NULL){ aRetErr("Error: Out of memory", 3); } RecNum = OL; while (1){ if (fseek(pHandle, RecNum, SEEK_SET) < O} { aRetErr("Error: in fseek", 4); } N = fread((char *) &RecHead, sizeof(aFileHead), 1, pHandle); if(N<O){ aRetErr("Error: in fread", 5); }elseif(N !=1){ aRetErr("Error: short fread", 6); } if (RecHead.Type == OL) { return(e); /* EOF */ } if (RecHead.Size) { if {(N= fread(Msg, RecHead. Size, 1, pHandle)) < 0){ aRetErr("Error: in fread", 7); }else if(N !: 1){ aRetErr("Error: short fread",8); } if ((Err = aPrint{Msg, RecHead. Size)) !: O){ aRetErr("Error: in aPrint", Err); } } RecNum = RecNum + RecHead. Size+ sizeof(aFileHead); } }/* aRead()*/
Transaction Error-Handling Method. The following listings show an implementation of the transaction error-handling style. The first listing shows the program (transaction) read.c rewritten to incorporate the transaction error-handling style. The other listings show the support functions for the transaction error-handling method.
Notice in the main body of the algorithm that the code following the recovery sections is clearer than the traditional error-handling example and there is no error-handling or recovery code mixed in with the algorithm.
There are some obvious shortcomings in the support modules. For example, most of the macros should be functions and the vEnv values should be saved in a linked list.
A number of engineers have pointed out that the transaction implementation of read.c is not really shorter than the traditional implementation of read.c because the error-handling code was simply moved out of read.c and put in the support functions. But that is exactly the goal: to remove the error handling code from most functions and encapsulate the errorhandling in common shared code.
The Main Program. This program performs the same function as the read.c program given above. However, it has been recoded to use the transaction style of error handling. The functions erSet, erUnset, and erRollBack provide the error handling and are defined in the include file erpub.h, which is described below.
The include file epub.h contains wrapper macros which are defined so that the appropriate transaction error-handling functions are called in place of the standard library function. For example, when the standard function fclose is invoked, the function eClose is actually called.
/* read.c - Read a binary formatted file */ /* This program reads and prints a binary file that has the */ /* following structure: */ /* */ /* Record type code (The last record has a value of O) */ /* Size Number of characters in Msg */ /* Msg e to 2048 characters */ /* Record type code */ /* Size */ /* Msg */ /* */ #include "erpub.h" #include "epub,h" typedel struct{ long Type; int Size; } aFileHead; */ */ /* Forward Algorithm: */ /* */ /* Main */ /* 1. Open the file. */ /* 2. Call the Read process. */ /* 3. Close the file. */ /* */ main() { FILE * InFile; erRecOn = 1; if (erSet()){/* Transaction rollback point */ prinff("Error: %d in function: %s\n", erErr erfurt); erUnset(); exit( 1 ); }/* End Recovery section */ InFile: fopen("file.bin", "th"); aRead(InFile); fclose(InFile); erUnset(); }/* main()*/ /* Forward Algorithm continued: */ /* */ /* Read Process */ /* 1. Read the Type and Size values. */ /* 2. If Type = 0, exit. */ /* 3. Read Size number of characters into the */ /* Msg variable. */ /* 4. Print the Msg. */ /* 5. Go to step 1. */ /* */ int aRead(pHandle) FILE * pHandle; { char * Msg; long RecNum; aFileHead RecHead; Msg = (char *) malloc(caMsgLen); RecNum =OL; while (1){ fseek(pHandle, RecNum, SEEK_SET); fread((char *) &RecHead, sizeof(aFileHead), 1, pHandle); if (RecHead.Type == eL){ return;/* EOF */ } if (RecHead.Size){ fread(Msg, RecHead. Size, 1,pHandle); aPrint(Msg, RecHead. Size); } RecNum = RecNum + RecHead. Size+ sizeof(aFileHead); } }/* aRead{)*/
File erpub.h. The macros and global data structures defined in this file form a crude error transaction manager. The following operations are performed by these macros:
* erSet. This macro adds a rollback point to the vEnv (environment) stack.
* erUnset. This macro removes the top ro]Iback point from the vEnv stack.
* erRollBack. This macro saves the function name and error code in a global area (erFun and erErr), and if the erRecOn flag is true, control is passed to the rollback point defined on the top of the vEnv stack. If erRecOn is false, erRollBack will simply return the usual error code.
Remember that these macros are for illustration only. Thus, there are no internal checks for problems, and the global data structures should be defined as static values in a library module or collected into a structure that is created and passed to each of the transaction error-handling functions.
/* erpub.h - Error Recovery Public Include file */ #include <setjmp.h> /* Private Variables */ #define vMaxEnv 5 jmp_buf vEnv[vMaxEnv]; int vLevel = -1; /* Public Variables */ #define cerFunNameLen 32 #define erSet() setjmp(vEnv[++vLevel]) #define erUnset() --vLevel #define erRollBack(pFun, pErr, pRet) \ strncpy(erFun, pFun, cerFunNameLen); \ erFun[cerFunNameLen-1] = \0; \ erErr = pErr; \ if (erRecOn && vLevel >= O){ \ Iongjrnp(vEnv[vLevel], pErr); \ } else { \ return(pRet); \ } int erErr = O; char erFun[cerFunNameLen]; int erRecOn = O;
File epub.h. This file contains wrapper macros that cause the functions defined in the file e.c to be called in place of the standard library functions. The functions in e.c will behave the same as the standard library functions, but if the error transaction manager is on (erRecOn is true in erpub.h), control will be passed to the last defined rollback point, rather than just returning the same error code as the associated standard library function.
Using these wrapper macros makes it easier to add transaction error handling to old programs, but if it is desired to make the error-handling process more visible, the functions defined in e.c would be called directly instead of the standard library functions.
This file is also a good place to define context independent error codes.
/* epub.h - Error Library Wrapper Macros (only a few are shown here)*/ #define ceEOF 1 #define ceOutOfMem 2 #define ceReadErr 3 #define ceReadShort 4 #ifndef vine #define fclose(pStream) eClose(pStream) #define fopen(pFileName, pType) eOpen(pFileName, pType) #define fread(pPtr, pSize, pNltem, pStream)\ eRead(pPtr, pSize, pNltem, pStream) #define fseek(pStream, pOffset, pPrtName)\ eSeek(pStrearn, pOffset, pPrtName) #define malloc(pSize) eMalloc(pSize) #endif
File e.c. This file contains the implementations of the wrapper macros defined in epub.h. Only two of the functions are shown in the following listing. Notice that these functions behave exactly like the standard library functions with the same name because they call the standard library functions.
For more flexibility, a real error transaction manager might allow the user to define the error codes that determine whether or not a rollback occurs.
/* e.c - Error Library Wrapper Functions (only a few are shown here) */ #define vine #include "epub.h" void * eMalloc(pSize) size_t pSize; { void * Mem; if ((Mem = malloc(pSize)) := NULL){ erRollBack("malloc", ceOutOfMem, Mem); } return(Mem); )/* eMalloc */ size_t eRead(pPtr, pSize, pNItem, pStream) char * pPtr; size_t pSize, pNItem; FILE * pStream; { size_t Num; Num = fread(pPtr, pSize, pNltern, pStream); if (feoflpStream)){ erRollBack("fread", ceEOF, Num); } else if (Num <:0){ erRollBack("fread", ceReadErr, Num); } else if (Num < pNltem) { erRollBack("fread", ceReadShort, Num) } return(Num); }/* eRead */
Conclusion
When transaction error handling was introduced on a project, engineers initially resisted removing IF statements after calls to functions using transaction error handling. After seeing how much easier the code was to write and read, the resistance faded and engineers started setting up their own transaction recovery points.
It would seem that debugging code using the transaction error-handling style would be difficult. However, experience has shown the debugging time to be a little better than the debugging time for a traditional error-handling style. This decrease in time can probably be attributed to less embedded error-handling code, causing defects to stand out more. Also when error-handling code is added, it is added in a structured way that disturbs very little of an already debugged program. This supports the way most engineers traditionally like to code.
So far this error-handling style has not been used on any large projects, but it has been used on small programs and functions written for enhancing old programs. One of the nicest features of this style is that it can be used independently of other error-handling styles.
In summary, a transaction error-handling style can lead to the following benefits:
* More reuse because error handling can be separated from the algorithm so that the coupling between functions is looser
* Improved code supportability because it is easier to read the algorithm and see what happens with errors
* Better code quality because there are fewer error-handling statements in the main algorithm, so the code is easier to read and the defects stand out.
Just as the functional parts of algorithms are being separated from user interfaces (client/server models), error handling can also be separated from the functional algorithm.
Acknowledgments
The author would like to thank a number of coworkers who helped review and refine the ideas presented in this paper, in particular: Andra Marynowski and Kevin Wentzel who were there at the birth of this coding style. Also thanks to King Wah Moberg for a number of reviews.
References
1. M. Page-Jones, The Practical Guide to Structured Systems Design, Yourdon Press, 1980, p. 104.
2. B. Stroustrup and M. Ellis, The Annotated C++ Reference Manual, Addison-Wesley Publishing Company, 1990.
3. C. Vidal, "Exception Handling," The C Users Journal, September 1992.
Authors
June 1993
Gary B. Gordon
Gary Gordon was the project manager for the HP Laboratories phase of the ORCA robot project. He joined HP full-time in 1966 as a digital designer on the computing counter project, HP's first arithmetic unit to employ digital ICs. Later he became project manager and then section manager for HP's first laser interferometer. Gary is perhaps best known for pioneering HP's entry into instrumentation for digital designers with such instruments as the logic probe, clip, and pulser and the logic analyzer and signature analyzer. In 1979 he transferred to HP's central research laboratories, where he has been a project manager for a series of instruments for the HP Analytical Products Group including the justintroduced high-sensitivity capillary electrophoresis detector. Presently he heads a micromachining effort. Gary received a BSEE degree in RF communications from the University of California at Berkeley in 1962 and an MSEE degree in computer design from Stanford University in 1970. He has authored a dozen articles, has had products featured on seven magazine covers, is named as an inventor in 23 patents, and is listed in Who's Who in California. He served four years as a U.S. naval officer and is an associate professor at California State University at San Jose. His hobbies include large-format photography (he shot this issue's cover), flying, and designing and building modern furniture and houses.
Joseph C. Roark
Software design engineer Joe Roark was born in Springfield. Ohio and studied chemistry at Denison University (BS 1974)and Duke University (PhD 1980). He joined HP Laboratories in 1980, where he worked on prototypes for the HP 1046A fluorescence detector and the HP MicroAssay System. More recently, he moved to the Scientific Instruments Division and contributed to the architecture and the method development software for the ORCA robot project. He's presently working on networking and automation for HP ChemLAN products. A member of the American Chemical Society, Joe is named as a coinventor in a patent related to robot motion. Outside work, he plays jazz piano and soccer and coaches youth soccer and baseball teams. He is married and has two children.
Arthur Schleiler
A New York City native, Artie Schleifer has held several technical and management positions since joining HP's Avondale Division in 1974. He contributed to the development of the HP 8450/51 diode array spectrophotometers and was project manager for robotic systems at HP Genenchem, HP's joint venture with Genentech, Inc. Now at the Scientific Instruments Division, he was project manager for the Analytical Products Group for the ORCA project and currently works on hyphenated instrument control and DOS and Windows systems software. Artie received a BS degree in chemistry from the City University of New York in 1971 and worked at Wyeth Laboratories before coming to HR He is the author of six papers and conference presentations on chemistry, instrument software, and automation and is named as an inventor in three patents on software algorithms and robotics, Artie coaches soccer and baseball, has two sons, and enjoys sailing, boardsailing, tennis, softball, golf, woodworking, gardening, and skiing.
20 HP Open ODB
Rafiul Ahad
As architect of the HP OpenODB program at HP's Commercial Systems Division, Rafiul Ahad is responsible for software design and development and consultation with customers. Born in Rangoon, Burma, he studied physics ,and computer science at Rangoon University. His degrees (BSc in physics and MSc in computer science)were awarded in 1973 and 1975. He continued his studies at the Asian Institute of Technology in Bangkok, Thailand, from which he received an MSc degree in computer applications in 1980. After coming to the United States, he completed work for a PhD degree in computer science at the University of Southern California in 1985. Before coming to HP in 1989, he was an assistant professor at the University of Maryland. Rafiul is the author of four technical articles in the area of database systems and has presented papers at numerous conferences. He is a member of the ACM and the IEEE. He is married, has two children, and enjoys tennis and volleybail.
Tu-Ting Cheng
R&D section manager Tu-Ting Cheng was horn in Bangkok, Thailand and attended National Taiwan University, from which he received a E)SEE degree in 1969. Later, he completed work for an MSCS degree from the University of Wisconsin at Madison (1971)and for MS and PhD degrees in computer science from Ohio State University (1975 and 1976). With HP since 1976, most of his work has been in the database area, aod he is now responsible for the HP OpenODB program. Tu-Ting and his wife have one child, and he likes ballroom dancing.
31 HP Ultra VGA Graphics Board
Myron B. Turtle
A development engineer at the California PC Division, Myron Tuttle studied electrical engineering at the University of California at Berkeley (BSEE 1973 and MSEE 1974). With HP since 1974, he worked on the HP 2625/28 terminals and the original multimode video board for the HP Vectra. He contributed to the development of the video subsystem forthe HP Ultra VGA board and is now involved in video and graphics development. Myron is named as the inventor for a patent on automated software testing and is coauthor of an earlier HP Journal article as well as a paper for an HP software conference. He also served in the U.S. Navy as an electronic technician. His hobbies include computer programming, home improvement projects, and classical music.
Kenneth M. Wilson
With HP's California PC Division since 1989, Ken Wilson has worked on a series of HP Vectra products, including the Vectra 486/25T and 33T, the Vectra 486s/20, and the HP Super VGA board. Most recently, he contributed to the development of the HP Ultra VGA board. He completed work for a BSEE degree from California State Polytechnic College at San Luis Obispo in 1988 and expects to receive his MSEE degree from Stanford University in 1993. His professional specialty is computer architecture, and when he takes a break from work, he enjoys boardsailing and relaxing in his hot tub.
Samuel H. Chau
R&D engineer Sam Chau was born in Hong Kong and attended the University of California at Berkeley. He received his BA degree in computer science in 1984 and came to HP's Santa Clara Division in 1985. Now at the California Personal Computer Division, he contributed to the development of the HP Super VGA board and worked on the hardware and display timings forthe HP Ultra VGA board and the HP Vectra 486U embedded Ultra VGA+. Sam's outside interests include personal computers, audio and video technologies. photography, piano, classical music. and badminton.
Yong Deng
Born in Shanghai, China, software design engineer Yong Deng joined HP's California Personal Computer Division in 1989. He studied for his bachelor's degree in computer science at the University of California at Santa Cruz and graduated in 1986. In the past. he was responsible for software drivers and utilities for HP's intelligent graphics controllers. He developed a new display redraw method that improved CAD display list performance. He also ported Texas Instruments Graphics Language (TIGA) 2.05 and 2.20 to HP's intelligent graphics controllers. For the HP Ultra VGA graphics project, he was responsible for the AutoCAD and Windows high-resolution display drivers and video BIOS. His other professional experience includes software development at National Semiconductor and Autodesk Inc. His professional interests include high-resolution display drivers and application development for Windows and CAD tools. Yong is married and has a young daughter.
41 POSIC Interface for MPE/iX
Rajesh Lalwani
A software engineer at the Commercial Systems Division, Rajesh Lalwani joined HP in 1988. He was born in Mandsaur in the Madhya Pradesh state of India. He received a master of technology degree in computer science from the Indian Institute of Technology, New Delhi in 1986 and an MSCS degree from Pennsylvania State University in 1988. In the past. he enhanced and maintained command interpreter software and components of the MPE operating system kernel. More recently, he developed a procedure for parsing MPE and POSIX file names and a directory traversal routine. He's currently working on symbolic links functionality and device files for MPE/iX. Rajesh is the author of several POSIX articles, has presented a number of conference papers on the same topic, and is working on a book on POSIX.1. His outside activities include tennis, watching classic movies, and staying in touch with his wife, who is finishing her medical degree in India.
47 Preventing Software Hazards
Brian Connolly
Brian Connolly is a project manager for software quality engineering in HP's Patient Monitoring Systems Division and has been with the company since 1984. Previously, he developed real-time software systems for Raytheon Corporation and Westing-house Corporation. Since joining HP, he has worked on real-time software development for a bedside monitoring application, object-oriented software development in a clinical information system. and software quality engineering for several bedside monitor and central reporting station products. He has written several papers related to hazard avoidance and software quality and testing for internal HP publication. He's also a member of the IEEE. His educational background include a BS degree in physics and engineering awarded by Loyola College in 1977, and an MES degree (1983)in digital systems, also from Loyola. Brian is married and has two children. His leisure activities include running, swimming, woodworking, and coaching youth soccer.
53 Configuration Management for
Test
Leonard T. Schroat
With HP since 1985, software quality engineer Len Schroath worked at the Logic Systems Division and the Colorado Springs Division before moving to his current position at the Boise Printer Division. He's the author or coauthor of six papers for HP conferences related to software quality, testing, and reuse. Len was born in Detroit, Michigan and attended Brigham Young University, from which he received a BS degree in computer science in 1985. He is married, has three small children, and is a coach at his local YMCA. He also enjoys music and sports and officiates at basketball games.
60 Software Inspections
Jean M. MacLeod
A native of Arlington, Massachusetts, Jean MacLeod studied elementan/ education and sociology at Emmanuel College in Boston, Massachusetts, and received a BA degree in 1971. She has worked in the software quality field since 1974, initially in several small to mid-sized companies before joining Apollo in 1987. At Apollo, she was responsible for initiating a software inspection program in an R&D lab. She joined HP's Corporate Engineering Software Initiative in 1991, and contributed to the improvement of software inspections for the Patient Care Monitoring Systems Division at Waltham. She's now working on software process improvement with other divisions in the Northeast. Jean is a member of the Society of Women Engineers. She has two teenage children and enjoys golf, racquetball, and reading.
64 TQC for Software Localization
John W. Goodnow
1988 from Stanford University through the Honors Coop program. His first HP projects included work on HP PageWriter eiectrocardiographs and ultrasound system soft|areI and he continued work on ultrasound software development as a project manager and now as a section manager. John's professional interests include computer and system architecture, operating systems, and image processing. Born in York, Pennsylvania, he is married and enjoys boardsalting, skiing, woodworking, and vacationing on Martha's Vineyard.
Cindie A. Hammond
Cindie Hammond has been with HP's Imaging Systems Division since 1989. Born in Nassau, the Bahamas, she studied computer science at the University of Utah, from which she received a B8 degree the same year she started at HR An R&D software development engineer, her professional interests include ultrasound imaging and image processing. She's a member of the ACM and tutors mathematics at a local etementary school. Her outside activities include softbail, boardsailing, drawing and painting, and renovating her home.
William A. Koppes
Bill Koppes was born in Morristown, New Jersey and studied electrical engineering at the University of Washington at Seattle (BSEE 1976)and at the University of California at Berkeley (MSEE 1978). At Berkeley's Donner Laborato|y he also developed positron emission tomegraphy and reconstruction algorithms. He joined HP's Imaging Systems Division in 1978, where he first was a hardware development engineer and then a software development engineer, project manager, and section manager. Now principal engineer at the Advanced Imaging Systems group, his professional interests include medical imaging and clinical diagnosis, software development, and R&D management. He is coauthor of a paper related to digital signal and image processing and has actively participated in several professional conferences. Bill is married, has a son and daughter, and enjoys composing and performing music.
John J. Krieger
John Kriegerjoined HP's Waltham Division in 1974, where he worked on the digital hardware and software design of the HP 4721 OA capnometer. After moving to the Imaging Systems Division, he contributed to the software design and development for the HP SONOS 100 and 1000 cardiovascular imaging systems. He's now specializing in diagnostic ultrasound imaging. He's the author of two previous HP Journal articles related to the HP 47210A capnometer, and has presented papers at two HP software engineering productivity conferences. He is also the inventor of a patent related to a help facility for the HP SONOS 10Q Born in Santa Monica, California, John received a combined bachelor's and master's degree in electrical and biomedical engineering from the University of California at Los Angeles in 1973. He is married and has two daughters. Active in his church, he enjoys acting in community theater and is renovating his home,
an 1850s vintage New England farm house.
Daniel Kris Rovell-Rixx
Kris Rovell-Rixx has been with HP since 1990 and is a software development engineer at the Imaging Systems Division, Previously, he designed and implemented real-time software for automated test equipment and fuel controls for jet aircraft at the Hamilton-Standard Division of United Technologies. He also worked for Ashton-Tate, and for a small manufacturer of IBM PC peripherals. Born in Miami, Florida, he completed work for a BS degree in engineering (computer science emphasis)in 1979 from the University of Florida and an MS degree in engineering management in 1987 from Western New England College. He's a member of the ACM and the IEEE. Kris is a sailing enthusiast. He and his wife have sailed in the Virgin Islands and Windward Islands, and in 1992 he was a volunteer for Sail Boston '92, a parade of tall ships. He's also an amateur radio operator (call sign WXlZ)and enjoys all types of music.
Sandra J. Warner
Sandy Warner joined HP in 1984 as a clinical applications specialist in the Midwest sales organization and is now a globalization specialist in the Imaging Systems Division. Her professional interests include market research on Customer needs, foreign language translations, and ISO 9000 coordination. She was born in Rochester, New York and has a BS degree in zoology from The Ohio State University (1976). Before joining HP she managed a mobile cardiovascular testing service for a diagnostic service organization and before that she managed a diagnostic lab for a medical center. Outside of work, she teaches astronomy for an HP-sponsored school science program, and likes skiing, carpentry, landscaping, and backyard barbecue extravaganzas.
71 Transaction Error Handling
Brace A. Rafnel
Software development engineer Bruce Rafnel has worked in the R&D labs at eight HP divisions since joining the company's General Systems Division in 1981. His contributions include the development of software for the HP 150 and HP Vectra personal computers and working on the dictionary team for the HP 3000 and HP 9000 computers. He's now in the Professional Services Division. A graduate of California Polytechnic State University at San Luis Obispo, he received a BS degree in computer science in 1981. He's a member of the IEEE and the C User's Group, and includes.document management systems, computer graphics and image processing, objectoriented programming, and neural networks as professional interests. Bruce is married and has a young daughter. His hobbies include home automation with voice control.
80 HP-UX System Administration
Mark H. Notess
Mark Notess was born in Buffalo, New York and studied English and teaching English as a second language at Virginia Polytechnic Institute and State University. He received a BA degree in English in 1979 and an MA degree in education in 1981. He was an instructor at the University of Alabama and later was a programmer and instructional designer at the Virginia Cooperative Extension Service before completing an MS degree in computer science, again from Virginia Polytechnic Institute, in 1988. Since joining what is now HP's Open Systems Software Division the same year, he has designed, implemented, and tested software for several projects, including user interfaces for HP-UX system administration. His work on the object action manager for HP-UX has resulted in a patent application. He is a coauthor of two articles and has presented several papers at technical conferences. He's also a member of the ACM and SIGCHI. Mark is married and has three children. His leisure interests include reading medieval history and literature, hiking, and playing acoustic guitar.
COPYRIGHT 1993 Hewlett Packard Company
COPYRIGHT 2004 Gale Group