PreviousSystem Limits and Programming Restrictions Portability IssuesNext"

Chapter 4: Handling Protection Violation Errors

This chapter explains how your programs can produce illegal code and describes how you can identify and fix such errors as and when they occur. After reading this chapter you will be familiar with the different types of protection violation you could encounter when using this COBOL system, as well as being able to identify and eliminate these protection violations.

4.1 Overview

This COBOL system very thorough in preventing or trapping potentially illegal code. However, it is still possible for your programs to generate code that is illegal in some way, and when this happens the error might be trapped as a general protection violation by the operating system or a COBOL protection violation by this COBOL system.

4.2 What are Protection Violations?

This section briefly describes the causes of protection violations, then discusses some possible causes of the following types of protection violation, as well as describing how these protection violations are handled:

A protection violation occurs when a machine instruction tries to execute and is found to be illegal in the context of the currently running process. This might be because the instruction is not recognized by the processor (as is the case if data is executed as if it were a procedure), or if a valid instruction references a memory location or other resource that is invalid in the context of the currently running process.

The operating system determines the context for general protection violations and this COBOL system determines the context for COBOL protection violations. A general protection error is an error caught by the operating system. A COBOL protection error is an error caught by the COBOL system, although the error might be trapped when running a non-COBOL program.

4.2.1 General Protection Violations

Operating systems typically allocate only a portion of a computer's resources to each process and monitor each process to see that it does not exceed its allocation. If the operating system detects a process exceeding its allocation, it takes some error action. The action it takes is a general protection violation (also known as an exception) or some other action, depending on the operating system.

When the operating system detects a general protection violation, it runs a special program called an exception handler before abandoning the process that caused the exception. The exception handler might be one specifically associated with the program that caused the exception. Alternatively, if there is no specific handler, the operating system runs its own default exception handler.

This COBOL system provides a COBOL exception handler for 32-bit systems on Windows NT, OS/2 and UNIX, and for 16-bit COBOL systems for Windows and OS/2. See the section COBOL Protection Violations below for information on COBOL protection violations.

4.2.2 COBOL Protection Violations

Some operating systems are less vigilant than others in trapping protection violations. Where appropriate, this COBOL system provides facilities to monitor a COBOL application (or non-COBOL program running under the control of the COBOL system) to ensure that it does not exceed the resources allocated to it by the COBOL system. A COBOL protection violation occurs when your COBOL system sees a program behaving in this way.

Whether the COBOL system detects a protection violation depends on which resources are monitored, how they are monitored, and how the resources are allocated. The hardware and operating system determine how effectively the COBOL system can monitor COBOL protection violations. A COBOL program might appear to run correctly in one environment, but might fail if available resources change or the operating system changes.

If a COBOL program causes a protection violation, the information provided about the failure and the tools available to supplement this information varies between operating systems. For this reason, if you find difficulty debugging a failing program in one environment you should consider debugging it under an environment that might provide more information.

4.3 Typical Effects of Protection Violations

This section describes the behavior that accompanies a protection violation on each environment. It splits the behavior into two categories:

4.3.1 Error Handling

32-bit:
Windows NT and OS/2 do not display any message indicating a protection violation, but both operating systems do trap protection violations. A general protection violation under Windows NT and OS/2 gives run-time system (RTS) error 114 ("Attempt to access item beyond bounds of memory").

UNIX traps general protection violations, enabling the run-time system to give RTS error 114 ("Attempt to access item beyond bounds of memory") or RTS error 115 ("Unexpected signal") depending on the type of trapped protection violation.

16-bit:
On the 16-bit COBOL system using DOS (with XM), Windows or OS/2, a general protection violation results in RTS error 114 ("Attempt to access item beyond bounds of memory").

4.3.2 Related Behavior

Protection violations typically occur when a process tries to access a memory location that lies outside the memory allocated to that process for the type of access it is attempting. Clearly the process miscalculated the location it wants to access.

However, if the same process moves, is rearranged in memory, or grows in size, the memory location might eventually lie in the range of the process. In such a case, the process would not give rise to a protection violation even though we would like it to. If this is the case:

4.4 Correcting Protection Violations

This section presents some of the common causes of protection violations (and RTS errors associated with COBOL protection violations) and suggests how you can overcome these problems. The following are all problems that can cause protection violations or RTS errors:

The following sections describe each of these problems and how to overcome them.

4.4.1 Errors in Non-COBOL Portions of an Application

Because of the success of this COBOL system at detecting COBOL protection violations, it is uncommon for COBOL applications to result in general protection violations. In contrast, other programming languages, such as C, typically make heavy use of pointers which increase the probability of causing general protection violations.

If your application fails with a general protection violation and contains a part that is written in a language other than COBOL, we recommend that you closely investigate the part of the application that is not written in COBOL. In most cases, that is where the general protection violation is caused.

4.4.2 Parameter Mismatches in a CALL Statement

The CALL statement provides a number of areas where general protection violations can occur if you make a mistake in specifying the call.

The following are things you should check if you suspect that a CALL statement might be causing a general protection violation:

These factors become more difficult to manage when one of the calling or called programs is not COBOL. As a result, protection violations are more likely in such applications. You must ensure that the non-COBOL language conforms with the default calling convention for COBOL, or COBOL conforms to the calling convention of the non-COBOL language (by using the CALL-CONVENTION clause). See the chapter The COBOL Interfacing Environment for more information on the CALL-CONVENTION clause.

The effects of a mismatch in the calling interface between two programs can be extremely varied depending on the interaction between the mismatch in question and the calling conventions used.

4.4.3 Stack Overflow

A less obvious cause for a general protection violation is stack overflow. The stack is the system area in which called parameters and the calling program return address are temporarily stored for a CALL statement. Stack overflow occurs when the level of nesting of called subprograms, or the size or number of passed parameters is greater than the stack can manage.

Stack overflow can occur due to excessive use of the stack, or because the default or requested stack size is small. You should bear in mind that operating system support routines might also make use of the stack and reduce its effective size, and that different versions of the same operating system can make different use of the stack, thus varying its effective size.

If one of your programs causes a general protection violation when you run it on a different version of an operating system, you should consider increasing the default stack size. Use the /stack linker option for Windows NT or the /ST linker option for OS/2 to change the size of the stack. See the chapter on linking in your Object COBOL User Guide for more information on the /stack and /ST linker options.

Stack overflow is very rarely a problem on UNIX environments. If you suspect you need to change the size of your stack on UNIX, see your UNIX system documentation for details of if and how you can do this.

4.4.4 Illegal Reference Modification

Using reference modification you can easily reference an area of memory that lies outside the named data item. The results of illegal reference modification depend on the location of the area of memory that your program accesses:

Example

In the following example, the reference modification results in RTS error 114 ("Attempt to access item beyond bounds of memory") when run. This is caused by setting a to be greater than the maximum length of b. The first use of a reference modified item is a source field, so results in incorrect data being passed into c. This problem is detected by this COBOL system.

The second use of a reference modified item is potentially more dangerous, as the reference modified item is a target field. Again, this COBOL system detects this problem and produces RTS error 114 ("Attempt to access item beyond bounds of memory").

This example is used in the following sections to illustrate how to debug the program in various environments.

 program-id. "buggy".
 working-storage section.
 01 a   pic 9(6).
 procedure division.
     move 999999 to a
     call "bug" using a
     stop run.
 end program "buggy".
 program-id. "bug".
 working-storage section.
 01 b        pic x(20).
 01 c        pic x.
 linkage section.
 01 a    pic 9(6).
 procedure division using a.
     move b(a:1) to c
     move "1" to b(a:1)
     exit program.

4.4.5 Illegal Values for Pointers

Data items that you define with usage POINTER or PROCEDURE-POINTER must contain valid addresses when they are used. Using a pointer that does not contain a valid address results in RTS error 114 ("Attempt to access item beyond bounds of memory"), because this COBOL system traps the error that would otherwise result in a general protection violation.

Example

In the following example, data item undefined-pointer is defined as a pointer to a procedure, but is not given a value before it is used. As a result, the CALL statement fails, giving RTS error 114 ("Attempt to access item beyond bounds of memory").

 working-storage section.
 01 undefined-pointer    usage procedure-pointer.
 procedure division.
     call undefined-pointer
     stop run.
         

4.4.6 Subscript Out of Range

The values of subscripts and index items are checked by this COBOL system, with an RTS error 153 ("Subscript out of range") given if they are found to be out of range. However, checking subscripts and index items decreases the performance of your application to some extent. To avoid this decrease in performance you can use the NOBOUND directive to disable such checking. If the NOBOUND directive is used and a subscript or index item is out of range when referencing a table, a protection violation might occur.

If you get unexpected results or a protection violation error in an application that has been compiled or generated with the NOBOUND directive, you should recompile the program without the directive and rerun it to determine if the fault is caused by a subscript error.

Example

The following programs show how you could experience unexpected results as a result of inadvertently using an out of range subscript when the NOBOUND directive is specified. Because of the value passed from Bound-main, Build-sub moves "1" to the 21st element of an array that is only 20 elements in size. Because the NOBOUND directive is specified, this COBOL system permits this operation, which overwrites the next data item, c. If the NOBOUND directive was not set, the COBOL system would have given RTS error 153 ("Subscript out of range") when the MOVE was performed.

 program-id. "bound-main".
 working-storage section.
 01 a   pic 99.
 procedure division.
     move 21 to a
     call "bound-sub" using a
     stop run.
 end program "bound-main".

$set align(2) nobound
 program-id. "bound-sub".
 working-storage section.
 01 b    pic x occurs 20.
 01 c    pic xx.
 linkage section.
 01 a    pic 99.
 procedure division using a.
     move (1) to b(a)
     exit program.

4.4.7 Incorrect Linking Options or Procedures

There are a number of linking options that if used incorrectly might indirectly cause a general protection violation. Problems commonly occur when either the wrong objects or libraries are linked, or the correct objects or libraries are used, but incorrect versions of them.

If you suspect that this might be the case, you should check that old versions of objects or libraries have not been left in search paths and that new versions have been installed correctly. See the chapter on linking in your Object COBOL User Guide for information on linking with this COBOL system.

4.5 Debugging Techniques

This section describes the techniques you use to debug an application when you encounter a protection violation or an RTS error mentioned in this chapter. It covers working with both intermediate and generated code.

The techniques you use to debug a program depend on how the program is loaded or built. For example, if a program is built as an operating system executable file (such as an .exe, a .dll, or a .dlw file) the operating system loads the program and uses special privileges to partition memory for different usages and trap inappropriate references. For example it might split data and procedures and trap attempts to execute data or write over procedure code.

When you run a program as an .int or .gnt file, the operating system loads the run-time system, and the run-time system dynamically loads your COBOL program. In general, the run-time system cannot use the operating system's special privileges to load the COBOL program into protected areas. Instead, where appropriate, the COBOL system sets up its own COBOL traps in conjunction with the operating system general protection violation traps.

4.5.1 Debugging Intermediate Code Programs

When you run a program as intermediate (.int) code and the COBOL system traps a protection violation, the run-time system gives an RTS error and identifies the program in which the error occurred. The run-time system also gives a reference to the COBOL source line which caused the failure. See the chapter Run-time System Messages in your Error Messages for more information on the possible error messages reported by the run-time system.

In order to identify the COBOL source line from the reference you must compile the source with the Compiler directives LIST() and REF. Each source line then has a reference at the extreme right of the listing which identifies the starting location for the procedure for each statement. See the chapter on compiler directives in your Object COBOL User Guide for information on the LIST and REF directives.

Example

The following listing shows the listing information from the file created when compiling the example programs Buggy and Bug. The listing file produced contains more information than is shown here, but has been edited to make viewing this information easier.

 1 program-id. "buggy".         0
 2 working-storage section.     160
 3 01 a pic 9(6).               160
 4 procedure division.          0
 5     move 999999 to a         29
 6     call "bug" using a       33
 7     stop run.                3D
 8     end program "buggy".     3E
 9                              47
10 program-id. "bug".           47
11 working-storage section.     160
12 01 b pic x(20).              160
13 01 c pic x.                  178
14 linkage section.             17C
15 01 a pic 9(6).               0
16 procedure division using a.  0
17     move "1" to b(a:1)       29
18     exit program.            30
19                              31

An alternative method to using the LIST () and REF directives is to animate the program using Animator V2. Use the Animator V2's Run operation to execute your program at full speed to the location that causes the protection violation. At this point, RTS error 114 ("Attempt to access item beyond bounds of memory") is issued, and Animator V2 regains control on the line of source that caused the protection violation.

For more information on running a program using Animator V2, see the Object COBOL User Guide for DOS, Windows and OS/2, and see the Object COBOL Character Tools for UNIX.

4.5.2 Debugging Generated Code Programs

When you run a program as generated code and the COBOL system traps a protection violation, the run-time system gives an RTS error and identifies the program in which the error occurred, together with a reference to the native code instruction that caused the error. The run-time system also gives a reference to the COBOL source line which caused the failure. See the chapter Run-time System Messages in your Error Messages for more information on the possible error messages reported by the run-time system.

To match the native code instruction reference to the COBOL source line which caused the error, you need to compile with additional Compiler directives. On the 16-bit COBOL system, you should specify SOURCEASM and ASMLIST, while on a 32-bit COBOL system you should specify SOURCEASM, ASMLIST and ASM. Specifying these directives causes the Compiler to create a .grp file which contains an assembler listing for your program, showing the relationship between COBOL program lines and native instructions. For more information on these directives see the chapter on compiler directives in your Object COBOL User Guide.

32-bit:
To eliminate an RTS error in generated code on a 32-bit COBOL system for Windows NT or OS/2 use Animator V2. You can use the Run operation to run the program until the error occurs, and when control is passed back to Animator V2 you can identify the line causing the error. For more information on using Animator V2 to animate generated code, see your Object COBOL User Guide for DOS, Windows and OS/2, and see the Object COBOL Character Tools for UNIX.

4.6 Debugging Examples

This section shows some examples of how you should debug COBOL programs you have found to contain protection violations (regardless of whether or not the COBOL system traps them and gives an RTS error). It gives examples for Windows NT, OS/2, and UNIX.

4.6.1 Windows NT and OS/2 Example

When a COBOL program encounters a protection violation under Windows NT or OS/2, it returns RTS error 114 ("Attempt to access item beyond bounds of memory") for the COBOL statement in which the fault occurred.

You can use Animator V2 to discover the statement that causes the error. If you are using the 16-bit COBOL system you can use Animator V2 on intermediate code. If you are using a 32-bit COBOL system for Windows NT or OS/2, you can use Animator V2 on either intermediate or generated code. Typical commands to animate genreated code for the example program Buggy are as follows:

cobol buggy nognt;
cobol bug.int noanim;
set cobanim_2=animate
anim2 buggy

For more information on animating programs, see the chapter Executing Your Applications Using Animator V2 in your Object COBOL User Guide. For information on debugging generated code, see the section Debugging Generated Code in the chapter Executing Your Applications Using Animator V2 in your Object COBOL User Guide.

4.6.2 UNIX Example

When a program encounters a protection violation under UNIX, it returns either RTS error 114 ("Attempt to access item beyond bounds of memory") or RTS error 115 ("Unexpected signal"), depending on the type of protection violation. A typical RTS error display is shown below.

Execution error : file 'bug.int'
error code: 114, pc=29, call=2, seg=0
114 Attempt to access item beyond bounds of memory (Signal 11)

This error corresponds to the following segment of the report listing, which was generated by compiling bug.cbl with the LIST() and REF directives specified.

 1 program-id. "bug".          0
 2 working-storage section.    160
 3 01 b pic x(20).             160
 4 01 c pic x.                 178
 5 linkage section.            17C
 6 01 a pic 9(6).              0
 7 procedure division using a. 0
 8     move "1" to b(a:1)      29
 9     exit program.           30

If the program is in intermediate code format, you can use Animator's Zoom function to run the program and identify the source where the protection violation occurs.

If the program is in generated code format, you can still use Animator to animate it. Typical commands to animate generated code for the example program Buggy under the Bourne shell on an Intel-based machine are as follows:

cob -G buggy.cbl
cob -Gu bug.int
rm bug.int
COBANIM_2=animate
export COBANIM_2
anim buggy

For more information on using Animator to debug your programs, see your Object COBOL Character Tools.


Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousSystem Limits and Programming Restrictions Portability IssuesNext"