# Compaq Fortran
User Manual for
Tru64 UNIX and
Linux Alpha Systems

Previous | Contents | Index

# Chapter 4
Using the Ladebug Debugger

This chapter contains the following topics:

- Section 4.1, Overview of Ladebug and dbx Debuggers
- Section 4.2,Compaq Fortran Options for Debugging
- Section 4.3, Running the Debugger
- Section 4.4, Sample Program and Debugging Session
- Section 4.5, Summary of Debugger Commands
- Section 4.6, Displaying Variables
- Section 4.7, Expressions in Debugger Commands
- Section 4.8, Debugging Mixed-Language Programs with Ladebug
- Section 4.9, Debugging a Program that Generates an Exception
- Section 4.10, Locating Unaligned Data
- Section 4.11, Using Alternate Entry Points
- Section 4.12, Debugging Optimized Programs

# 4.1 Overview of Ladebug and dbx Debuggers

You can use these debuggers to debug Compaq Fortran programs:

- On Tru64 UNIX: Ladebug and dbx
- On Linux: Ladebug

Ladebug supports Compaq Fortran data types, syntax, and use. Ladebug is a source-level, symbolic debugger that lets you:

- Control the execution of individual source lines in a program.
- Set stops (breakpoints) at specific source lines or under various conditions.
- Change the value of variables in your program.
- Refer to program locations by their symbolic names, using the debugger's knowledge of the Compaq Fortran language to determine the proper scoping rules and how the values should be evaluated and displayed.
- Print the values of variables and set a tracepoint (trace) to notify you when the value of a variable changes. Another term for a tracepoint is a watchpoint.
- Perform other functions, such as examining `core` files, examining the call stack, or displaying registers.

The command names and command syntax used by Ladebug and dbx are almost identical. However, Ladebug provides significantly more Compaq Fortran language support than dbx, especially Fortran 95/90 features not found in the FORTRAN-77 standard.

This chapter primarily describes the Ladebug debugger.

# 4.2 Compaq Fortran Options for Debugging

The `-gn` options control the amount of information placed in the object file for debugging. To use Ladebug, you should specify the `-ladebug` option along with the `-g` , `-g2` , or `-g3` options.

Table 4-1 summarizes the information provided by the `-g` n options and their relationship to the `-on` options.

Table 4-1 Command-Line Options Affecting Traceback and Symbol Table Information
Option | Traceback Information | Debugging Symbol Table Information | Effect on -On Options
--- | --- | --- | ---
`-g0` | No | No | Default is `-o4` .
`-g1` (default) | Yes | No | Default is `-o4` .
`-g` or `-g2` 1 | Yes | Yes, but for unoptimized code. | Changes default to `-o0` .
`-g3` | Yes | Yes, but for unoptimized code. | Default is `-o4` .
`-ladebug` | Yes | Allows access to Fortran 95/90 dynamic arrays using standard Fortran 95/90 syntax, including array sections. | No effect.

1The `-g` and `-g2` options are equivalent.

Traceback information and symbol table information are both necessary for debugging. As shown in Table 4-1, if you specify `-g` , `-g2` , or `-g3` , the compiler provides the symbol table and traceback information needed for symbolic debugging. Unless you specify `-g0` , the compiler supplies traceback information in the object file.

To use the Ladebug debugger, you should specify the `f90` (on Tru64 UNIX systems) or the `fort` (on Linux systems) command and the command option `-ladebug` along with `-g` , `-g2` , or `-g3` .

Likely uses of these options at the various stages of program development are as follows:

- During early stages of program development, use the `-g` ( `-g2` ) option to create unoptimized code (optimization level `-o0` ). This option also might be chosen later to debug reported problems from later stages.
- During the later stages of program development, use `-g0` or `-g1` to minimize the object file size and, as a result, the memory needed for program execution, usually with optimized code. (See Chapter 5, Performance: Making Programs Run Faster.)

Traceback and symbol table information result in a larger object file. When you have finished debugging your program, you can recompile and relink to create an optimized executable program or remove traceback and symbol table information with the `strip` command. (See `strip(1)`.)

If your program generates an exception, see Section 4.9, Debugging a Program that Generates an Exception.

# 4.3 Running the Debugger

The Ladebug debugger provides the following user interfaces in the Compaq Tru64 UNIX operating system Programmer's Development Toolkit:

- A graphical Ladebug windowing interface (TU*X ONLY)
- A character-cell interface

The examples in this chapter show the character-cell interface to the Ladebug debugger.

## 4.3.1 Creating the Executable Program and Running the Debugger

Use the `f90` command with certain options to create an executable program for debugging. To invoke the debugger, enter the debugger shell command and the name of the executable program.

### 4.3.1.1 Invoking Ladebug

The following commands create (compile and link) the executable program and invoke the character-cell interface to the Ladebug debugger:

    % f90 -g -ladebug -o squares squares.f90
    % ladebug squares
    Welcome to the Ladebug Debugger Version x.x-xx
    ---------------
    object file name: squares
    reading symbolic information ... done
    (ladebug)

In this example, the `f90` command:

- Compiles and links the program `squares.f90` .
- Requests symbol table information needed for symbolic debugging and no optimization ( `-g` and `-ladebug` ).
- Names the executable file `squares` instead of `a.out` ( `-o squares` ).

The `ladebug` shell command runs the debugger, specifying the executable program `squares` . The `ladebug` command accepts various options. (See `ladebug(1)`.)

At the debugger prompt `(ladebug)` , you can enter a debugger command.

### 4.3.1.2 Invoking dbx

The following commands create the executable program and invoke the dbx debugger (TU*X ONLY). Note that the `-ladebug` option is omitted, which causes dbx to be used:

    % f90 -g -o squares squares.f90
    % dbx squares
    dbx version x.x.x
    Type 'help' for help.
    squares:   1  PROGRAM SQUARES
    (dbx)

In this example, the `f90` command:

- Compiles and links the program `squares.f90` .
- Requests symbol table information needed for symbolic debugging and no optimization ( `-g` ).
- Names the executable file `squares` instead of `a.out` ( `-o squares` ).

The `dbx` shell command runs the debugger, specifying the executable program `squares` . The `dbx` command accepts various options. (See `dbx(1)`.)

At the debugger prompt `(dbx)` , you can enter a debugger command.

## 4.3.2 Debugger Commands and Breakpoints

To find out what happens at critical points in your program, you need to stop execution at these points and look at the contents of program variables to see if they contain the correct values. Points at which the debugger stops program execution are called breakpoints.

To set a breakpoint, use one of the forms of the `stop` or `stopi` commands.

Using the program created in Section 4.3.1, the following debugger commands set a breakpoint at line 4, run the program, continue the program, delete the breakpoint, rerun the program, and return to the shell:

    (ladebug) stop at 4
    [#1: stop at "squares.f90":4 ]
    (ladebug) run
    [1] stopped at [squares:4 0x120001880]
    >   4      OPEN(UNIT=8, FILE='datafile.dat', STATUS='OLD')
    (ladebug) cont
    Process has exited with status 0
    (ladebug) delete 1
    (ladebug) rerun
    Process has exited with status 0
    (ladebug) quit
    %

1. The `stop at 4` command sets a breakpoint at line 4.
   To set a breakpoint at the start of a subprogram (such as calc), use the `stop in` (such as `stop in calc` ).
2. The `run` command begins program execution and stops at the first breakpoint. The program is now active, allowing you to view the values of variables with `print` commands and perform related functions.
3. The `cont` (continue) command resumes program execution.
   In addition to the `cont` command, you can also use the `step` , `next` , `run` , or `rerun` commands to resume execution.
4. The `delete 1` command shows how to delete a previously set breakpoint (with event number 1). For instance, you might need to delete a previously set breakpoint before you use the `rerun` command.
5. The `rerun` command runs the program again. Since there are no breakpoints, the program runs to completion.
6. The `quit` command exits the debugger and returns to the shell.

Other debugger commands include the following:

- To get help on debugger commands, enter the `help` command.
- To display previously typed debugger commands, type the `history` command.
- To look at, or examine, the contents of a location, use the `print` or `dump` commands.
- You can use the debugger `sh` command (followed by the desired shell command) to execute a shell command. For instance, if you cannot recall the name of a FUNCTION statement, the following `grep` shell command displays the lines containing the letters FUNCTION, allowing use of the function name (SUBSORT) in the `stop in` command:

      (ladebug) sh grep FUNCTION data.for
         INTEGER*4 FUNCTION SUBSORT (A,B)
      (ladebug) stop in subsort
      (ladebug)

## 4.3.3 Ladebug Limitations

For a list of known Ladebug limitations, see the Compaq Tru64 UNIX Ladebug Debugger Manual.

# 4.4 Sample Program and Debugging Session

Example 4-1 shows a program called SQUARES that requires debugging. The program was compiled and linked without diagnostic messages from either the compiler or the linker. However, this program contains a logic error in an arithmetic expression.

Compiler-assigned line numbers have been added in the example so that you can identify the source lines to which the explanatory text refers.

Example 4-1 Sample Program SQUARES

    1        PROGRAM SQUARES
    2        INTEGER INARR(20), OUTARR(20)
    3  C  ! Read the input array from the data file.
    4        OPEN(UNIT=8, FILE='datafile.dat', STATUS='OLD')
    5        READ(8,*,END=5) N, (INARR(I), I=1,N)
    6     5  CLOSE (UNIT=8)
    7  C ! Square all nonzero elements and store in OUTARR.
    8        K = 0
    9        DO I = 1, N
    10         IF (INARR(I) .NE. 0) THEN
    11            OUTARR(K) = INARR(I)**2
    12         ENDIF
    13       END DO
    14
    15 C ! Print the squared output values.  Then stop.
    16       PRINT 20, K
    17   20  FORMAT (' Number of nonzero elements is',I4)
    18       DO I = 1, K
    19         PRINT 30, I, OUTARR(I)
    20   30    FORMAT(' Element',I4,' has value',I6)
    21       END DO
    22       END PROGRAM SQUARES

The program SQUARES performs the following functions:

1. Reads a sequence of integer numbers from a data file and saves these numbers in the array INARR (lines 4 and 5). The file `datafile.dat` contains one record with the integer values 4, 3, 2, 5, and 2. The first number (4) indicates the number of data items that follow.
2. Enters a loop in which it copies the square of each nonzero integer into another array OUTARR (lines 8 through 13).
3. Prints the number of nonzero elements in the original sequence and the square of each such element (lines 16 through 21).

Note: This example assumes that the program was executed without array bounds checking (set by the Section 3.23 command-line option). When executed with array bounds checking, a run-time error message appears.

When you run SQUARES, it produces the following output, regardless of the number of nonzero elements in the data file:

    % squares
    Number of nonzero elements is   0

The logic error occurs because variable K, which keeps track of the current index into OUTARR, is not incremented in the loop on lines 9 through 13. The statement K = K + 1 should be inserted just before line 11.

Example 4-2 shows how to start the debugging session and how to use the character-cell interface to the Ladebug debugger to find the error in the sample program in Example 4-1. Comments keyed to the callouts follow the example.

Example 4-2 Sample Debugging Session Using Program Squares

    % f90 -g -ladebug -o squares squares.f90  (1)
    % ladebug squares                         (2)
    Welcome to the Ladebug Debugger Version x.x-xx
    ---------------
    object file name: squares
    reading symbolic information ... done
    (ladebug) list 1,9                        (3)
          1   PROGRAM SQUARES
          2     INTEGER INARR(20), OUTARR(20)
          3 C  ! Read the input array from the data file.
    >     4      OPEN(UNIT=8, FILE='datafile.dat', STATUS='OLD')
          5      READ(8,*,END=5) N, (INARR(I), I=1,N)
          6    5 CLOSE (UNIT=8)
          7 C  ! Square all nonzero elements and store in OUTARR.
          8      K = 0
          9      DO 10 I = 1, N
    (ladebug) stop at 8                       (4)
    [#1: stop at "squares.f90":8]
    (ladebug) run                             (5)
    [1] stopped at ["squares.f90":4 0x120001a88]
    >   8      K = 0
    (ladebug) step                            (6)
    stopped at [squares:9 0x120001a90]
          9        DO 10 I = 1, N
    (ladebug) print n, k                      (7)
    4 0
    (ladebug) step                            (8)
    stopped at [squares:10 0x120001ab0]]
         10       IF(INARR(I) .NE. 0)  THEN
    (ladebug) s
    stopped at [squares:11 0x1200011acc]
         11       OUTARR(K) =   INARR(I)**2
    (ladebug) print i, k                      (9)
    1 0
    (ladebug) assign k = 1                    (10)
    (ladebug) watch variable k                (11)
    [#2: watch variable (write) k 0x1400002c0 to 0x1400002c3 ]
    (ladebug) cont                            (12)
    Number of nonzero elements is   1
    Element   1 has value     4
    Process has exited with status 0
    (ladebug) quit                            (13)
    % vi squares.f90                          (14)
       .
       .
       .
    10:       IF(INARR(I) .NE. 0) THEN
    11:           K = K + 1
    12:           OUTARR(K) = INARR(I)**2
    13:       ENDIF
       .
       .
       .
    % f90 -g -ladebug -o squares squares.f90     (15)
    % ladebug squares
    Welcome to the Ladebug Debugger Version x.x-xx
    Reading symbolic information ...done
    (ladebug) when at 12 {print k}               (16)
    [#1: when at "squares.f90":12 { print K} ]
    (ladebug) run                                (17)
    [1] when [squares:12 0x120001ae0]
    1
    [1] when [squares:12 0x120001ae0]
    2
    [1] when [squares:12 0x120001ae0]
    3
    [1] when [squares:12 0x120001ae0]
    4
    Number of nonzero elements is   4
    Element   1 has value     9
    Element   2 has value     4
    Element   3 has value    25
    Element   4 has value     4
    Process has exited with status 0
    (ladebug) quit                               (18)
    %

1. On the `f90` command line, the `-g` and `-ladebug` options direct the compiler to write the symbol information associated with SQUARES into the object file for the debugger. It also disables most optimizations done by the compiler to ensure that the executable code matches the source code of the program. On a Linux system, the `fort` command and the same options would give the compiler the same directions.
2. The shell command `ladebug squares` runs the debugger, which displays its banner and the debugger prompt, `(ladebug)` . This command specifies the executable program as a file named `squares` . You can now enter debugger commands.
   After the `ladebug squares` command, execution is initially paused before the start of the main program unit (before program SQUARES, in this example).
   To use the dbx debugger, enter the following shell command instead of `ladebug squares` :

       % dbx squares
       dbx version x.x
       Type 'help' for help.
       squares:   4  OPEN(UNIT=8, FILE='datafile.dat', STATUS='OLD')
       (dbx)

3. The `list 1,9` command prints lines 1 through 9.
4. The command `stop at 8` sets a breakpoint (1) at line 8.
5. The `run` command begins program execution. The program stops at the first breakpoint, line 8, allowing you to examine variables N and K before program completion.
6. The `step` advances the program to line 9.
   The `step` command ignores source lines that do not result in executable code; also, by default, the debugger identifies the source line at which execution is paused.
   To avoid stepping into a subprogram, use the `next` command instead of `step`
7. The command `print n, k` displays the current values of variables N and K. Their values are correct at this point in the execution of the program.
8. The two `step` commands continue executing the program into the loop (lines 9 to 11) that copies and squares all nonzero elements of INARR into OUTARR.
   Certain commands can be abbreviated. In this example, the `s` command is an abbreviation of the `step` command.
9. The command `print i, k` displays the current values of variables I and K.
   Variable I has the expected value, 1. But variable K has the value 0 instead of the expected value, 1. To fix this error, K should be incremented in the loop just before it is used in line 11.
10. The `assign` command assigns K the value 1.
11. The `watch variable k` command sets a watchpoint that is triggered every time the value of variable K changes. In the original version of the program, this watchpoint is never triggered, indicating that the value of variable K never changes (a programming error).
12. To test the patch, the `cont` command (an abbreviation of continue) resumes execution from the current location.
    The program output shows that the patched program works properly, but only for the first array element. Because the watchpoint ( `watch variable k` command) does not occur, the value of K did not change and there is a problem. The Ladebug message "Process has exited with status 0" shows that the program executed to completion.
    When using the dbx debugger, the message "Program terminated normally" shows that the program executed to completion.
13. The `quit` command returns control to the shell so that you can correct the source file and recompile and relink the program.
14. The shell command `vi` runs a text editor and the source file is edited to add K = K + 1 after line 10, as shown. (Compiler-assigned line numbers have been added to clarify the example.)
15. The revised program is compiled and linked.
    The shell command `ladebug squares` (or `dbx squares` ) starts the debugger, using the revised program so that its correct execution can be verified.
16. The `when at 12 {print k}` command reports the value of K at each iteration through the loop.
17. The `run` command starts execution.
    The displayed values of K confirm that the program is running correctly.
18. The `quit` command ends the debugging session, returning control to the shell.

# 4.5 Summary of Debugger Commands

Table 4-2 lists some of the more frequently used debugging commands available in Ladebug and dbx. Many of these commands can be abbreviated (for example, you can enter `c` instead of `cont` ). When using the debugger with a windowing interface, you can access these commands by using the windowing interface (command buttons and command menu). For a complete list of available debugger commands, see the `ladebug(1)` and `dbx(1)` reference pages.

Table 4-2 Summary of Debugger Commands
Command Example | Description
--- | ---
`catch` | Displays all signals that the debugger is currently set to catch (see also `ignore` ).
`catch fpe` | Tells the debugger to catch the fpe signal (or the signal specified). This prevents the specified signal from reaching the Compaq Fortran RTL. The signals that the Compaq Fortran RTL arranges to catch are listed in Section 8.3.
`catch unaligned` | Tells the debugger to catch the unaligned signal, as further described in Section 4.10. The signals that the Compaq Fortran RTL arranges to catch are listed in Section 8.3.
`cont` | Resumes execution of the program that is being debugged. Note that there is no Ladebug command named `continue` .
`delete 2` | Removes the breakpoint or tracepoint identified by event number 2 (see also `status` ).
`delete all` | Removes all breakpoints and tracepoints.
`help` | Displays debugger help text.
`history 5` | Displays the last 5 debugger commands.
`ignore` | Displays the signals the debugger is currently set to ignore. The ignored signals are allowed to pass directly to the Compaq Fortran RTL. (see also `catch` ).
`ignore fpe` | Tells the debugger to ignore the fpe signal (or the signal specified). This allows the specified signal to pass directly to the Compaq Fortran RTL, allowing message display. The signals that the Compaq Fortran RTL arranges to catch are listed in Section 8.3.
`ignore unaligned` | Tells the debugger to ignore the unaligned signal (the default).
`kill` | Terminates the program process, leaving the debugger running and its breakpoints and tracepoints intact for when the program is rerun.
`list` | Displays source program lines. To list a range of lines, add the starting line number, a comma (,), and the ending line number, such as `list 1,9` .
`print k` | Displays the value of the specified variable, such as K.
`printregs` | Displays all registers and their contents.
`next` | Steps one source statement but does not step into calls to subprograms (compare with `step` ).
`quit` | Ends the debugging session.
`run` | Runs the program being debugged. You can specify program arguments and redirection.
`rerun` | Runs the program being debugged again. You can specify program arguments and redirection.
`return [ routine-name]` | When using the `step` command, if you step into a subprogram that does not require further investigation, use the `return` command to continue execution of the current function until it returns to its caller. If you include the name of a routine with the `return` command, execution continues until control is returned to that routine. The routine-name is the name of the routine, usually named by a PROGRAM, SUBROUTINE, or FUNCTION statement. If there is no PROGRAM statement, the debugger refers to the main program with a prefix of `main$` followed by the file name.
`sh more progout.f90` | Executes the shell command `more` to display file `progout.f90` , then returns to the debugger environment.
`show thread` | Lists all threads known to the Ladebug debugger.
`status` | Displays breakpoints and tracepoints with their event numbers (see also `delete` ).
`step` | Steps one source statement, including stepping into calls of a subprogram. For Compaq Fortran I/O statements, intrinsic procedures, 3f library routines, or other subprograms, use the `next` command instead of `step` to step over the subprogram call. Compare with `next` ; also see `return` .
`stop in foo` | Stops execution (breakpoint) at the beginning of routine foo.
`stop at 100` | Stops execution at line 100 (breakpoint) of the current source file.
`stopi at` xxxxxxx | Stops execution at address xxxxxxx of the current executable program.
`thread [ n]` | Identifies or sets the current thread context (ladebug).
`watch location` | Displays a message when the debugger accesses the specified memory location. For example, `watch 0x140000170` .
`watch variable m` | Displays a message when the debugger accesses the variable specified by m.
`whatis sym` | Displays data type of specified symbol.
`when at 9 { command}` | When a specified line (such as 9) is reached, the command or commands are executed. For example, `when at 9 {print k}` prints the value of variable K when the program executes source code line 9.
`when in name { command}` | When a procedure specified by name is reached, the command or commands are executed. For example, `when in calc_ave {print k}` prints the value of variable K when the program begins executing the procedure named calc_ave.
`where` | Displays the call stack.
`where thread all` | Displays the stack traces of all threads.

The debuggers support other special-purpose commands. For example:

- You might use the `attach` and `detach` commands for programs with very long execution times.
- The `listobj` command may be helpful when debugging programs that depend on shared libraries. The `listobj` debugger command displays the names of executables and shared libraries currently known to the debugger.

For More Information:

- On debugger command syntax, use the `help` command.
- On the debugger windowing interface, use online windowing help or see Section 4.3.
- On examples of debugger commands, see Section 4.4 and Section 4.5.
- On Ladebug commands, see the Compaq Tru64 UNIX Ladebug Debugger Manual or `ladebug(1)` reference page.
- On dbx commands, see Compaq Tru64 UNIX Programmer's Guide and `dbx(1)`.

# 4.6 Displaying Variables

To refer to a variable, use either the uppercase or lowercase letters. For example:

    (ladebug) print J
    (ladebug) print j

You can enter command names in uppercase:

    (ladebug) PRINT J

If you compile the program with the `f90` command option `-names as_is` and you need to examine case-sensitive names, you can control whether Ladebug is case sensitive by setting the `$lang` environment variable to the name of a case-sensitive language (see Section 4.8).

## 4.6.1 Compaq Fortran Module Variables

To refer to a variable defined in a module, insert a dollar sign ($), the module name, and another dollar sign ($) before the variable name. For example, with a variable named J defined in a module named modfile (statement MODULE MODFILE), enter the following command to display its value:

    (ladebug) list 5,9
         5     USE MODFILE
         6      INTEGER*4 J
         7      CHARACTER*1 CHR
         8      J = 2**8
    (ladebug) PRINT $MODFILE$J
    256

## 4.6.2 Compaq Fortran Common Block Variables

You can display the values of variables in a Fortran common block by using debugger commands such as `print` or `whatis` .

To display the entire common block, use the common block name.

To display a specific variable in a common block, use the variable name. For example:

    (ladebug) list 1,11
       1       PROGRAM EXAMPLE
       2
       3       INTEGER*4 INT4
       4       CHARACTER*1 CHR
       5       COMMON /COM_STRA/ INT4, CHR
       6
       7       CHR = 'L'
       8
       9       END
    (ladebug) PRINT COM_STRA
    COMMON
            INT4 = 0
            CHR = "L"
    (ladebug)
    (ladebug) PRINT CHR
    "L"

If the name of a data item in a common block has the same name as the common block itself, the data item is accessed.

## 4.6.3 Compaq Fortran Derived-Type Variables

Variables in a Fortran 95/90 derived-type (TYPE statement) are represented in Ladebug commands such as `print` or `whatis` using Fortran 95/90 syntax form.

For derived-type structures, use the derived-type variable name, a percent sign (%), and the member name. For example:

    (ladebug) list 3,11
        3  TYPE X
        4      INTEGER A(5)
        5    END TYPE X
        6
        7   TYPE (X) Z
        8
        9   Z%A = 1
       10
       11   PRINT *,Z%A
    (ladebug) PRINT Z%A
    (1) 1
    (2) 1
    (3) 1
    (4) 1
    (5) 1
    (ladebug)

To display the entire object, use the `PRINT` command with the object name. For example:

    (ladebug) PRINT Z

## 4.6.4 Compaq Fortran Record Variables

To display the value of a field in a record structure, enter the variable name as: the record name, a delimiter (either a period (.) or a percent sign (%)), and the field name.

To view all fields in a record structure, enter the name of the record structure, such as REC (instead of REC.CHR or REC%CHR) in the previous example.

## 4.6.5 Compaq Fortran Pointer Variables

Compaq Fortran supports two types of pointers:

- Fortran 95/90 pointers (standard-conforming)
- Compaq Fortran CRAY-style pointers (extension to the Fortran 95/90 standards)

### 4.6.5.1 Fortran 95/90 Pointers

Fortran 95/90 pointers display their corresponding target data with a `print` command. You must specify the `-ladebug` option to provide Ladebug with information about pointers to arrays.

    % f90 -g -ladebug point.f90
    % ladebug ./a.out
    Welcome to the Ladebug Debugger Version x.x-xx
    ------------------
    object file name: ./a.out
    Reading symbolic information ...done
    (ladebug) stop in ptr
    [#1: stop in ptr ]
    (ladebug) list 1:13
          1       program ptr
          2
          3       integer, target :: x(3)
          4       integer, pointer :: xp(:)
          5
          6       x = (/ 1, 2, 3/)
          7       xp => x
          8
          9       print *, "x = ", x
         10       print *, "xp = ", xp
         11
         12       end
    (ladebug) run
    [1] stopped at [ptr:6 0x120001838]
          6        x = (/ 1, 2, 3/)
    (ladebug) whatis x
    int x(1:3)
    (ladebug) whatis xp  (1)
    int xp(:)
    (ladebug) s
    stopped at [ptr:7 0x120001880]
          7       xp => x
    (ladebug) s
    stopped at [ptr:9 0x120001954]
          9       print *, "x = ", x
    (ladebug) s
    x =            1           2           3
    stopped at [ptr:10 0x1200019c8]
    (ladebug) s
     xp =            1           2           3
    stopped at [point:12 0x120001ad8]
         12       end
    (ladebug) S
     xp =            1           2           3
    (ladebug) whatis xp (2)
    int xp(1:3)
    (ladebug) print xp
    (1) 1
    (2) 2
    (3) 3
    (ladebug) quit
    %

1. For the first `whatis xp` command, xp has not yet been assigned to point to variable x and is a generic pointer.
2. Since xp has been assigned to point to variable x, for the second `whatis xp` command, xp takes the same size, shape, and values as x.

### 4.6.5.2 CRAY-Style Pointers

Like Fortran 95/90 pointers, Compaq Fortran (CRAY-style) pointers (POINTER statement) display the target data in their corresponding source form with a `print` command.

    (ladebug) stop at 14
    [#1: stop at "dfpoint.f90":14 ]
    (ladebug) run
    [1] stopped at [dfpoint:14 0x1200017e4]
    (ladebug) list 1,14
          1       program dfpoint
          2
          3       real i(5)
          4       pointer (p,i)
          5
          6       n = 5
          7
          8       p = malloc(sizeof(i(1))*n)
          9
         10       do j = 1,5
         11          i(j) = 10*j
         12       end do
         13
    >    14       end
    (ladebug) whatis p
    float (1:5) pointer p
    (ladebug) print p
    0x140003060 = (1) 10
    (2) 20
    (3) 30
    (4) 40
    (5) 50
    (ladebug) quit
    %

## 4.6.6 Compaq Fortran Array Variables

For array variables, put subscripts within parentheses, as with Fortran 95/90 source statements. For example:

    (ladebug) assign arrayc(1)=1

You can print out all elements of an array using its name. For example:

    (ladebug) print arrayc
    (1) 1
    (2) 0
    (3) 0
    (ladebug)

Avoid displaying all elements of a large array. Instead, display specific array elements or array sections. For example, to print array element arrayc(2):

    (ladebug) print arrayc(2)
    (2) 0

### 4.6.6.1 Array Sections

An array section is a portion of an array that is an array itself. An array section can use subscript triplet notation consisting of a three parts: a starting element, an ending element, and a stride.

Consider the following array declarations:

    INTEGER, DIMENSION(0:99)    :: arr
    INTEGER, DIMENSION(0:4,0:4)  :: FiveByFive

Assume that each array has been initialized to have the value of the index in each position, for example, FiveByFive(4,4) = 44, arr(43) = 43. The following examples are array expressions that will be accepted by the debugger:

    (ladebug) print arr(2)
    2
    (ladebug) print arr(0:9:2)
    (0) = 0
    (2) = 2
    (4) = 4
    (6) = 6
    (8) = 8
    (ladebug) print FiveByFive(:,3)
    (0,3) = 3
    (1,3) = 13
    (2,3) = 23
    (3,3) = 33
    (4,3) = 43
    (ladebug)

The only operations permissible on array sections are `whatis` and `print` .

### 4.6.6.2 Assignment to Arrays

Assignment to array elements are supported by Ladebug.

For information about assigning values to whole arrays and array sections, see the Fortran chapter in the Compaq Tru64 UNIX Ladebug Debugger Manual.

## 4.6.7 Complex Variables

Ladebug supports COMPLEX or COMPLEX*8, COMPLEX*16, and COMPLEX*32 variables and constants in expressions.

Consider the following Fortran program:

        PROGRAM complextest
          COMPLEX*8 C8 /(2.0,8.0)/
          COMPLEX*16 C16 /(1.23,-4.56)/
          REAL*4     R4 /2.0/
          REAL*8     R8 /2.0/
          REAL*16    R16 /2.0/

          TYPE *, "C8=", C8
          TYPE *, "C16=", C16
        END PROGRAM

Ladebug supports the display and assignment of COMPLEX variables and constants as well as basic arithmetic operators. For example:

    Welcome to the Ladebug Debugger Version x.x-xx
    ------------------
    object file name: complex
    Reading symbolic information ...done
    (ladebug) stop in complextest
    [#1: stop in complextest ]
    (ladebug) run
    [1] stopped at [complextest:15 0x1200017b4]
         15       TYPE *, "C8=", C8
    (ladebug) whatis c8
    complex c8
    (ladebug) whatis c16
    double complex c16
    (ladebug) print c8
    (2, 8)
    (ladebug) print c16
    (1.23, -4.56)
    (ladebug) assign c16=(-2.3E+10,4.5e-2)
    (ladebug) print c16
    (-23000000512, 0.04500000178813934)
    (ladebug)

## 4.6.8 Compaq Fortran Data Types

Table 4-3 shows the Compaq Fortran data types and their equivalent built-in debugger names:

Table 4-3 Fortran Data Types and Debugger Equivalents
Fortran 95/90 Data Type Declaration | Debugger Equivalent
--- | ---
CHARACTER | character
INTEGER, INTEGER(KIND= n) | integer, integer*n
LOGICAL, LOGICAL (KIND= n) | logical, logical*n
REAL, REAL(KIND=4) | real
DOUBLE PRECISION, REAL(KIND=8) | real*8
REAL(KIND=16) | real*16
COMPLEX, COMPLEX(KIND=4) | complex
DOUBLE COMPLEX, COMPLEX(KIND=8) | double complex
COMPLEX(KIND=16), COMPLEX*32 | long double complex

# 4.7 Expressions in Debugger Commands

Expressions in debugger commands use Fortran 95/90 source language syntax for operators and expressions.

Enclose debugger command expressions between curly braces ({ }). For example, the expression `print k` in the following statement is enclosed between curly braces ({ }):

    (ladebug) when at 12 {print k}

## 4.7.1 Fortran Operators

The Compaq Fortran operators include the following:

- Relational operators, such as less than (.LT. or <) and equal to (.EQ. or ==)
- Logical operators, such as logical conjunction (.AND.) and logical disjunction (.OR.)
- Arithmetic operators, including addition (+), subtraction (--), multiplication (*), and division (/).

For More Information:

- For a complete list of operators, see the Compaq Fortran Language Reference Manual.

## 4.7.2 Procedures

The Ladebug debugger supports invocation of user-defined specific procedures using Fortran 95/90 source language syntax. Ladebug also supports the invocation of some of the Fortran 95/90 generic and specific procedures, currently limited to scalar arguments.

For More Information:

- For a complete list of intrinsic procedures, see the Compaq Fortran Language Reference Manual.
- For a list of supported intrinsic procedures and known limitations of that support, see the Compaq Tru64 UNIX Ladebug Debugger Manual.

# 4.8 Debugging Mixed-Language Programs with Ladebug

The Ladebug debugger lets you debug mixed-language programs. Program flow of control across subprograms written in different languages is transparent.

The debugger automatically identifies the language of the current subprogram or code segment on the basis of information embedded in the executable file. For example, if program execution is suspended in a subprogram in Fortran, the current language is Fortran. If the debugger stops the program in a C function, the current language becomes C. The debugger uses the current language to determine the valid expression syntax and the semantics used to evaluate an expression.

The debugger sets the `$lang` variable to the language of the current subprogram or code segment. By manually setting the `$lang` debugger variable, you can force the debugger to interpret expressions used in commands by the rules and semantics of a particular language. For example, you can check the current setting of `$lang` and change it as follows:

    (ladebug) print $lang
    "C++"
    (ladebug) set $lang = "Fortran"

When the `$lang` environment variable is set to "Fortran", names are case insensitive. To make names case-sensitive when the program was compiled with the `-names as_is` option, specify another language for the `$lang` environment variable, such as C, view the variable, then set the `$lang` environment variable to "Fortran".

# 4.9 Debugging a Program that Generates an Exception

If your program encounters an exception at run time, to make it easier to debug the program, you should recompile and relink with the following `f90` options before debugging the cause of the exception:

- Use the `-fpen` option to control the handling of exceptions. (See Section 3.44, -fpen --- Control Arithmetic Exception Handling and Reporting.)
- If you use `-fpe0` (default), specify the `-synchronous_exceptions` option to ensure that the exception error is reported as close to the cause of the exception as possible. (See Section 3.86, -synchronous_exceptions --- Report Exceptions More Precisely .)
- Like other debugging tasks, use the `-g` and `-ladebug` options to generate sufficient symbol table information and debug unoptimized code. (See Section 4.2,Compaq Fortran Options for Debugging.)

If requested, Ladebug will catch and handle exceptions before the Compaq Fortran run-time library does. You can use the Ladebug commands `catch` and `ignore` to control whether Ladebug catches exceptions or ignores them:

- When Ladebug catches an exception, a Ladebug message is displayed and execution stops at that statement line. The error-handling routines provided by the Compaq Fortran run-time library are not called. At this point, you can examine variables and determine where in the program the exception has occurred.
- When Ladebug ignores an exception, the exception is passed to the Compaq Fortran run-time library. This allows the handling and display of Compaq Fortran run-time exception messages in the manner requested during compilation.

To obtain the appropriate Compaq Fortran run-time error message when debugging a program that generates an exception (especially one that allows program continuation), you might need to use the `ignore` command before running the program. For instance, use the following command to tell the debugger to ignore floating-point exceptions and pass them through to the Compaq Fortran run-time library:

    (ladebug) ignore fpe

In cases where you need to locate the part of the program causing an exception, consider using the `where` command.

For More Information:

- On run-time errors, see Chapter 8, Run-Time Errors and Signals.

# 4.10 Locating Unaligned Data

As discussed in Chapter 5, unaligned data can slow program execution. You should determine the cause of the unaligned data, fix the source code (if necessary), and recompile and relink the program.

If your program encounters unaligned data at run-time, to make it easier to debug the program, you should recompile and relink with the following command-line options before debugging the cause of the exception:

- Use the `-fpen` option to control the handling of exceptions (see Section 3.44).
- If you use `-fpe0` (the default), specify the `-synchronous_exceptions` option to ensure that the exception error is reported as close to the cause of the exception as possible (see Section 3.86).

## 4.10.1 Locating Unaligned Data With Ladebug

To determine the cause of the unaligned data when using Ladebug, follow these steps:

1. Run the Ladebug debugger, specifying the program with the unaligned data (shown as `testprog` in the following example):

       % ladebug testprog

2. Before you run the program, enter the `catch unaligned` command:

       (ladebug) catch unaligned

3. Run the program:

       (ladebug) run
       Unaligned access pid=28413 <a.out> va=140000154 pc=3ff80805d60
           ra=1200017e8 type=stl
       Thread received signal BUS
       stopped at [oops:13 0x120001834]
            13       end

4. Enter a `list` command to display the source code at line 12:

       (ladebug) list 12
         12        i4 = 1
       > 13          end

5. Enter the `where` command to find the location of the unaligned access:

       (ladebug) where

6. Use any other appropriate debugger commands needed to isolate the cause of the unaligned data, such as `up` , `list` , and `down` .
7. Repeat these steps for other areas where unaligned data is reported. Use the `rerun` command to run the program again instead of exiting the debugger and running it from the shell prompt.
   After fixing the causes of the unaligned data (see Section 5.4), compile and link the program again.

## 4.10.2 Locating Unaligned Data With dbx

To determine the cause of the unaligned data when using `dbx` (TU*X ONLY), follow these steps:

1. Write down the addresses reported in the run-time message (see Section 5.4.2). For this example, assume the pc address in the "Unaligned access" message is 0x1200017f0.
2. Run the debugger, specifying the program with the unaligned data (shown as `testprog` in the following example):

       % dbx testprog

3. Set a breakpoint at the address reported in the warning message by using the `stopi at` command (shown as 0x1200017f0 below):

       (dbx) stopi at 0x1200017f0
        stopi at 0x1200017f0]

4. Run the program. It will stop at the breakpoint:

       (dbx) run
       [2] stopi at 0x1200017f0]
       [2] stopped at >*[oops:12, 0x1200017f0]         stl     r3, 0(r1)

5. Enter the `where` command to find the location of the unaligned access:

       (dbx) where

6. Use any other appropriate debugger commands needed to isolate the cause of the unaligned data, such as `list` , `up` , and `down` .
7. Repeat these steps for other addresses that warning messages report.
8. After fixing the causes of the unaligned data (see Section 5.4), compile and link the program again.

# 4.11 Using Alternate Entry Points

If a subprogram uses alternate entry points (ENTRY statement within the subprogram), Ladebug handles alternate entry points as separate subprograms, including:

- Use of the ENTRY statement name as a breakpoint ( `stop in` command)
- Use of the `where` command at an alternate entry point breakpoint location

# 4.12 Debugging Optimized Programs

The Compaq Fortran compiler performs code optimizations ( `-o4` ) by default, unless you specify `-g` (or `-g2` ).

Debugging optimized code is recommended only under special circumstances, for example, if a problem disappears when you specify the `-o0` option.

One aid to debugging optimized code is to use one of the following command-line options:

- Use the `-show code` and `-v` options to generate a listing file that shows the compiled code produced for your program.
- Use the `-s` option to generate an Assembler file ( `.s` ).

By referring to a listing of the generated code, you can see how the compiler optimizations affected your code. This lets you determine the debugging commands you need in order to isolate the problem.

When you try to perform a debugger operation on a variable or language construct that has been optimized, the variable or line may not exist in the debugging environment. For example:

- If the Compaq Fortran compiler can determine that a memory location for a variable is not needed for the correct operation of a program, no memory is allocated to it.
- If the Compaq Fortran compiler can determine that an entire Fortran 95/90 statement is not needed for correct operation of the program (for example, an unnecessary CONTINUE statement), that statement is not represented in the object code. As a result, the debugger will use the next available line.

For More Information:

- See Section 5.8, Optimization Levels: the -On Option.
- See Section 5.9, Other Options Related to Optimization.

Previous | Next | Contents | Index