Error handling in DP4 Programs

The following notes apply in detail only to application programs created using the DP4 C OWN libraries, though some of the information may be of interest to users of the dp4dbapi.h interface and dp4dbase C++ encapsulation of it. Special considerations apply to ADC and NOTRM programs, which are noted from time to time.

Introduction

Whenever a program calls a function to perform some operation, potentially the function may not be able to complete the operation normally for some reason. In this situation it may do one of two things:

The DP4 C library has traditionally favoured the second approach as it makes for simpler programming, and reduces the likelihood of a serious error condition's being inadvertently ignored. However this has left little scope for error handling beyond generating an error message and terminating the program, which in some situations is not acceptable.

How errors are raised in DP4

In the majority of cases DP4 functions raise errors by calling one of two error functions: sys_error(),and sys_fail(), which generate an error message and then call dp4_halt() to terminate the program.

Only functions which use the database manager or terminal manager generate calls to sys_error() or sys_fail(). Therefore none of the functions listed in dp4capi.h in the section devoted to functions that do not require SRVn or TRMn generate system or fail errors.



In the past a number of DP4 users tried to continue after errors by replacing the code of sys_error() and sys_fail() with functions which do not terminate, or (in more recent times) by writing an app_close() function which stops dp4_halt() from terminating the program.

Unfortunately this could lead to situations where programs have then failed catastrophically or gone into a tight loop, because DP4 library code was written with the expectation that sys_error() and sys_fail() would never return control to the caller.

In 4.523/4.6xx and later releases the sys_error(), sys_fail(), sys_message() and sys_request() functions all proceed via a new function, dp4_error(), which calls a user supplied function app_error() which can be used to intercept the error,allowing complete control over the generation and handling of error messages. Also library code does not rely on calls to DP4 error functions terminating the program.

The DP4 Quick Reference error documentation describes for each system and FAIL error, whether or not it is safe to try to recover from the error, and attempts to analyse on a function by function basis, (or error by error basis for errors which can be generated by a large number of functions), what modifications to the standard error handling are permitted. The next section discusses other types of error which can arise when DP4 functions are called and which are not handled by calls to sys_error() or sys_fail().

Errors not handled by calls to sys_error() and sys_fail()

  1. Parameter Errors

    In general DP4 functions do not make extensive checks on the validity of their parameters. Parameters are checked in situations where they could upset another program, so for example the length of records is checked on calls to the database manager.

    Passing an invalid pointer or a pointer to the wrong type of object is likely to cause some kind of protection violation. Under MS-DOS it is likely to cause disaster. (Meaning the kind of crash which can only be recovered from by physically switching machine off and on)

  2. Stack faults

    The DP4 C library functions do not use a substantial amount of stack and legacy versions are therefore generally built with compiler stack checking turned off. A stack overflow will therefore generally cause a protection fault or disaster under DOS.

  3. Heap Functions

    There are two types of error: memory exhaustion and heap corruption. Memory exhaustion is handled by calling the function pointed to by mallocx_handler() and/or returning 0.

    Heap corruption is not detected by the standard version of the DP4 heap functions. By compiling the module ccnheap1.c and cclru.c with DEBUG defined you can enable heap corruption to be detected. However this should only be needed at development time, as the heap can only be corrupted by programs containing bugs which cause memory corruption. Detection of heap corruption is quite expensive in terms of execution time.

  4. LRU functions

    The only type of error here is where the LRU chain becomes corrupt. Again this is only detected by linking in a version of cclru.c compiled with DEBUG defined.

  5. Errors from OSDI

    Errors from an OSDI are handled by calling the function dvc_check(). The standard version of this function generated sys_error(129). However typically this function is replaced by a custom version. In QAB the custom version typically uses hot key processing to handle such errors.

The sys_error(),sys_fail() and dp4_halt() error functions

Further details of exactly how and when calls to DP4 error functions are generated are contained in How calls to DP4 Error Functions are generated.

The following sections describes the implementation of the sys_error(),sys_fail() and dp4_halt() functions. The details of these functions depend considerably on the release of DP4 being used and also the type of program being written.

  1. Standard DP4 C programs
  2. NOTRM Programs
  3. ADCs