The runtime fails with a "Memory alignment error". How can this be resolved?
A "Memory alignment error" occurs in response to a Bus Error signal. This signal is generated on some UNIX machines (but not all) when a multi-byte data item is accessed on an inappropriate memory boundary. These machines require that integers and long data items be aligned on a certain byte boundary and involves how the CPU fetches data and the optimizations present in the machine's instruction set. For example, if a program accesses a 4-byte long data item that is not aligned on a memory address that is divisible by 4, a memory alignment error would occur.
Data correctly aligned:
data 1 = a|a|a|a|
data 2 = b|b|b|b|
(data 2 doesn't begin at the start of the 4-byte address)
data 1 = a|a|b|b|
data 2 = b|b| | |
COMPILE SWITCHES TO USE
The most common solution to memory alignment errors is to synchronize data items by compiling all programs with these three switches:
* Dw32 or -Dw64 (modifies the size of some data types based on the maximum word size specified (32-bit or 64-bit))
* Da4 or -Da8 (specifies that data should be aligned on quad-byte or octal- byte boundaries)
* Dl# (specifies a maximum boundary to the alignment modulus used for SYNCHRONIZED data items
Other compile switches which have been used to correct the alignment error:
* Dy treats all binary data items as if they were SYCHRONIZED. D5 treats BINARY data items as COMP-5 data items.
* D6 treats unsigned, PACKED-DECIMAL, data items as COMP-6.
* Dm changes the binary data item storage size.
* Df changes all COMP-1 data to FLOAT and COMP-2 data to DOUBLE.
OTHER POSSIBLE CAUSES AND SOLUTIONS
-Cr compile option:
Often, it has been found that compiling without the -Cr causes the memory alignment errors to disappear. RM-compatibility causes COMP data items to be treated as "COMP-2" items (unpacked decimal). This is RM/COBOL's normal meaning of COMP (although RM has switches to imply other formats). This can be worked around by adding "-D2" to the compile line. Note, however, that this change causes all COMP items to be treated as COMP-4, so this could affect compatibility with existing data.
If this problem is happening with a relinked runtime on a Solaris machine, it is interesting to note that one customer resolved a memory alignment problem by rebuilding the runtime with this switch, "-xmemalign=8i", which was found in the manual of Forte C (Standard C compiler for Solaris). The cc line in that makefile was "CC = cc -xarch=v9 -xmemalign=8i"
REDEFINES items can often cause problems; a closer look at those may be warranted.
The development team recommends using COMP-5 data types for numbers to help avoid memory alignment errors.
Debug in 'C' compiler
One way to find a memory alignment error is to compile for debugging and run under a 'C' debugger with the runtime's "-z" switch. "-Z" turns off our signal-catching routines. When bad things happen (such as segmentation violation or bus error), then the -z switch causes the runtime to dump the core instead of shutting down nicely. It allows 'C'-style debuggers to trap what is going on. When the error occurs, the debugger should pick up the bus error signal and point to the offending code.
Sometimes, a memory alignment error occurs on a table (array) that contains a referencing error. To find these errors, compile with a -Za, which will detect them. Be sure to recompile them without -Za for production as this switch adversely affects performance.
CHECK-USING configuration variable
There can be a linkage error causing the memory alignment error if CHECK-USING is turned off. Check configuration variables to make sure this option is either not specified, or set to the default value of 1.
Broken Data File
Although very rare, this type of error may be returned if a file is broken. Use the command 'vutil -check' on vision files to see if they are broken.
Occasionally in our busy lives we forget to specify the correct type of transfer (ASCII or Binary) when FTP'ing files. These incorrectly-transferred files may cause a memory alignment error.