PreviousRequirements-based Vocabulary Using the Object Inspector (Windows NT & OS/2)Next"

Chapter 23: Debugging Object COBOL Applications

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

23.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.

23.2 Debugging Facilities

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

These facilities are explained in the following sections.

23.2.1 Animating your Applications

Windows NT and OS/2:
Animator V2 has been enhanced for debugging OO applications with an Object Inspector. The Object Inspector is an extension to the Animator V2 Query function. When you query any data item of type object reference, the Object Inspector gives you the following information:

If the object attributes contain another object, you can query the contained object with the Object Inspector as well. Full information on using the Object Inspector is in the chapter Using the Object Inspector.

UNIX :
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".

23.2.2 Preventing Reallocation of Object Handles

32-bit:
The run-time system on 32-bit Object COBOL systems 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:

Windows and OS/2 : 
set oosw=+d
UNIX: 
OOSW=+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.


23.2.3 Object-Storage Guard pages

32-bit:
On Windows, OS/2 and 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 allocated and free memory, the following types of error are also trapped:

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:

Windows NT and OS/2: 
set oosw=+g1
UNIX: 
OOSW=+g1 export OOSW

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

Windows NT and OS/2: 
set oosw=+g2
UNIX: 
OOSW=+g2 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.


23.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:

Windows and OS/2: 
set oosw=+t
UNIX: 
OOSW=+t export OOSW

16-bit:
On 16-bit Object COBOL systems, every message sent by the application is logged in file ootrace.lst .

32-bit:
On 32-bit Object COBOL systems, 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 V2 or any ASCII editor. The lists below describe the columns in the 16-bit and 32-bit trace files respectively.

Trace File Format (16-bit)

Object The object reference to the object
Invoke The target of an INVOKE is categorized by one of the four codes below:

RCVR The INVOKE is from one object to another.
SELF An object invoked itself (INVOKE SELF...)
SUPR An object invoked its superclass(INVOKE SUPER...)
AS A program sent a message to a piece ofintrinsic data using INVOKED ... AS. For this type of INVOKE, the object reference is shown as blank.
Method invoked The class name and the method name invoked.
Invoking program name The name of the program which sent the invoke.
Trace File Format (32-bit systems)
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.

23.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.

23.3 Troubleshooting Tips

This section deals with the following common problems:

23.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:

16-bit:
On the 16-bit system, if a class is not available you will get this message at application startup, as the 16-bit run-time system loads all classes before starting to execute application code. You may also get this message even though your application does not use the class itself.

If this happens, check the classes referenced in the Class-Control paragraphs of all the programs and classes in your application. On the 16-bit system, a reference to a class in Class-Control causes it to be loaded. Delete any references to classes not used by your application.

You may also get this error on 16-bit systems if the stack size is set too high; you can reduce the size of the stack with the COBSW environment variable (see the following section).

23.3.2 Perform Nested too Deeply (16-bit only)

OO programs on 16-bit Object COBOL systems are very sensitive to the amount of stack space. If you get error message 154 (Perform nested too deeply), you may need to increase the amount of stack available.

To do this, change the setting of the /s switch with environment variable COBSW. For example:

set cobsw=/s12000

This sets the stack to 12,000 bytes. This is the recommended value for running OO applications.

23.3.3 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" 

23.3.4 Symbol Redefined (32-bit systems)

OO Programs running on the 32-bit systems 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 in the 32-bit system, 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:

 class-control.
 DateClass is class "Date" 
 ... 

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

 class-control.
 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.

23.3.5 Unexpected Application Behavior

The persistence feature of Object COBOL (see the chapter Persistence) may occasionally lead to unexpected results, when an application loads a persistence file created by a different application. This is more likely to happen on the 32-bit systems, where the persistence files for different applications can have the same name. On these systems, persistence files are either named objstore.dat and objstore.idx, or according to the setting of the OODIR environment variable.

The actual effects of an application running with the wrong persistence file are unpredictable. For example, you can create a persistence file for the Phonebook as explained in the chapter Persistence. On the 32-bit system this will have the filename objstore.

If the persistence file is in the current directory or pointed to by OODIR when you run a different Object COBOL application, the OO RTS opens the existing Phonebook persistence file and attempts to use it. The main Phonebook window appears instead of your own application running, and fails at an unpredictable point.


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 Using the Object Inspector (Windows NT & OS/2)Next"