PreviousRequirements-based Vocabulary Compiling and Shipping OO ApplicationsNext

Chapter 14: Debugging Object COBOL Applications

This chapter provides some information to help you debug Object COBOL applications.

14.1 Overview

Many of the same tools and techniques used for debugging COBOL applications are applicable to OO Object COBOL applications. You can animate the classes in an application in the same way that you can animate any COBOL program.

There are also some extra facilities to help you with some debugging problems which are unique to OO programs.

14.2 Debugging Facilities

Object COBOL comes with the following facilities for debugging OO applications:

These facilities are explained in the following sections.

14.2.1 Animating your Applications

You can animate your Object COBOL classes using Animator. When you query an object reference, the Animator displays the object handle contained in the object reference. This enables you to see whether object references are pointing to the same or different objects. An object handle with value x"0000" always refers to the NilObject. An object handle with the value of x"20202020" is reserved by the RTS. Sending messages to it gives the error message "Invalid object reference".

14.2.2 Preventing Reallocation of Object Handles

The run-time system has a debugging option to prevent reallocation of object handles. The default behavior of the run-time system is to reuse the object handle for any object which has been finalized.

An application which sends messages to object handles after the object referenced has been finalized can cause unpredictable behavior. The message may be sent to a new object which has been allocated the old handle.

If the message sent is one the new object does not understand, then the "doesNotUnderstand" exception is raised, alerting you to the fact that something has gone wrong. If the new object does understand the message, then it will execute a method, and your application may fail at some later point, or give unexpected results.

To prevent reallocation of object handles, set environment variable OOSW to +d:

export OOSW

Now when a message is sent to an object handle for an object which no longer exists, the run-time system displays the following error message:

RTS 240 Object reference not valid

Note: The +d setting for OOSW is intended for development work only. Do not set +d in a production environment, as the OO RTS could eventually run out of object handles to allocate. The number of object handles the run-time system can allocate before this happens depends on the amount of memory available.

14.2.3 Object-Storage Guard pages

On some UNIX systems guard pages can help you track down some types of memory corruption problem. Check your Object COBOL for UNIX release notes to see whether they are supported on your system. They can help you find errors on two types of memory:

You can use guard pages to trap either:

These sorts of problems can occur when you are using reference modification to access data, or when you pass Object-Storage data as parameter to a method, which attempts to access it using Linkage Section data items declared the wrong size. If you are using the Base class methods "malloc" and "dealloc" to allocate and free memory, you can also trap attempts to use memory you have freed.

If any of these types of errors occur when you are running with guard pages active, you will get run-time error 114; if you are animating the program execution stops with the statement that caused the problem highlighted.

You can set the guard pages before or after Object-Storage and memory allocations.

To set the guard page before Object-Storage and memory allocations:

export OOSW

To set the guard page after Object-Storage and memory allocations:

export OOSW

Switches +g1 and +g2 are mutually exclusive - you can't set them both at the same time.

Note: Running with guard pages on increases the amount of memory used by your application. Only use it for debugging.

14.2.4 Message Tracing

If you are having problems with finding the point at which an application fails or raises an exception, you can switch on a message trace. This can be particularly useful if the error occurs while execution is in the Class Library.

To turn on message tracing, set the OOSW environment variable before you run your application:

export OOSW

Every message sent by the application is logged in file trace.log.

Note: Running with trace on slows down application execution as every message sent is written and flushed to the file.

The output from trace is an ASCII file which you can look at with Animator or any ASCII editor. The lists below describe the columns in the trace file.

Trace File Format
Type of Resolve The target of an INVOKE is categorized by one of the three values below:

resolve The INVOKE is from one object to another.
resolveself An object invoked itself (INVOKE SELF...)
resolvetosuper An object invoked its superclass (INVOKE SUPER...)
Object reference The object handle of the receiver of the message.
Message The message sent by the INVOKE.
Object type Shows one of the following codes:
I Instance object.
C Class object.
M Metaclass object.

Class of object invoked The classname of the type of object invoked.
Class of implementor Class name of the implementor of the method.
Stack level Shows the depth of the message stack. The stack level becomes one greater each time a method sends a message, and one lower each time a method exits.

For example, if method A invokes another method, the stack level becomes one greater. When the second method completes execution, the stack level becomes one smaller.

14.2.5 Finding Memory Leaks

A memory leak is memory allocated to an object which is no longer in use by your application, but which has not been finalized. One way to track down memory leaks is to watch the number of objects in your application. For example, if adding a record created an extra 24 objects, but deleting it only removed 20, a memory leak is a possibility.

You can find out the number of objects in existence at any time by sending the message "getNumberOfObjects" to the Behavior class. For example:

invoke Behavior "getNumberOfObjects" returning totalNumber

where totalNumber is declared as a pic x(4) comp-5.

14.3 Troubleshooting Tips

This section deals with the following common problems:

14.3.1 Program Not Found

If your application tries to use a class which is not available, the RTS gives you error message 173 (Called program not found). To be available, there must be an executable file for the class either on the current directory or in any of the directories pointed to by one of the following environment variables:

14.3.2 Memory Exceptions and Protection Violations on Invokes

When passing parameters to and from methods, you need to ensure that the data items used in the invoke match those expected by the method. In particular, if a method attempts to move data into a RETURNING parameter, and an invoke statement calling a method does not supply a RETURNING parameter, the application may cause a protection violation or memory exception.

For example, the "currentTime" method below returns the time in a 6-byte group item:

 method-id. "currentTime". 
 linkage section. 
 01 lnkTime.
    03 lnkHours     pic xx.
    03 lnkMins      pic xx.
    03 lnkSecs      pic xx. 

 procedure division returning lnkTime. 
     move timeNow to lnkTime
     exit method. 
 end method "currentTime".

The method invocation below has no RETURNING parameter, and would probably cause a protection violation or other memory exception error at run-time:

 invoke mainClock "currentTime" 

14.3.3 Symbol Redefined

OO programs can cause RTS error 119 (Symbol redefined) for either of the following reasons:

The first of these happens when you have within a single class named two class methods the same or two instance methods the same. You are allowed to name a class and instance method the same however; you might for example have a class program which defined an "initialize" method for both the class and the instance object.

The second usually happens when you have a particular class defined in the class-control paragraph of different programs, against different filenames. Filenames are case-sensitive, so you can get this error even if the names only differ in case.

For example, the class-control paragraph in program A might look like this:

 DateClass is class "Date" 

and the class-control paragraph in the DateClass class might look like this:

 DateClass is class "date" 

At run-time, when program A tries to invoke DateClass the run-time system raises error 119. The convention used throughout the Class Library and supplied example programs is to enter all filenames as lower case.

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

PreviousRequirements-based Vocabulary Compiling and Shipping OO ApplicationsNext