The following information on the CA-Clipper 5.2b patch was extrated from 52abi.txt which came with the patch. This is an important patch as it fixes 28 known bugs !!!
The problems resolved by CA-Clipper 5.2b include:
1. Fixed a Virtual Memory Integrity Failure in FOPEN() when the file name is numeric instead of a character string.
2. Fixed a Virtual Memory Integrity Failure when calling AADD() to increase the size of an array.
3. Fixed a Virtual Memory Integerity Failure that occured when an ACHOICE() user function deleted elements from the menu selection array. ACHOICE() now allows the user function to add, delete, or modify existing elements without causing any problems in ACHOICE().
4. Fixed a Virtual Memory Integrity Failure in the Internal Runtime Event System. This was causing the DBFCDX driver to hang as well as various "unexplainable" errors.
5. Fixed a Virtual Memory Integrity Failure in the debugger when viewing multiple nested arrays. Tbrowse was producing a parameter error when viewing multiple nested arrays. In some instances this produced a Virtual Memory Integrity Failure.
6. Fixed a Virtual Memory Integrity Failure in the debugger's memory allocator. (STAR Issue# 737689)
7. Fixed INDEXKEY() memory corruption problem. INDEXKEY() would occasionally return a garbage string when called repeatedly. This sometimes caused a Virtual Memory Integrity Failure.
8. Fixed MEMOEDIT() buffer memory corruption problem. This occurred when MEMOEDIT() was called with a user defined function. This would result in various memory related errors including a Virtual Memory Integrity Failure.
9. Fixed slow disk I/O on replaces on large DBF's with non-unique indexes. The performance has been improved to a speed which is comparable to CA-Clipper 5.01a.
10. Fixed the releasing of all relations (in all workareas) when any child dbf was closed. Now closing a child database releases only the relations that it is involved with.
11. Fixed the DBFNDX Replaceable Database Driver so that it now properly seeks on a date value with SET DELETED ON.
12. Fixed DBCREATE() to properly return a NIL value as documented.
13. Fixed INDEXORD() so that it now returns a zero when no database is open rather than generating a runtime error.
14. Fixed some occurances of internal error 1210 (database and index are out of sync).
15. Fixed many occurances of internal error 415 (can not open external overlay file).
16. Fixed the Runtime Memory Manager so that it now returns an EG_MEM (5300 "Memory Low Warning") before generating a memory exhausted error.
17. Fixed Runtime failures that occured when CA-Clipper mistakenly tried to use non-existent EMS memory.
18. Fixed FREAD() so that it does not modify variables that it shouldn't have access to.
19. Fixed BROWSE() so that it no longer causes the repositioning of a file to BOF() when editing takes place in a new record.
20. Fixed the debugger so that it is no longer necessary to specify the default file extension (.PRG or .PPO) when opening a file.
21. Fixed the debugger so that it correctly searches the path (indicated by the PATH environment variable) when searching for a file to open.
22. Fixed the debugger so that it does not produce "Argument error +" when the F6 key is pressed to view databases.
23. Fixed DBU so it now correctly parses a file name that contained a drive letter and colon (:) but no backslash (\) (such as C:TEMP).
24. Fixed numerous bugs in the R.L. utility.
25. Fixed the compiler screen to include the missing /t and /z options in order to match the documented options.
26. Fixed the spelling of OrdDestory to OrdDestroy in STD.CH for the DELETE TAG command.
27. Fixed the "Guide to CA-Clipper" .NG file so that the Norton Guide engine may now be unloaded from memory.
28. Enhanced the //INFO command line parameter to show what message and collation driver is linked in.
Technical Note: The Virtual Memory Integrity Failure Error Message
The Virtual Memory Integrity Failure error message (or VMIF for short) refers to a problem that is neither well documented nor well understood. In this technical note, we will explore what the VMIF message indicates, some of the common reasons it occurs, and what measures to take if you encounter one.
CA-Clipper uses a virtual memory manager to allow applications to access more strings, arrays, and objects than conventional memory would otherwise allow. It accomplishes this by swapping information to and from expanded memory or disk as needed. Each virtual data item (called a segment) has an entry in a descriptor table that maintains its current location and length. A segment's length can be up to 65,518 bytes, while its location may be conventional memory (resident), disk or EMS (non-resident). When CA-Clipper receives a request for non-resident data, it always checks the segment's descriptor entry to ensure that it's length is non-zero. Any descriptor whose length is zero is, by definition, invalid because VM does not allow zero-byte segments. Thus, a zero length segment is interpreted as a corruption, and the VMIF error message is displayed.
Along with the VMIF message is a hexadecimal address that indicates the address of the corrupted descriptor table element. This information may be useful to the CA-Clipper Technical Support as well as the development staff. C and Assembler programmers may also find this information useful in determining if and how their code caused the corruption. A special case is the address 0000:0000. It indicates that a NULL and (possibly uninitialized) pointer was used to access virtual data.
While it is true that the VMIF message occurs for exactly one condition, that condition can be created in many different ways. Research indicates that the conditions that lead to a VMIF can be broken down into three distinct categories.
First, several VMIFs can be attributed to Clipper programming bugs. While a VMIF should never occur solely on the basis of executing Clipper code, a combination of inadequate error detection on the part of Clipper runtime and a violation of proper programming practices may cause the error to occur. Examples of this have been: calling FOPEN() with numeric data for the file name, deleting array elements from within an ACHOICE() UDF, and assigning NIL to any TBROWSE instance variable that requires a character value. (Please note that the TBROWSE VMIFs were fixed in the 5.01a release and the ACHOICE() and FOPEN() VMIFs are fixed in the 5.2b release by producing an error when improper values are used.)
The second category is within the CA-Clipper runtime support libraries. CA-Clipper's runtime support libraries constantly issue calls to the VM system throughout the normal execution of a Clipper application. On occasion, specific conditions pertaining to runtime activities are not properly handled internally, creating conditions that eventually result in a VMIF. These instances are always considered problems by the development staff.
The last category is external code typically written in C or Assembler by CA-Clipper programmers and third party library developers. These are usually caused by improper use of one of CA-Clipper's APIs or by changing the functionality of something within CA-Clipper's runtime that is assumed to remain constant.
Although CA-Clipper's VM system provides detection and reporting, it is almost never the cause of a VMIF.
VMIFs are commonly detected long after the actual corruption occurred. A module may store a zero-length segment in the segment descriptor table either through use of VM or by writing to a wild pointer. This corruption will not be detected until a VM segment is accessed that requires the corrupted segment to be discarded, or swapped to disk or EMS. The Clipper VM subsystem is demand-based. This means that it only performs swapping when swapping is absolutely required. If a VMIF consistently occurs at a specific point in the execution of an application, it is often not actually caused at this point. It tells us that a corruption has occurred, but has no means for determining the cause of the corruption or when the corruption actually occurred.
Because VMIFs are detected when the VM system attempts to swap in memory, a change in the amount of conventional memory available when an application is executed changes the possibility of the VMIF occurring. When sufficient real memory is available, VM has no need to perform any swapping and any possible VMIFs will not be detected. When less real memory is available to an application, the entire profile of swapping is changed, and may prevent the VMIF from occurring in a constant location.
This raises the question of how to ensure that the VM system is being called during the testing phase of application development. A simple and effective method is to use CA-Clipper's //X: parameter to decrease the available memory as much as is feasible. This will ensure that the VM system will be called with the most frequency. (The //X: parameter is detailed in the Runtime Environment chapter of the CA-Clipper 5.2 Programming and Utilities Guide.)
If a VMIF occurs, try to determine how to reproduce the problem at will and if possible, isolate it to a small example and immediately contact your CA-Clipper Technical Support Representative. The CA-Clipper Quality Assurance team is also constantly searching for occurrences of VMIFs. Either way, the CA-Clipper Development team is anxious to correct all internal VMIFs as quickly as possible.