C H A P T E R  5

Program Analysis and Debugging

This chapter presents a number of compiler features that facilitate program analysis and debugging.


5.1 Global Program Checking (-Xlist)

The -Xlist options provide a valuable way to analyze a source program for inconsistencies and possible runtime problems. The analysis performed by the compiler is global, across subprograms.

-Xlist reports errors in alignment, agreement in number and type for subprogram arguments, common block, parameter, and various other kinds of errors.

-Xlist also can be used to make detailed source code listings and cross-reference tables.

Programs compiled with -Xlist options have their analysis data built into the binary files automatically. This enables global program checking over programs in libraries.

5.1.1 GPC Overview

Global program checking (GPC), invoked by the -Xlistx option, does the following:

In particular, global checking reports problems such as:

5.1.2 How to Invoke Global Program Checking

The -Xlist option on the command line invokes the compiler's global program analyzer. There are a number of suboptions, as described in the sections that follow.

Example: Compile three files for basic global program checking:

demo% f95 -Xlist  any1.f  any2.f  any3.f

In the preceding example, the compiler:

5.1.2.1 Screen Output

Normally, output listings produced by -Xlistx are written to a file. To display directly to the screen, use -Xlisto to write the output file to /dev/tty.

Example: Display to terminal:

demo% f95 -Xlisto /dev/tty  any1.f 

5.1.2.2 Default Output Features

The -Xlist option provides a combination of features available for output. With no other -Xlist options, you get the following by default:

5.1.2.3 File Types

The checking process recognizes all the files in the compiler command line that end in .f, .f90, .f95, .for, .F, .F95, or .o. The .o files supply the process with information regarding only global names, such as subroutine and function names.

5.1.3 Some Examples of -Xlist and Global Program Checking

Here is a listing of the Repeat.f source code used in the following examples:

demo% cat Repeat.f
       PROGRAM repeat
         pn1 = 27.005
         CALL subr1 ( pn1 )
         CALL newf ( pn1 )
         PRINT *, pn1
       END 
 
       SUBROUTINE subr1 ( x )
         IF ( x .GT. 1.0 ) THEN
          CALL subr2 ( x * 0.5 )
         END IF
       END
 
       SUBROUTINE newf( ix )
         INTEGER PRNOK
         IF (ix .eq. 0) THEN
                ix = -1
         ENDIF
         PRINT *, prnok ( ix )
       END
 
       INTEGER FUNCTION prnok ( x )
         prnok = INT ( x ) + .05
       END
 
       SUBROUTINE unreach_sub()
         CALL sleep(1)
       END
 
       SUBROUTINE subr2 (x)
         CALL subr1(x+x)
       END

Example: Use -XlistX to show errors, warnings, and cross-reference

demo% f95 -XlistX Repeat.f
demo% cat Repeat.lst
Repeat.f                    Mon Mar 18 18:08:27 2002    page 1
 
FILE  "Repeat.f"
program  repeat
     4           CALL newf ( pn1 )
                             ^
**** ERR  #418:  argument "pn1" is real, but dummy argument is integer
                 See: "Repeat.f" line #14
     5           PRINT *, pn1
                          ^
**** ERR  #570:  variable "pn1" referenced as real but set as integer in
                 line #4
subroutine  newf
    19           PRINT *, prnok  ( ix )
                                   ^
**** ERR  #418:  argument "ix" is integer, but dummy argument is real
                 See: "Repeat.f" line #22
function  prnok
    23           prnok = INT ( x ) + .05
                 ^
**** WAR  #1024:  suspicious assignment a value of type "real*4" to a
                 variable of type "integer*4"
subroutine  unreach_sub
    26         SUBROUTINE unreach_sub()
                          ^
**** WAR  #338:  subroutine "unreach_sub" never called from program
subroutine  subr2
    31           CALL subr1(x+x)
                 ^
**** WAR  #348:  recursive call for "subr1". See dynamic calls:
                 "Repeat.f" line #10
                 "Repeat.f" line #3
 
Cross Reference                 Mon Mar 18 18:08:27 2002    page 2
 
         C R O S S   R E F E R E N C E   T A B L E
 
  Source file:   Repeat.f
 
 
Legend:
D        Definition/Declaration
U        Simple use
M        Modified occurrence
A        Actual argument
C        Subroutine/Function call
I        Initialization: DATA or extended declaration
E        Occurrence in EQUIVALENCE
N        Occurrence in NAMELIST
L        Use Module
 
 
 
Cross Reference                 Mon Mar 18 15:40:57 2002     page 3
 
P R O G R A M   F O R M
 
 Program
 -------
 
repeat          <repeat>        D      1:D 
 
Cross Reference                 Mon Mar 18 15:40:57 2002    page 4
 
 
 Functions and Subroutines
 -------------------------
 
INT      intrinsic
                <prnok>         C     23:C 
 
newf            <repeat>        C      4:C 
                <newf>          D     14:D 
 
prnok    int*4  <newf>         DC     15:D     19:C 
                <prnok>        DM     22:D     23:M 
 
sleep           <unreach_sub>            C     27:C 
 
subr1           <repeat>        C      3:C 
                <subr1>         D      8:D 
                <subr2>         C     31:C 
 
subr2           <subr1>         C     10:C 
                <subr2>         D     30:D 
 
unreach_sub     <unreach_sub>            D     26:D 
 
Cross Reference                 Mon Mar 18 15:40:57 2002    page 5
 
 
 Variables and Arrays
 --------------------
 
ix      int*4  dummy
                <newf>       DUMA     14:D     16:U     17:M     19:A 
 
pn1      real*4 <repeat>      UMA      2:M      3:A      4:A      5:U 
 
x       real*4 dummy
                <subr1>        DU      8:D      9:U     10:U 
                <subr2>        DU     30:D     31:U     31:U 
                <prnok>        DA     22:D     23:A 
 
------------------------------------------------------------------
STATISTIC                    Mon Mar 18 15:40:57 2002    page 6
 
 
Date:     Mon Mar 18 15:40:57 2002
Options:  -XlistX 
Files:         2 (Sources: 1; libraries: 1)
Lines:        33 (Sources: 33; Library subprograms:1)
Routines:      6 (MAIN: 1; Subroutines: 4; Functions: 1)
Messages:      6 (Errors: 3; Warnings: 3)

5.1.4 Suboptions for Global Checking Across Routines

The basic global cross-checking option is -Xlist with no suboption. It is a combination of suboptions, each of which could have been specified separately.

The following sections describe options for producing the listing, errors, and cross-reference table. Multiple suboptions may appear on the command line.

5.1.4.1 Suboption Syntax

Add suboptions according to the following rules:

5.1.4.2 -Xlist and its Suboptions

Combine suboptions according to the following rules:

Example: Each of these two command lines performs the same task:

demo% f95  -Xlistc  -Xlist  any.f

demo% f95  -Xlistc  any.f

 

The following table shows the reports generated by these basic -Xlist suboptions alone:

TABLE 5-1 Basic Xlist Suboptions

Generated Report

Option

Errors, listing, cross-reference

-Xlist

Errors only

-XlistE

Errors and source listing only

-XlistL

Errors and cross-reference table only

-XlistX

Errors and call graph only

-Xlistc


The following table shows all -Xlist suboptions.

TABLE 5-2 Complete List of -Xlist Suboptions

Option

Action

-Xlist (no suboption)

Shows errors, listing, and cross-reference table

-Xlistc

Shows call graphs and errors

Used alone, -Xlistc does not show a listing or cross-reference. It produces the call graph in a tree form, using printable characters. If some subroutines are not called from MAIN, more than one graph is shown. Each BLOCKDATA is printed separately with no connection to MAIN.

The default is not to show the call graph.

-XlistE

Shows errors

Used alone, -XlistE shows only cross-routine errors and does not show a listing or a cross-reference.

-Xlisterr[nnn]

Suppresses error nnn in the verification report

Use -Xlisterr to suppress a numbered error message from the listing or cross-reference.

For example: -Xlisterr338 suppresses error message 338. To suppress additional specific errors, use this option repeatedly. If nnn is not specified, all error messages are suppressed.

-Xlistf

Produces output faster

Use -Xlistf to produce source file listings and a cross-checking report and to check sources without full compilation.

-Xlisth

Shows errors from cross-checking stop compilation

With -Xlisth, compilation stops if errors are detected while cross-checking the program. In this case, the report is redirected to stdout instead of the *.lst file.

-XlistI

Lists and cross-checks include files

If -XlistI is the only suboption used, include files are shown or scanned along with the standard -Xlist output (line numbered listing, error messages, and a cross-reference table).

Listing--If the listing is not suppressed, then the include files are listed in place. Files are listed as often as they are included. The files are: Source files, #include files, INCLUDE files

Cross-Reference Table--If the cross reference table is not suppressed, the following files are all scanned while the cross reference table is generated: Source files, #include files, INCLUDE files

The default is not to show include files.

-XlistL

Shows the listing and errors

Use -XlistL to produce only a listing and a list of cross routine errors. This suboption by itself does not show a cross reference table. The default is to show the listing and cross reference table

-Xlistln

Sets page breaks

Use -Xlistl to set the page length to something other than the default page size. For example, -Xlistl45 sets the page length to 45 lines. The default is 66.

With n=0 (-Xlistl0) this option shows listings and cross-references with no page breaks for easier on-screen viewing.

-XlistMP

Check consistency of OpenMP directives

Use -XlistMP to report on any inconsistencies in the OpenMP directives specified in the source code file. See also the OpenMP API User's Guide for details.

-Xlisto name

Specify the -Xlist output report file

Use -Xlisto to specify the generated report output file. (A space between o and name is required.) With -Xlisto name, the output is to name and not to file.lst.

To display directly to the screen, use the option:
-Xlisto /dev/tty

-Xlists

Suppresses unreferenced symbols from cross-reference

Use -Xlists to suppress from the cross reference table any identifiers defined in the include files but not referenced in the source files.

This suboption has no effect if the suboption -XlistI is used.

The default is not to show the occurrences in #include or INCLUDE files.

-Xlistvn

Sets checking "strictness" level

n is 1,2, 3, or 4. The default is 2 (-Xlistv2):

  • -Xlistv1

Shows the cross-checked information of all names in summary form only, with no line numbers. This is the lowest level of checking strictness--syntax errors only.

  • -Xlistv2

Shows cross-checked information with summaries and line numbers. This is the default level of checking strictness and includes argument inconsistency errors and variable usage errors.

  • -Xlistv3

Shows cross-checking with summaries, line numbers, and common block maps. This is a high level of checking strictness and includes errors caused by incorrect usage of data types in common blocks in different subprograms.

  • -Xlistv4

Shows cross-checking with summaries, line numbers, common block maps, and equivalence block maps. This is the strictest level of checking with maximum error detection.

-Xlistw[nnn]

Sets the width of output lines

Use -Xlistw to set the width of the output line. For example, -Xlistw132 sets the page width to 132 columns. The default is 79.

-Xlistwar[nnn]

Suppresses warning nnn in the report

Use -Xlistwar to suppress a specific warning message from the output reports. If nnn is not specified, then all warning messages are suppressed from printing. For example, -Xlistwar338 suppresses warning message number 338. To suppress more than one, but not all warnings, use this option repeatedly.

-XlistX

Shows just the cross-reference table and errors

-XlistX produces a cross reference table and cross routine error list but no source listing.



5.2 Special Compiler Options

Some compiler options are useful for debugging. They check subscripts, spot undeclared variables, show stages of the compile-link sequence, display versions of software, and so on.

The Solaris linker has additional debugging aids. See ld(1), or run the command ld -Dhelp at a shell prompt to see the online documentation.

5.2.1 Subscript Bounds (-C)

If you compile with -C, the compiler adds checks at runtime for out-of-bounds references on each array subscript, and array conformance. This action helps catch some situations that cause segmentation faults.

Example: Index out of range:

demo% cat range.f
      REAL a(10,10)
      k = 11
      a(k,2) = 1.0
      END
demo% f95 -o range range.f
demo% range
 
 ******  FORTRAN RUN-TIME SYSTEM  ******
Subscript out of range. Location: line 3 column 9 of 'range.f'
Subscript number 1 has value 11 in array 'A'
Abort
demo%

5.2.2 Undeclared Variable Types (-u)

The -u option checks for any undeclared variables.

The -u option causes all variables to be initially identified as undeclared, so that all variables that are not explicitly declared by type statements, or by an IMPLICIT statement, are flagged with an error. The -u flag is useful for discovering mistyped variables. If -u is set, all variables are treated as undeclared until explicitly declared. Use of an undeclared variable is accompanied by an error message.

5.2.3 Compiler Version Checking (-V)

The -V option causes the name and version ID of each phase of the compiler to be displayed. This option can be useful in tracking the origin of ambiguous error messages and in reporting compiler failures, and to verify the level of installed compiler patches.

demo% f95 -V wh.f
f95: Sun Fortran 95 7.0 DEV 2002/01/30
f90comp: Sun Fortran 95 7.0 DEV 2002/01/30
f90comp: 9 SOURCE LINES
f90comp: 0 ERRORS, 0 WARNINGS, 0 OTHER MESSAGES, 0 ANSI
ld: Solaris Link Editors: 5.8-1.272


5.3 Debugging With dbx

Sun Studio provides a tightly integrated development environment for debugging applications written in Fortran, C, and C++.

The dbx program provides event management, process control, and data inspection. You can watch what is happening during program execution, and perform the following tasks:

To debug optimized programs, use the dbx fix command to recompile the routines you want to debug:

1. Compile the program with the appropriate -On optimization level.

2. Start the execution under dbx.

3. Use fix -g any.f without optimization on the routine you want to debug.

4. Use continue with that routine compiled.

Some optimizations will be inhibited by the presence of -g on the compilation command. See the dbx documentation for details.

For details, see the Sun Studio Debugging a Program With dbx manual, and the dbx(1) man pages.