PreviousDirectives for Animator FaultFinderNext

Chapter 5: Debugging Tutorials

This chapter gives examples of using Animator. The examples use demonstration programs that can be found in the demo directory. Use Infomgr to locate the demonstration programs.

5.1 Basic Debugging

Animator enables you to debug all levels of code produced by the Compiler. To debug an .int file, a .gnt file or an .so file you have to pass specific options to the Compiler. For these examples, use the demonstration program pi.cbl.

See the chapters:

All three chapters are in your Server Express User Guide.

For .int files:

To create an .int file for debugging, compile it:

cob -ia pi.cbl 

You can then start Animator:

anim pi.int
For .gnt files:

To create a .gnt file for debugging, compile it:

cob -ug -C anim pi.cbl 

You can then start Animator:

anim pi.gnt 
For .so files:

To create an .so file for debugging, compile it:

cob -zg -C anim pi.cbl 

You can then start Animator:

anim pi.so
For system executable files:

To create a system executable file for debugging, compile it:

cob -xg -C anim pi.cbl 

You can then start Animator:

anim pi

5.2 Just-in-time Debugging

Just-in-time debugging enables you start the Animator and debug a running program if it terminates with a run-time error. This enables you to see what was happening when the program failed. For this example, use the demonstration program ticerr.cbl.

To start just-in-time debugging you need to add the run-time tunable debug_on_error to the configuration file. For example, if the configuration file is called cobopt.cfg, add the following line:

set debug_on_error=1 

You might also need to specify which debugger to start. Normally, you do not need to specify this as cobanim is set by default, as it enables Animator to start in a separate window under X. If you want to specify a different debugger, such as anim add:

set debugger_command="anim"

to the configuration file You might also want to add directives to the command; for example, to add directives to the cobanim command:

set debugger_command="cobanim mixedlangdebug"

Ensure that the configuration file can be read by the run-time:

export COBCONFIG=cobopt.cfg

If cobopt.cfg does not exist, create it. It is a plain text file. For details on the run-time configuration file and run-time tunables, see the chapter Run-time Configuration in your Server Express User Guide.

The demonstration program ticerr.cbl contains an error. Compile it:

cob -aiv ticerr.cbl 

Run the program:

cobrun ticerr.int

Animator starts and highlights the line call dodgy-pointer.

5.3 Core File Debugging

Core file debugging enables you to see what went wrong during the execution of a program. When an error occurs the operating-system generates a core file. The core file is a snapshot of the process's memory when program execution failed.

You need to set the run-time tunable core_on_error to generate a core file. Edit your run-time configuration file to include the line:

set core_on_error=1

If cobopt.cfg does not exist, create it. It is a plain text file. For details on the run-time configuration file and run-time tunables, see the chapter Run-time Configuration in your Server Express User Guide.


Note: If the tunable debug_on_error is set, the core_on_error tunable is overridden. You must therefore delete any reference to debug_on_error.


For this example, use the demonstration program ticerr.cbl

Compile the program:

cob -aiv ticerr.cbl

If you haven't already set the core_on_error tunable, set it now:

echo set core_on_error=1 >> cobopt.cfg
export COBCONFIG=./cobopt.cfg 

Run the program:

cobrun ticerr.int 

As this program contains an error, a message appears from the operating system telling you that a core file has been created.

To view the core file, start Animator:

anim core

Animator starts and highlights the line call dodgy-pointer.

5.4 Unsolicited Dynamic Attachment Debugging

At some point during the development cycle you might find that your program hangs, or fails in an unexpected way. In such circumstances, it is useful to start Animator at the point the program hung or otherwise failed to behave as expected.. Unsolicited dynamic attachment enables you to do this. To start an unsolicited dynamic attachment you tell the Animator which process it needs to attach to.

For this example, use the demonstration program tictac.cbl.

Compile the program:

cob -iav csi tictac.cbl

Run the program:

cobrun tictac.int

The Tictac program runs and prompts you with a question; ignore this for the moment. Switch to another console, or new X window. Type the command:

ps -fumyid | grep tictac.int

where myid is your own user id.

This command tells you which process is running Tictac. You should see two processes; one contains the entry for the Tictac, the other the grep command using "tictac". The one you need is usually the first one and should contain the word rts32.

You should see something like this:

myid 36712 83665 0 10:47:53 pts/34 0:00 /home/myid/..../rts32 tictac.int 
myid 67264 40892 3 10:54:43 pts/20 0:00 grep tictac.int

The process id is the first numeric entry on the process line. The process id you require is that for the line containing rts32 tictac.int, in this case 36712.

Start Animator using the process id:

anim 36712

Animator starts, and attaches to your running program, tictac.int. You will see the Animator menu but no COBOL code. The status line says Animate ADISKEY2 and the message Execution interruptedis displayed. This is because the Tictac program is waiting in an ACCEPT statement which makes a call to the COBOL system program ADISKEY2.

To continue, type:

p - Selects the Perform option from the menu

v - selects the View option from the menu

You should now see a list of programs and sections. It looks like this:

+Perform/Call Stack - view---------------------------------------------------+ 
|Program Name Section Name                                                   | 
+----------------------------------------------------------------------------+ 
|ADISKEY2 Program is not animatable                                          | 
|ADISKEY Program is not animatable                                           | 
|ADIS Program is not animatable                                              | 
|...1/kf/gen/src/tmp/tictac.int GET-REPLY                                    | 
|...1/kf/gen/src/tmp/tictac.int PLAY-1                                       | 
|                                                                            |
+----------------------------------------------------------------------------+
| ^ v =scroll <-+=View Escape                                                |
+----------------------------------------------------------------------------+

Press the <cursor-down> key so that GET-REPLY is highlighted, and press Enter. You should now see the COBOL statement that is actually in the process of executing.

Type:

s - Step the current statement.

You now need to switch back to your previous terminal or X window that is running tictac and answer the question. Type:

n - Do not start the computer

Switch back to the terminal or X window running Animator. The line after the ACCEPT statement is highlighted. Animator is now running normally.

5.5 Mixed-language Debugging

To enable mixed-language programming, you use Animator and any relevant system debugger. You use Animator to debug the COBOL program -- running as one process -- and the system debugger to debug the other-language program - running as a separate process.

For this example, use the demonstration programs cobmain.cbl, and csub.c. You also need a system debugger; this example uses dbx, the AIX system debugger.


Note: For information on using the system debugger, see your system documentation. No information on using system debuggers is given in this manual.


Compile the COBOL program for animation:

cob -iav cobmain.cbl

Compile the C program with debugging information to a shared object:

cob -zg -e “” csub.c

Start Animator:

anim cobmain.int mixedlangdebug

The MIXEDLANGDEBUG directive tells Animator to enable debugging using the pipes interface between the processes.

You can now step through the Cobmain program as you would normally. Stop on the line:

call "csub1" using a b

Now switch to a different terminal or X window. Type the command:

ps -fu myid | grep cobmain.int

This tells you which process to attach to dbx. You should see something like this:

myid 36712 83665 0 10:47:53 pts/34 0:00 /home/myid/..../rts32 cobmain.int mixedlangdebug
myid 67264 40892 3 10:54:43 pts/20 0:00 grep cobmain.int

The process id you want is the one shown in the line containing rts32 cobmain.int, in this case 36712.

Start the dbx debugger:

dbx -a 36712 

and attach it to the running process.

Tell dbx to stop when the program enters csub1 by typing stop in csub1. Type:

c

This tells dbx to let the process run. Now switch back to the the terminal or X window where Animator is running. Type:

s

This steps the call to csub1. Switch back to the terminal or X window in which dbx is running. dbx has stopped in the csub1 function. You can now debug this function as you like, setting more breakpoints or querying values, or whatever.

When you have finished using dbx you need to either detach or continue. Detaching removes the ptrace attachment; the Animator and program being debugged will continue. Continuing keeps dbx running in the background waiting for the program being debugged to hit one of your set breakpoints. For this example, elect to detach.

5.6 Multi-threaded Debugging

This section assume that you are familiar with multi-threaded programming. If you are not, see your Multi-threaded Programming book. Generally speaking, any method of debugging a program that has been discussed in the previous sections can be used to debug programs that have been created for use with the multi-threaded run-time system.

For this example, use the demonstration programs mthread.cbl, mthreadcore.cbl, service.cbl, servui.cbl, servwrk.cpy, servlnk.cpy, servdisp.cpy.

Compile our demonstration programs:

cob -iavt mthread.cbl mthreadcore.cbl service.cbl servui.cbl

The t cob flag turns on re-entrance for multi-threading.

You can then run the program using the trigger for the multi-threaded run-time system, cobrun_t, setting the +A run-time switch to start the Animator:

cobrun_t +A mthread.int


Note: The trigger name has _t at the the end. This is the trigger for the multi-threaded run-time. Each of the triggers cobrun, anim and cobanim have a corresponding multi-threaded version cobrun_t, anim_t and cobanim_t respectively.)


When Animator starts, type:

  1. v - View-threads. You can see two threads. One is unknown, the other is running mthread.int. The unknown thread is the main run-time thread; as it is not a COBOL program, and it is not animatable, it can be ignored.

  2. Esc - Close the View-thread box

    Press the <down arrow> cursor key until you reach the following code in mthread.int:

           
            *> Create service thread 
            *> 
             move thread-count-id to service-id 
             start 'service' using by content service-linkage 
             identified by current-req-thread 
             if return-code not = 0 
                 move service-id to service-done-id 
                 move 78-DONE-ABORT to service-done-type 
             perform send-message  
             else 
     ------>     add 1 to thread-count-id  
                 thread-count 
             end-if

    Set the cursor to the line pointed to by the arrow. Type:

  3. bs - Sets a breakpoint on this line.

  4. z - Zooms the mthread.int program.

Switch to the window in which mthread.int is running. Type:

  1. 1 - Starts a thread. Animator has stopped on the breakpoint. Switch to the Animator window.

  2. z - Zooms the mthread.int program again. Switch to the window in which mthread.int is running.

  3. 2 - Starts another thread. The animator stops on the breakpoint. Switch to the Animator window.

  4. v - view-threads. You can now see there are a few more threads running. Highlighting a different thread from the current thread and pressing enter will show you the code that the selected thread is currently running.

From this you can see that multi-threaded debugging is similar to non-threaded debugging; you just have to keep track of more programs. There are additional options available to Animator under multi-threaded debugging. You have already seen one, View-threads; another is Breakpoint thread-local, which sets a breakpoint that stops program execution, but is exclusive to a single thread. see the chapter Working With Animator for more information.

You can use core file debugging, just-in-time debugging and unsolicited dynamic attachment with multi-threaded programs in a similar way to that outlined in the previous sections. You just need to remember to apply the _t suffix to any triggers.

For example, to create a core file dump:

  1. Set the core_on_error run-time tunable in the run-time configuration file; for example:
    echo set core_on_error=1 > cobopt.cfg 
    export COBCONFIG=./cobopt.cfg 
  2. Assuming that you have already compiled mthreadcore.cbl to intermediate code, run the program:
    cobrun_t mthreadcore.int

    When requested, type 1, then 2. A message is displayed by the operating system telling you that a core file has been created. The core file is generated when two or more threads are created to run the service program. If your system is very fast then the first thread might finish before you managed to start the second; if this happens try running the program again

  3. Start Animator, using the core file as input:
    anim_t core

    Animator starts, and the line call dodgy-pointer is highlighted. You can view threads and switch between threads to see what each thread was doing at the point of failure.

Note that the difference between this procedure and that for non-threaded debugging is in the use of the _t suffix to the triggers.

5.7 The CBL_DEBUGBREAK Routine

CBL_DEBUGBREAK is a run-time library routine. If you have this routine in your program, then Animator starts debugging your program at this point in your program. To see the effect of CBL_DEBUGBREAK, compile and run the demonstration program ticbreak.cbl.

  1. Compile the program for debugging:
    cob -iav ticbreak.cbl
  2. Run the program:
    cobrun ticbreak.int

As soon as the call to CBL_DEBUGBREAK is executed, Animator is started and you can start debugging the ticbreak.cbl program.

This call is useful because it enables you to attach Animator at any point during COBOL code execution. For example, your program might contain error checking with a clause like this:

if error equals 2 
    display "Should never reach here. It's impossible" 
end-if

and when you run your program, the message is displayed. Add the line:

call "CBL_DEBUGBREAK"

which starts Animator at this point. You can now check the program logic that results in that section of code being executed.

CBL_DEBUGBREAK can also be useful when you have a large and complex application consisting of mixed language programs. Using Animator to step through the COBOL, C and any other language programs to get to the function you want to debug can be time-consuming. If you add CBL_DEBUGBREAK to your function, then compile and run the application, then when the function to be debugged is called Animator will start.


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