Static Corruptions

Static corruptions are typically caused by invalid pointer arithmetic, uninitialized pointers, or differences in parameter passing between z/OS and distributed platforms. Three common types of static corruptions are:

Corruption of static variable contents
Corrupted static variable contents can typically be found by monitoring variable contents for change when executing in the debugger, and stopping at the point it occurs. Things to look for when trying to identify the cause are array bounds being exceeded, string lengths being manipulated without the use of PL/I built-in functions, etc. To determine the potential for exceeding array bounds, you can look at a compile listing generated with the -map directive.

To diagnose corruption of static variable contents during the debugging phase, compile the application code using -prefix stringrange,subscriptrange. This injects additional code that attempts to detect overwrites and raise appropriate conditions.

Note: We do not recommend that you compile with -prefix stringrange,subscriptrange for production applications because this can significantly degrade performance.

Diagnosing when the descriptor for a PL/I variable has been corrupted unintentionally can be difficult. PL/I variables such as structures, CONTROLLED variables, etc. cause the compiler to create hidden internal structures that describe several items such as the layout of the variable, how many generations of a CONTROLLED variable exist, current generation statistics, etc. If the code unintentionally corrupts one of these internal data structures, errors such as an unexpected SIGSEGV when accessing a built-in function, or an abend in a called procedure that relies upon the descriptor for processing can occur. As an advanced technique, use the -map and -exp options of the compiler listing to work out where the descriptors reside, and then either inject new code to monitor the descriptor(s) for changes or to identify what has possibly caused the corruption.

Corruption of descriptors
When a non-scalar variable is declared, such as a data structure or an array of scalar items, a descriptor is created. Corruption of descriptors related to a data structure or other items embedded in static storage can occur.

A descriptor is a hidden data structure embedded within the generated code. It describes the layout of the structure, the number of array elements, etc. used when calling subroutines or built-in functions, thus providing the shape and size of the data being passed. The descriptor does not show up on the ENTRY declaration, but it is an item passed as part of the calling convention for non-scalar items, and for arrays of scalar items. It is also passed for things like variables declared with CHAR(*).

Accessing a STATIC EXTERNAL data item that was not compiled with -defext
In this scenario, a program has declared a STATIC EXTERNAL variable and accessed it in exactly one place within the application; however, the program was not compiled with -defext PL/I compiler option. In this case the storage for the variable is not allocated, and is therefore pointing to a random location within the application because the linker was unable to generate the relocation information at link time. Any attempt to modify this variable causes a random part of static storage to be corrupted.