Requirements-based Vocabulary | Using the Object Inspector (Windows NT & OS/2) |
This chapter provides some information to help you debug Object COBOL applications.
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.
Object COBOL comes with the following facilities for debugging OO applications:
These facilities are explained in the following sections.
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:
Whether it is a class or instance object, and the class of the object
If it is a class object, the class data, and if it is an instance, the instance data
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".
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.
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.
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.
Object | The object reference to the object | ||||||||
Invoke | The target of an INVOKE is categorized by one of the
four codes below:
|
||||||||
Method invoked | The class name and the method name invoked. | ||||||||
Invoking program name | The name of the program which sent the invoke. |
Type of Resolve | The target of an INVOKE is categorized by one of the
three values below:
|
||||||
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:
|
||||||
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. |
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
.
This section deals with the following common problems:
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).
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.
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"
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.
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.
Requirements-based Vocabulary | Using the Object Inspector (Windows NT & OS/2) |