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; see the chapter Infomgr in the your Utilities Handbook for details.

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's Guide.

To create the different types of executable files and use Animator with them:

Executable File Type
To Compile
To Start Animator
.int file
cob -ia pi.cbl 
anim pi.int
.gnt file
cob -ug -C anim pi.cbl 
anim pi.gnt 
.so file
cob -zg -C anim pi.cbl 
anim pi.so
System executable file
cob -xg -C anim pi.cbl 
anim pi

5.2 Just-in-time Debugging

Just-in-time debugging enables you to start Animator and debug a running program if that program 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 run-time configuration file. For example, 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 system:

export COBCONFIG=cobopt.cfg

For details on the run-time configuration file and run-time tunables, see the chapter Run-time Configuration in your Server Express User's Guide.

The demonstration program ticerr.cbl contains an error. To use just-in-time debugging:

  1. Set the run-time tunable:
    debug_on_error=1

    in your run-time configuration file.

  2. Export your configuration file.

  3. Compile the program:
    cob -aiv ticerr.cbl 
  4. 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

For details on the run-time configuration file and run-time tunables, see the chapter Run-time Configuration in your Server Express User's 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

  1. Set the run-time tunable:
    set core_on_error=1

    in your configuration file.

  2. Export your configuration file.

  3. Compile the program:
    cob -aiv ticerr.cbl
  4. 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.

  5. 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 Animator which process it needs to attach to.

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

  1. Compile the program:
    cob -iav csi tictac.cbl
  2. Run the program:
    cobrun tictac.int

    The Tictac program runs and displays a prompt; ignore this for the moment.

  3. Switch to another console, or new X window.

  4. 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 Tictac, the other the grep command. The one you need is usually the first one and should contain the word rts32; for example, 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.

  5. 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 interrupted

    is displayed. This is because the Tictac program is waiting in an ACCEPT statement which makes a call to the COBOL system program ADISKEY2.

  6. Press p; this selects the Perform option from the menu.

  7. Press v; this select 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.

  8. Press s to step the current statement.

  9. Switch back to your previous terminal or X window that is running Tictac, and reply to the Tictac prompt.

  10. Press n

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


  1. Compile the COBOL program for animation:
    cob -iav cobmain.cbl
  2. Compile the C program to a shared object:
    cob -zg -e “” csub.c
  3. Start Animator:
    anim cobmain.int mixedlangdebug

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

  4. You can now step through the Cobmain program as you would normally. Stop on the line:
    call "csub1" using a b
  5. Switch to a different terminal or X window.

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

  7. Start the dbx debugger and attach it to the running process:
    dbx -a 36712 
  8. Enter:
    stop in csub1

    This tells dbx to stop when the program enters csub1.

  9. Press c

    This tells dbx to let the process run.

  10. Switch back to the terminal or X window where Animator is running.

  11. Press s

    This steps the call to csub1.

  12. 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, and so on.

  13. Detach from the program when you have finished.

    Detaching removes the ptrace attachment; Animator and the program being debugged continue. Alternatively, you can choose to continue; this keeps dbx running in the background waiting for the program being debugged to hit one of your set breakpoints.

5.6 Multi-threaded Debugging

This section assumes that you are familiar with multi-threaded programming. If you are not, see your Multi-threaded Programming. 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 and servdisp.cpy.

  1. Compile the demonstration programs:
    cob -iavt mthread.cbl mthreadcore.cbl service.cbl servui.cbl

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

  2. Run the program using the trigger for the multi-threaded run-time system, cobrun_t, setting the +A run-time switch to start Animator:
    cobrun_t +A mthread.int

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

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

  4. Press Esc to close the View-thread box

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

  6. Enter bs; this sets a breakpoint on this line.

  7. Press z to zoom the mthread.int program.

  8. Switch to the window in which mthread.int is running.

  9. Press 1 to start a thread. Animator has stopped on the breakpoint.

  10. Switch to Animator window.

  11. Press z to zoom the mthread.int program again.

  12. Switch to the window in which mthread.int is running.

  13. Press 2. This starts another thread. Animator stops on the breakpoint.

  14. Switch to the Animator window.

  15. Press 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 shows you the code that the selected thread is currently running.

From this example 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:
    set core_on_error=1
  2. Assuming that you have already compiled mthreadcore.cbl to intermediate code, run the program:
    cobrun_t mthreadcore.int 
  3. Enter 1

  4. Enter 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 the first thread might finish before you manage to start the second; if this happens try running the program again.

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

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, Animator starts debugging at the line that calls the routine. 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 non-COBOL 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 starts.


Copyright © 2000 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