Dr. Khan Monzoor-E-Khoda
The failure of an internal assertion causes the base of an internal error. It is all environmentally related and does not branch to Clipper internal Error block whenever it occurs. In this paper, a set of unexplained internal errors are investigated and their casual factors are carefully examined.
Every developer gets a runtime error when they are involved with their new development, but in fact, none of them can accept or tolerate any of these unwanted errors after the product has been released. Although most Clipper Errors branch to the current error block, some internal errors do not.
In a very recent paper by Key, S (Ref. 4.), an incomplete subset of Internal Clipper Errors were documented. We hope, in this paper, to both augment Key’s work by further examining other less widely understood internal errors, and re-examine those errors listed by Key in his original paper. Error characteristics will be analyses, with an emphasis on root causes.
2. What are Internal Errors
In Clipper, runtime errors are dependent totally on the error handler and the subsystem that generates the error. Errors generally occur either because of mistakes in the program code (i.e., type mismatch, divided by zero) or because of some condition of the environment (i.e., out of file handles, file sharing violations, memory low). The error handler communicates with the subsystem by returning a value. This value indicates what the subsystem should attempt to do to recover from the error. The legal values are generally determined by the values handler. These type of errors, in fact, can be trapped in the error system so that the application which has been affected does not necessarily terminate. However, sometimes it is not possible to trap a runtime recoverable error due to an invalid value returning from the error handler to the subsystem (see Ref. 1).
On the other hand, whenever a program code is executed in the error system, ErrorSysQ function, before invoking the ErrorBlockQ function, an error handler is unavailable to the ErrorSysQ and unrecoverable error is caused. This usually happens because such errors can not branch to the error block so that the ErrorSysQ is unable to execute the error block. These errors are, in general, reported with the message
‘Unrecoverable error <error type>’
Other errors occur when an internal assertion fails. These are simply reported with ‘Internal Error’. All of such errors are more of less related to the environment (i.e., out of memory, error reading code to execute from disk). An in-depth analysis of error handling strategies can be found in Ref. 2.
3. Highlighting Internal Errors
An outline of the major infamous Internal Errors are listed here, whereas the standard list can be found in either Ref. 3 or Ref. 1. The characteristics together with the causes of each error are examined.
Internal error 16
This error occurs at the end of a large block database operation (i.e., APPEND, JOIN, UPDATE or TOTAL
command) and when one of the database files used in the operation is no longer open. The suggested solution is to check the user defined function used within the erroneous statement for any statements that close the database files.
Internal errors 17, 18 and 19
These errors exist in both Clipper Summer ’87 and 5.x releases. They occur when an index has become corrupted at the time of attempting to update an index page. The suggested solution is to delete and re-create the index.
Unrecoverable error 22: Ntx file key type error
It is caused only if either a seek expression in an index file (i.e., .ntx file) evaluates to a logical or the system runs out of memory whenever evaluating the key expression.
Unrecoverable error 24: write error
The Clipper internal function that does file writes returns the number of bytes that were successfully written. If the number is less than expected, this error occurs. The most likely cause is lack of disk space. In other words, it is caused if the Clipper application is unable to write a database file or index file to the disk.
To avoid the incident of this type of internal error, make sure that either sufficient disk space and directory entries are available or the file is not marked read only. In a network environment, make sure the application has the necessary rights to write to the file.
Unrecoverable error 92: Sort/Index error
The system is unable to create a temporary file during a ‘sort’ or ‘index’ operation. It can happen only in one of the following situations
- No disk space.
- Disk is write-protected.
- No more directory entries.
- The file already exists and is read-only.
Unrecoverable error 331 and 332: string/array memory overflow
Clipper 5′s Release Notes Norton Guide (see Ref. 3) contains some cryptic notes about the Segmented Virtual Object Store (SVOS). Basically, it’s what Clipper uses to manage all of its strings, arrays, and code blocks. These two errors occur when the SVOS tables have overflowed, which is caused by the creation of large, nested arrays.
Unrecoverable error 349: too many extend locks
This error caused when an extend system function locks pointers to more than 16 parameters. Whenever someone uses _parc() to retrieve a pointer to a string in an extend system function, Clipper has to lock it in memory. A maximum of 16 parameters can be locked at a time.
To solve this, design the calling function so that fewer than 16 parameters need to be locked at a time, and call the _xunlock() function to free them. _xunlock(), which release all current locks, is described in Clipper 5.0l’s documentation, but it was omitted from the documentation in Clipper 5.2.
Unrecoverable error 415: cannot open overlay file
This error occurs when Clipper can not open its overlay file. Usually, The file in question is the executable one, but it can also be an external overlay or a prelinked library created with RTLink. The most common cause for this error is a shortage of file handles. Several errors occur due to a lack of file handles. The solution to this is to increase the number of available handles. There are three places where one could increase the file handle count:
- The F parameter in the Clipper environment variable.
- The CONFIG.SYS file.
- The network config file (provided the environment is attached with a network).
Unrecoverable error 416: read error on overlay file This error occurs when the overlay manager fails to read from the overlay file. Some possible causes:
- The file is no longer available. For example, a user can run a Clipper application from a floppy drive and then switch floppies.
- something has inadvertently closed the overlay file. Calling on an incorrect handle can cause this.
Unrecoverable error 520: Attempt to get value for an Invalid field type
This error occurs when a database (i.e., .DbfJ file is found to be corrupted, The solution is to fix the database. Unrecoverable error 650: processor stack fault
These error is caused when out of stack space is reached. The suggested solution is to use /STACK command to increase the stack space in the time of linking with RTLink. Internal error 666
This error occurs only when a C function has attempted to free an invalid pointer. The best bet is to check the application where the C function is being called.
Unrecoverable error 667, 668 and 669: eval stack fault
These errors are all related. Clipper uses two different stacks: the CPU stack and the Eval stack. The CPU stack holds local variables and parameters for C functions and can be controlled by using the /STACK command when the link is performed. The Eval stack is similar, but it is used to hold Clipper’s parameters and local variables. To understand the causes behind these errors and their possible solutions, one needs to understand how Clipper’s memory is organized. Most programming languages store local data in an area of memory called DGROUP, which is limited to 64K. In Clipper, this area contains:
- C static data
- The CPU stack
- The Eval stack Clipper static data
After the C static data, one has the CPU stack, which grows downward. Next is the Eval stack, which grows upward. Finally, there is the Clipper static area that starts at the end of DGROUP and grows downward. These errors occur when one of the expandable areas tries to grow into the space of one of the others.
Specifically, the errors occur under the following circumstances:
650 The CPU stack has overflowed.
667 The Eval stack has bumped into the Clipper static area.
668 The Eval stack has bumped into a locked
669 Virtual Memory (VM, in short) segment in the space between the Eval stack and the Clipper static area. The Clipper static area has bumped into a locked VM segment in the space between itself and the Eval stack.
Generally, problems that cause one of these errors could cause any of them, which is why we have listed them together.
Stack fault errors have several possible causes:
- Unintended or too deep recursion. If a function is called recursively, one of the stacks may run out of space. The most common cause for unintended recursion is an error in an error handler.
- Too much C static data. If someone has his own extend system code, the static data goes to the C static’s area by default. If the program uses too much static data, one of the other areas may run short of space. Third party libraries can also be guilty of this. Later versions of C compilers allow one to specify a data threshold that permits one to move some of this data elsewhere.
- Too large a CPU stack. Clipper defaults to a 4k CPU stack, which is sufficient in most cases. However, some third-party libraries cause additional stack space to be allocated. In addition, the user can control the size with the STACKS command to the linker or with the Blinker’s BLINKER PROCEDURE DEPTH command. To find out how much stack space the user has allocated, generate a map file and examine the size of the segment STACK. If it is too large, explicitly limit it with a link option.
- Too many static variables. Each static variable that is created requires 14 bytes in the Clipper static area. If one has quite a few, it adds up. Storing multiple values in a static array can help alleviate this problem because the 14-byte entry is used for the entire array.
- Too many ITEMs. ITEMs created with the ITEM API in Clipper 5.2 also go in the Clipper static’s area. Every item created must be released, and failing to do so may cause one of the Eval stack faults as the static’s area increases.
- Too large a load size. Normally, the area between the Eval stack and the Clipper static’s area is unoccupied, but in low memory conditions, VM segments can get swapped there. If these segments are there and locked, errors 668 and 669 can occur. Generally, reducing load size can help alleviate the problem.
Unrecoverable error 670: memory initialization error
This error is occurred during the initialization or reinitialization of the memory system. It, in fact, indicates an extremely low memory condition at startup, or that an application using RUN command from within the Clipper allocated DOS memory without freeing it.
The suggested solution is to make more conventional memory available for the application if it is caused at startup time. If it is happened immediately following the RUN command, the application that was run should be eliminated to solve the problem. This error also occurs with an improperly linked or corrupted application.
Internal Error 999
Internal error 999 occurs when Clipper tries to call an internal function that was not linked in. This error can be caused by one of two actions. One is a bad incremental link. If deleting and re-creating the executable corrects the error, this was probably the cause. The other is calling a Clipper function indirectly, usually through a macro, and not referring to it explicitly. The solution is to add an EXTERNAL declaration for it so that the linker will include it.
Internal error 1210
This error occurs when a record is not found in an index. Typically, it is caused when a file is updated and the index is not open, In the original release of Clipper 5.2, there was a bug that caused this error to appear even though the record was there.
Internal error 4424: Temporary file creation error
Error 4424 is caused by a failure when creating a temporary file for indexing or sorting. It is generally caused by either not enough file handles or invalid TEMPPATH setting for Clipper environment or a lack of file creation rights on a network for the directory where the temporary flies are created. Notice that temporary flies are created in the current directory if no TEMPPATH is specified.
The appropriate solution is to correct the environment. If there are not enough file handles, the solution is similar to that of error 415. If insufficient network rights is the problem, either give the user the necessary rights or redirects the temporary file to a more appropriate directory.
Unrecoverable error 5311: Unable to create VM swap file
This error is caused when the VM subsystem is unable to create a VM swap file on the disk. It is generally caused for several reasons, which includes
- The target disk or directory is full. Insufficient file handles are available.
- An invalid path is specified in the SWAPPATH parameter of the Clipper environment variables or on the command line used to start the application.
The user has not enough rights on a network drive to create the swap file.
It, in fact, indicates that the Clipper application no longer has sufficient VM available to proceed. Specifically, this error occurs whenever the VM system needs to swap a VM segment out of conventional memory, and it has used all expanded memory and disk space that has been made available to it.
The suggested solution is that provide more VM available to the application. This can be don either by providing more expanded memory available with the aid of increasing the value of the E setting of the Clipper environment variable, or by providing more disk spaces available with the aid of increasing the SWAPK setting of the Clipper environment variable.
The problem caused by this error can also be resolved by reducing the size and/or number of strings and arrays that are active at anyone time. Probably, the most common cause of this error is the declaration of extremely large arrays, (for explanation, we refer to Ref.3).
Unrecoverable error 5300: not enough memory
This error happens when there is not enough conventional memory and the VM system can not initialize. The solution is to make more memory available. Unrecoverable error 5302, 5304 5305, 5306: conventional memory exhausted
These errors are caused by a lack of conventional memory at various places in the VM system. Specifically, 5302, 5305 and 5306 occur when a VM segment can not be swapped in. When an attempt to allocate fixed memory with _xgrab() or an internal function fails, error 5304 occurs. The solution in all cases is to make more memory available, either by decreasing load size, increasing available conventional memory, or decreasing the amount of memory that is locked at any one time. Another solution is to move the application to protected mode.
Unrecoverable error 5312: VM swap file over allocated
Error 5312 occurs when Clipper’s VM swap file becomes full and has no more space to receive swapped items. This occurs when the size of the swap file is limited by using the SWAPK setting of the Clipper environment variable.
Unrecoverable error 5313: out of space for VM swap file
This occurs when the VM swap file can not be expanded. Typically, it means you are out of disk space. It is similar to error 24 but it occurs specifically in the VM system.
Internal error 5320 and 5321:
These errors occur if there is a problem reading or writing to EMS. Try using the BADCACHE setting in the Clipper environment verbal. If that does network, try to eliminate Clipper’s usage of EMS by setting the E parameter of the Clipper environment variable to zero.
Internal Error 5333:
Colloquially named the internal error from hell, it was renamed in Clipper 5.2 to “VM Integrity Failure”. It is probably the single most misunderstood Clipper internal error. It happens when the VM system is instructed to swap in a VM segment but the segment is empty. The vast majority of the time, this error has nothing to do with the VM system itself, but rather indicates a bug in another system that is either using the VM system incorrectly or trashing memory. Unfortunately, there is no easy way to track these errors down. However, moving the application to the protected mode in many cases makes these errors go away and in other cases, it identifies the problem with a general protection fault.
We conclude that the existing version of Clipper has major drawbacks because of its unexplained Internal Errors. It has been seen that is not a complete listing but it includes the most common internal errors and these that frequently occur in the development cycle.. We investigated the cause for each one of the errors included in our set. We believe this will definitely help every Clipper developer while they are in their development stage.
Finally, we strongly wish for a better error handler to be incorporated into the future Clipper 5.3 release by refining and reducing its drawbacks.
1. CA-Clipper: Error Message and Appendices Guide for DOS, Version 5.2, Computer Associates, 1992.
2. CA-Clipper : Programming and Utilities Guide for DOS, Version 5.2, Computer Associates, 1992.
3. CA-Clipper 5.2 : Internal Error Listing, Databases for Norton Guide, Computer Associates, 1992.
4. Key, S., “25 Internal Errors I’ve Witnessed”, Clipper Reference, pp. 9-11, December 1993.
It is great pleasure to thank Greg Mezo, who helped me with all aspects of my investigation and research.